94 lines
2.3 KiB
C
94 lines
2.3 KiB
C
|
|
#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);
|
||
|
|
}
|