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
|
#include <u.h>
#include <libc.h>
#include <mach.h>
#include "stabs.h"
#include "macho.h"
void
usage(void)
{
fprint(2, "usage: machodump file list\n");
fprint(2, " machodump file stabs\n");
exits("usage");
}
uchar*
load(int fd, ulong off, int size)
{
uchar *a;
a = malloc(size);
print("malloc %d -> %p\n", size, a);
if(a == nil)
sysfatal("malloc: %r");
if(seek(fd, off, 0) < 0)
sysfatal("seek %lud: %r", off);
if(readn(fd, a, size) != size)
sysfatal("readn: %r");
return a;
}
void
main(int argc, char **argv)
{
int i;
Macho *m;
ARGBEGIN{
default:
usage();
}ARGEND
if(argc < 2)
usage();
if((m = machoopen(argv[0])) == nil)
sysfatal("machoopen %s: %r", argv[0]);
if(strcmp(argv[1], "stabs") == 0){
Stab stabs;
StabSym sym;
for(i=0; i<m->ncmd; i++){
if(m->cmd[i].type == MachoCmdSymtab){
stabs.stabbase = load(m->fd, m->cmd[i].sym.symoff, m->cmd[i].sym.nsyms*16);
stabs.stabsize = m->cmd[i].sym.nsyms*16;
stabs.strbase = load(m->fd, m->cmd[i].sym.stroff, m->cmd[i].sym.strsize);
stabs.strsize = m->cmd[i].sym.strsize;
stabs.e4 = m->e4;
stabs.e2 = (m->e4 == beload4 ? beload2 : leload2);
print("cmd%d: %p %ud %p %ud\n", i, stabs.stabbase, stabs.stabsize, stabs.strbase, 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);
print("err at %d: %r\n", i);
}
}
}
else if(strcmp(argv[1], "list") == 0){
print("macho cpu %ud sub %ud filetype %lud flags %lud\n",
m->cputype, m->subcputype, m->filetype, m->flags);
for(i=0; i<m->ncmd; i++){
switch(m->cmd[i].type){
case MachoCmdSymtab:
print("cmd%d: symtab %lud+%lud %lud+%lud\n", i,
m->cmd[i].sym.symoff, m->cmd[i].sym.nsyms,
m->cmd[i].sym.stroff, m->cmd[i].sym.strsize);
break;
case MachoCmdSegment:
print("cmd%d: segment %s vm 0x%lux+0x%lux file 0x%lux+0x%lux prot 0x%lux/0x%lux ns %d flags 0x%lux\n", i,
m->cmd[i].seg.name, m->cmd[i].seg.vmaddr, m->cmd[i].seg.vmsize,
m->cmd[i].seg.fileoff, m->cmd[i].seg.filesz, m->cmd[i].seg.maxprot,
m->cmd[i].seg.initprot, m->cmd[i].seg.nsect, m->cmd[i].seg.flags);
break;
default:
print("cmd%d: type %d offset %lud\n", i, m->cmd[i].type, m->cmd[i].off);
break;
}
}
}
else
usage();
exits(0);
}
|