aboutsummaryrefslogtreecommitdiff
path: root/src/libmach/elfdump.c
blob: e96f818d310d032401f0dda129ba629db06ef884 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <mach.h>
#include "elf.h"
#include "stabs.h"

void
usage(void)
{
	fprint(2, "usage: elf file list\n");
	fprint(2, "	elf file syms\n");
	fprint(2, "	elf file prog n\n");
	fprint(2, "	elf file sect n\n");
	exits("usage");
}

void
main(int argc, char **argv)
{
	int i, n, nn;
	char buf[512];
	ulong off, len;
	Elf *elf;
	ElfProg *p;
	ElfSect *s;

	ARGBEGIN{
	default:
		usage();
	}ARGEND

	if(argc < 2)
		usage();

	if((elf = elfopen(argv[0])) == nil)
		sysfatal("elfopen %s: %r", argv[0]);

	if(strcmp(argv[1], "syms") == 0){
		ElfSym sym;
		for(i=0; elfsym(elf, i, &sym) >= 0; i++){
			print("%s 0x%lux +%lud bind %d type %d other %d shndx 0x%ux\n",
				sym.name, (ulong)sym.value, (ulong)sym.size,
				sym.bind, sym.type, sym.other, (uint)sym.shndx);
		}
	}
	else if(strcmp(argv[1], "stabs") == 0){
		ElfSect *s1, *s2;
		Stab stabs;
		StabSym sym;

		if((s1 = elfsection(elf, ".stab")) == nil)
			sysfatal("no stabs");
		if(s1->link==0 || s1->link >= elf->nsect)
			sysfatal("bad stabstr %d", s1->link);
		s2 = &elf->sect[s1->link];
		if(elfmap(elf, s1) < 0 || elfmap(elf, s2) < 0)
			sysfatal("elfmap");
		stabs.stabbase = s1->base;
		stabs.stabsize = s1->size;
		stabs.strbase = s2->base;
		stabs.strsize = s2->size;
		stabs.e2 = elf->hdr.e2;
		stabs.e4 = elf->hdr.e4;
		print("%ud %ud\n", stabs.stabsize, stabs.strsize);
		for(i=0; stabsym(&stabs, i, &sym) >= 0; i++)
			print("%s type 0x%x other %d desc %d value 0x%lux\n",
				sym.name, sym.type, sym.other, (int)sym.desc, (ulong)sym.value);
		fprint(2, "err at %d: %r\n", i);
	}
	else if(strcmp(argv[1], "list") == 0){
		if(argc != 2)
			usage();
		print("elf %s %s v%d entry 0x%08lux phoff 0x%lux shoff 0x%lux flags 0x%lux\n",
			elftype(elf->hdr.type), elfmachine(elf->hdr.machine),
			elf->hdr.version, elf->hdr.entry, elf->hdr.phoff, elf->hdr.shoff,
			elf->hdr.flags);
		print("\tehsize %d phentsize %d phnum %d shentsize %d shnum %d shstrndx %d\n",
			elf->hdr.ehsize, elf->hdr.phentsize, elf->hdr.phnum, elf->hdr.shentsize,
			elf->hdr.shnum, elf->hdr.shstrndx);
		for(i=0; i<elf->nprog; i++){
			p = &elf->prog[i];
			print("prog %d type %d offset 0x%08lux vaddr 0x%08lux paddr 0x%08lux filesz 0x%08lux memsz 0x%08lux flags 0x%08lux align 0x%08lux\n",
				i, p->type, p->offset, p->vaddr, p->paddr,
				p->filesz, p->memsz, p->flags, p->align);
		}
		for(i=0; i<elf->nsect; i++){
			s = &elf->sect[i];
			print("sect %d %s type %d flags 0x%lux addr 0x%08lux offset 0x%08lux size 0x%08lux link 0x%lux info 0x%lux align 0x%lux entsize 0x%lux\n",
				i, s->name, s->type, s->flags, s->addr, s->offset, s->size, s->link, s->info,
				s->align, s->entsize);
		}
	}
	else if(strcmp(argv[1], "prog") == 0){
		if(argc != 3)
			usage();
		i = atoi(argv[2]);
		if(i < 0 || i >= elf->nprog)
			sysfatal("bad prog number");
		off = elf->prog[i].offset;
		len = elf->prog[i].filesz;
		fprint(2, "prog %d offset 0x%lux size 0x%lux\n", i, off, len);
	copy:
		seek(elf->fd, off, 0);
		for(n=0; n<len; n+=nn){
			nn = sizeof buf;
			if(nn > len-n)
				nn = len-n;
			nn = read(elf->fd, buf, nn);
			if(nn == 0)
				break;
			if(nn < 0)
				sysfatal("read error");
			write(1, buf, nn);
		}
		if(n < len)
			fprint(2, "early eof\n");
	}
	else if(strcmp(argv[1], "sect") == 0){
		if(argc != 3)
			usage();
		i = atoi(argv[2]);
		if(i < 0 || i >= elf->nsect)
			sysfatal("bad section number");
		off = elf->sect[i].offset;
		len = elf->sect[i].size;
		fprint(2, "section %d offset 0x%lux size 0x%lux\n", i, off, len);
		goto copy;
	}
	else
		usage();
	exits(0);
}