blob: 181061aa7d7d269986d25f4058584e1e42d835df [file] [log] [blame]
rsca84cbb22004-04-19 19:29:25 +00001#include <u.h>
2#include <libc.h>
3#include <mach.h>
4#include "stabs.h"
5#include "macho.h"
6
7void
8usage(void)
9{
10 fprint(2, "usage: machodump file list\n");
11 fprint(2, " machodump file stabs\n");
12 exits("usage");
13}
14
15uchar*
16load(int fd, ulong off, int size)
17{
18 uchar *a;
19
20 a = malloc(size);
21print("malloc %d -> %p\n", size, a);
22 if(a == nil)
23 sysfatal("malloc: %r");
24 if(seek(fd, off, 0) < 0)
25 sysfatal("seek %lud: %r", off);
26 if(readn(fd, a, size) != size)
27 sysfatal("readn: %r");
28 return a;
29}
30
31void
32main(int argc, char **argv)
33{
34 int i;
35 Macho *m;
36
37 ARGBEGIN{
38 default:
39 usage();
40 }ARGEND
41
42 if(argc < 2)
43 usage();
44
45 if((m = machoopen(argv[0])) == nil)
46 sysfatal("machoopen %s: %r", argv[0]);
47
48 if(strcmp(argv[1], "stabs") == 0){
49 Stab stabs;
50 StabSym sym;
51
52 for(i=0; i<m->ncmd; i++){
53 if(m->cmd[i].type == MachoCmdSymtab){
54 stabs.stabbase = load(m->fd, m->cmd[i].sym.symoff, m->cmd[i].sym.nsyms*16);
55 stabs.stabsize = m->cmd[i].sym.nsyms*16;
56 stabs.strbase = load(m->fd, m->cmd[i].sym.stroff, m->cmd[i].sym.strsize);
57 stabs.strsize = m->cmd[i].sym.strsize;
58 stabs.e4 = m->e4;
59 stabs.e2 = (m->e4 == beload4 ? beload2 : leload2);
60 print("cmd%d: %p %ud %p %ud\n", i, stabs.stabbase, stabs.stabsize, stabs.strbase, stabs.strsize);
61 for(i=0; stabsym(&stabs, i, &sym) >= 0; i++)
62 print("%s type 0x%x other %d desc %d value 0x%lux\n",
63 sym.name, sym.type, sym.other, (int)sym.desc, (ulong)sym.value);
64 print("err at %d: %r\n", i);
65 }
66 }
67 }
68 else if(strcmp(argv[1], "list") == 0){
69 print("macho cpu %ud sub %ud filetype %lud flags %lud\n",
70 m->cputype, m->subcputype, m->filetype, m->flags);
71 for(i=0; i<m->ncmd; i++){
72 switch(m->cmd[i].type){
73 case MachoCmdSymtab:
74 print("cmd%d: symtab %lud+%lud %lud+%lud\n", i,
75 m->cmd[i].sym.symoff, m->cmd[i].sym.nsyms,
76 m->cmd[i].sym.stroff, m->cmd[i].sym.strsize);
77 break;
78 case MachoCmdSegment:
79 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,
80 m->cmd[i].seg.name, m->cmd[i].seg.vmaddr, m->cmd[i].seg.vmsize,
81 m->cmd[i].seg.fileoff, m->cmd[i].seg.filesz, m->cmd[i].seg.maxprot,
82 m->cmd[i].seg.initprot, m->cmd[i].seg.nsect, m->cmd[i].seg.flags);
83 break;
84 default:
85 print("cmd%d: type %d offset %lud\n", i, m->cmd[i].type, m->cmd[i].off);
86 break;
87 }
88 }
89 }
90 else
91 usage();
92 exits(0);
93}