rsc | a84cbb2 | 2004-04-19 19:29:25 +0000 | [diff] [blame] | 1 | #include <u.h> |
| 2 | #include <libc.h> |
| 3 | #include <mach.h> |
| 4 | #include "stabs.h" |
| 5 | #include "macho.h" |
| 6 | |
| 7 | void |
| 8 | usage(void) |
| 9 | { |
| 10 | fprint(2, "usage: machodump file list\n"); |
| 11 | fprint(2, " machodump file stabs\n"); |
| 12 | exits("usage"); |
| 13 | } |
| 14 | |
| 15 | uchar* |
| 16 | load(int fd, ulong off, int size) |
| 17 | { |
| 18 | uchar *a; |
| 19 | |
| 20 | a = malloc(size); |
| 21 | print("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 | |
| 31 | void |
| 32 | main(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 | } |