machodump.c (2377B)
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 }