#include #include #include #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; incmd; 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; incmd; 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); }