libmach: more mach-o support
R=rsc http://codereview.appspot.com/2277041
This commit is contained in:
parent
875351f44f
commit
873e5f5094
5 changed files with 343 additions and 35 deletions
|
|
@ -11,6 +11,7 @@ file such as NOTICE, LICENCE or COPYING.
|
||||||
Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
|
Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
|
||||||
Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
|
Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
|
||||||
Portions Copyright © 2001-2007 Russ Cox.
|
Portions Copyright © 2001-2007 Russ Cox.
|
||||||
|
Portions Copyright © 2008-2010 Google Inc.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
|
||||||
|
|
@ -115,8 +115,8 @@ crackmacho(int fd, Fhdr *fp)
|
||||||
if(m->cmd[i].type == MachoCmdSymtab)
|
if(m->cmd[i].type == MachoCmdSymtab)
|
||||||
break;
|
break;
|
||||||
if(i < m->ncmd){
|
if(i < m->ncmd){
|
||||||
fp->stabs.stabbase = load(fp->fd, m->cmd[i].sym.symoff, m->cmd[i].sym.nsyms*16);
|
fp->stabs.stabbase = load(fp->fd, m->cmd[i].sym.symoff, m->cmd[i].sym.nsym*16);
|
||||||
fp->stabs.stabsize = m->cmd[i].sym.nsyms*16;
|
fp->stabs.stabsize = m->cmd[i].sym.nsym*16;
|
||||||
fp->stabs.strbase = (char*)load(fp->fd, m->cmd[i].sym.stroff, m->cmd[i].sym.strsize);
|
fp->stabs.strbase = (char*)load(fp->fd, m->cmd[i].sym.stroff, m->cmd[i].sym.strsize);
|
||||||
if(fp->stabs.stabbase == nil || fp->stabs.strbase == nil){
|
if(fp->stabs.stabbase == nil || fp->stabs.strbase == nil){
|
||||||
fp->stabs.stabbase = nil;
|
fp->stabs.stabbase = nil;
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,27 @@
|
||||||
/*
|
/*
|
||||||
http://www.channelu.com/NeXT/NeXTStep/3.3/nd/DevTools/14_MachO/MachO.htmld/
|
http://www.channelu.com/NeXT/NeXTStep/3.3/nd/DevTools/14_MachO/MachO.htmld/
|
||||||
*/
|
*/
|
||||||
|
static long
|
||||||
|
preadn(int fd, void *vdata, uint32 ulen, uint64 offset)
|
||||||
|
{
|
||||||
|
long n;
|
||||||
|
uchar *data;
|
||||||
|
long len;
|
||||||
|
|
||||||
|
len = ulen;
|
||||||
|
data = vdata;
|
||||||
|
/* fprint(2, "readn 0x%llux 0x%ux\n", offset, ulen); */
|
||||||
|
while(len > 0){
|
||||||
|
n = pread(fd, data, len, offset);
|
||||||
|
if(n <= 0)
|
||||||
|
break;
|
||||||
|
data += n;
|
||||||
|
offset += n;
|
||||||
|
len -= n;
|
||||||
|
}
|
||||||
|
return data-(uchar*)vdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Macho*
|
Macho*
|
||||||
machoopen(char *name)
|
machoopen(char *name)
|
||||||
|
|
@ -22,11 +43,15 @@ machoopen(char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
unpackseg(uchar *p, Macho *m, MachoCmd *c, uint type, uint sz)
|
unpackcmd(uchar *p, Macho *m, MachoCmd *c, uint type, uint sz)
|
||||||
{
|
{
|
||||||
u32int (*e4)(uchar*);
|
uint32 (*e4)(uchar*);
|
||||||
|
uint64 (*e8)(uchar*);
|
||||||
|
MachoSect *s;
|
||||||
|
int i;
|
||||||
|
|
||||||
e4 = m->e4;
|
e4 = m->e4;
|
||||||
|
e8 = m->e8;
|
||||||
|
|
||||||
c->type = type;
|
c->type = type;
|
||||||
c->size = sz;
|
c->size = sz;
|
||||||
|
|
@ -45,59 +70,257 @@ unpackseg(uchar *p, Macho *m, MachoCmd *c, uint type, uint sz)
|
||||||
c->seg.initprot = e4(p+44);
|
c->seg.initprot = e4(p+44);
|
||||||
c->seg.nsect = e4(p+48);
|
c->seg.nsect = e4(p+48);
|
||||||
c->seg.flags = e4(p+52);
|
c->seg.flags = e4(p+52);
|
||||||
|
c->seg.sect = mallocz(c->seg.nsect * sizeof c->seg.sect[0], 1);
|
||||||
|
if(c->seg.sect == nil)
|
||||||
|
return -1;
|
||||||
|
if(sz < 56+c->seg.nsect*68)
|
||||||
|
return -1;
|
||||||
|
p += 56;
|
||||||
|
for(i=0; i<c->seg.nsect; i++) {
|
||||||
|
s = &c->seg.sect[i];
|
||||||
|
strecpy(s->name, s->name+sizeof s->name, (char*)p+0);
|
||||||
|
strecpy(s->segname, s->segname+sizeof s->segname, (char*)p+16);
|
||||||
|
s->addr = e4(p+32);
|
||||||
|
s->size = e4(p+36);
|
||||||
|
s->offset = e4(p+40);
|
||||||
|
s->align = e4(p+44);
|
||||||
|
s->reloff = e4(p+48);
|
||||||
|
s->nreloc = e4(p+52);
|
||||||
|
s->flags = e4(p+56);
|
||||||
|
// p+60 and p+64 are reserved
|
||||||
|
p += 68;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MachoCmdSegment64:
|
||||||
|
if(sz < 72)
|
||||||
|
return -1;
|
||||||
|
strecpy(c->seg.name, c->seg.name+sizeof c->seg.name, (char*)p+8);
|
||||||
|
c->seg.vmaddr = e8(p+24);
|
||||||
|
c->seg.vmsize = e8(p+32);
|
||||||
|
c->seg.fileoff = e8(p+40);
|
||||||
|
c->seg.filesz = e8(p+48);
|
||||||
|
c->seg.maxprot = e4(p+56);
|
||||||
|
c->seg.initprot = e4(p+60);
|
||||||
|
c->seg.nsect = e4(p+64);
|
||||||
|
c->seg.flags = e4(p+68);
|
||||||
|
c->seg.sect = mallocz(c->seg.nsect * sizeof c->seg.sect[0], 1);
|
||||||
|
if(c->seg.sect == nil)
|
||||||
|
return -1;
|
||||||
|
if(sz < 72+c->seg.nsect*80)
|
||||||
|
return -1;
|
||||||
|
p += 72;
|
||||||
|
for(i=0; i<c->seg.nsect; i++) {
|
||||||
|
s = &c->seg.sect[i];
|
||||||
|
strecpy(s->name, s->name+sizeof s->name, (char*)p+0);
|
||||||
|
strecpy(s->segname, s->segname+sizeof s->segname, (char*)p+16);
|
||||||
|
s->addr = e8(p+32);
|
||||||
|
s->size = e8(p+40);
|
||||||
|
s->offset = e4(p+48);
|
||||||
|
s->align = e4(p+52);
|
||||||
|
s->reloff = e4(p+56);
|
||||||
|
s->nreloc = e4(p+60);
|
||||||
|
s->flags = e4(p+64);
|
||||||
|
// p+68, p+72, and p+76 are reserved
|
||||||
|
p += 80;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case MachoCmdSymtab:
|
case MachoCmdSymtab:
|
||||||
if(sz < 24)
|
if(sz < 24)
|
||||||
return -1;
|
return -1;
|
||||||
c->sym.symoff = e4(p+8);
|
c->sym.symoff = e4(p+8);
|
||||||
c->sym.nsyms = e4(p+12);
|
c->sym.nsym = e4(p+12);
|
||||||
c->sym.stroff = e4(p+16);
|
c->sym.stroff = e4(p+16);
|
||||||
c->sym.strsize = e4(p+20);
|
c->sym.strsize = e4(p+20);
|
||||||
break;
|
break;
|
||||||
|
case MachoCmdDysymtab:
|
||||||
|
if(sz < 80)
|
||||||
|
return -1;
|
||||||
|
c->dsym.ilocalsym = e4(p+8);
|
||||||
|
c->dsym.nlocalsym = e4(p+12);
|
||||||
|
c->dsym.iextdefsym = e4(p+16);
|
||||||
|
c->dsym.nextdefsym = e4(p+20);
|
||||||
|
c->dsym.iundefsym = e4(p+24);
|
||||||
|
c->dsym.nundefsym = e4(p+28);
|
||||||
|
c->dsym.tocoff = e4(p+32);
|
||||||
|
c->dsym.ntoc = e4(p+36);
|
||||||
|
c->dsym.modtaboff = e4(p+40);
|
||||||
|
c->dsym.nmodtab = e4(p+44);
|
||||||
|
c->dsym.extrefsymoff = e4(p+48);
|
||||||
|
c->dsym.nextrefsyms = e4(p+52);
|
||||||
|
c->dsym.indirectsymoff = e4(p+56);
|
||||||
|
c->dsym.nindirectsyms = e4(p+60);
|
||||||
|
c->dsym.extreloff = e4(p+64);
|
||||||
|
c->dsym.nextrel = e4(p+68);
|
||||||
|
c->dsym.locreloff = e4(p+72);
|
||||||
|
c->dsym.nlocrel = e4(p+76);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
macholoadrel(Macho *m, MachoSect *sect)
|
||||||
|
{
|
||||||
|
MachoRel *rel, *r;
|
||||||
|
uchar *buf, *p;
|
||||||
|
int i, n;
|
||||||
|
uint32 v;
|
||||||
|
|
||||||
|
if(sect->rel != nil || sect->nreloc == 0)
|
||||||
|
return 0;
|
||||||
|
rel = mallocz(sect->nreloc * sizeof r[0], 1);
|
||||||
|
if(rel == nil)
|
||||||
|
return -1;
|
||||||
|
n = sect->nreloc * 8;
|
||||||
|
buf = mallocz(n, 1);
|
||||||
|
if(buf == nil) {
|
||||||
|
free(rel);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(seek(m->fd, sect->reloff, 0) < 0 || readn(m->fd, buf, n) != n) {
|
||||||
|
free(rel);
|
||||||
|
free(buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
for(i=0; i<sect->nreloc; i++) {
|
||||||
|
r = &rel[i];
|
||||||
|
p = buf+i*8;
|
||||||
|
r->addr = m->e4(p);
|
||||||
|
|
||||||
|
// TODO(rsc): Wrong interpretation for big-endian bitfields?
|
||||||
|
v = m->e4(p+4);
|
||||||
|
r->symnum = v & 0xFFFFFF;
|
||||||
|
v >>= 24;
|
||||||
|
r->pcrel = v&1;
|
||||||
|
v >>= 1;
|
||||||
|
r->length = 1<<(v&3);
|
||||||
|
v >>= 2;
|
||||||
|
r->extrn = v&1;
|
||||||
|
v >>= 1;
|
||||||
|
r->type = v;
|
||||||
|
}
|
||||||
|
sect->rel = rel;
|
||||||
|
free(buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
macholoadsym(Macho *m, MachoSymtab *symtab)
|
||||||
|
{
|
||||||
|
char *strbuf;
|
||||||
|
uchar *symbuf, *p;
|
||||||
|
int i, n, symsize;
|
||||||
|
MachoSym *sym, *s;
|
||||||
|
uint32 v;
|
||||||
|
|
||||||
|
if(symtab->sym != nil)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
strbuf = mallocz(symtab->strsize, 1);
|
||||||
|
if(strbuf == nil)
|
||||||
|
return -1;
|
||||||
|
if(seek(m->fd, symtab->stroff, 0) < 0 || readn(m->fd, strbuf, symtab->strsize) != symtab->strsize) {
|
||||||
|
free(strbuf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
symsize = 12;
|
||||||
|
if(m->is64)
|
||||||
|
symsize = 16;
|
||||||
|
n = symtab->nsym * symsize;
|
||||||
|
symbuf = mallocz(n, 1);
|
||||||
|
if(symbuf == nil) {
|
||||||
|
free(strbuf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(seek(m->fd, symtab->symoff, 0) < 0 || readn(m->fd, symbuf, n) != n) {
|
||||||
|
free(strbuf);
|
||||||
|
free(symbuf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
sym = mallocz(symtab->nsym * sizeof sym[0], 1);
|
||||||
|
if(sym == nil) {
|
||||||
|
free(strbuf);
|
||||||
|
free(symbuf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
p = symbuf;
|
||||||
|
for(i=0; i<symtab->nsym; i++) {
|
||||||
|
s = &sym[i];
|
||||||
|
v = m->e4(p);
|
||||||
|
if(v >= symtab->strsize) {
|
||||||
|
free(strbuf);
|
||||||
|
free(symbuf);
|
||||||
|
free(sym);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
s->name = strbuf + v;
|
||||||
|
s->type = p[4];
|
||||||
|
s->sectnum = p[5];
|
||||||
|
s->desc = m->e2(p+6);
|
||||||
|
if(m->is64)
|
||||||
|
s->value = m->e8(p+8);
|
||||||
|
else
|
||||||
|
s->value = m->e4(p+8);
|
||||||
|
p += symsize;
|
||||||
|
}
|
||||||
|
symtab->str = strbuf;
|
||||||
|
symtab->sym = sym;
|
||||||
|
free(symbuf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Macho*
|
Macho*
|
||||||
machoinit(int fd)
|
machoinit(int fd)
|
||||||
{
|
{
|
||||||
int i;
|
int i, is64;
|
||||||
uchar hdr[7*4], *cmdp;
|
uchar hdr[7*4], *cmdp;
|
||||||
u32int (*e4)(uchar*);
|
uchar tmp[4];
|
||||||
|
uint16 (*e2)(uchar*);
|
||||||
|
uint32 (*e4)(uchar*);
|
||||||
|
uint64 (*e8)(uchar*);
|
||||||
ulong ncmd, cmdsz, ty, sz, off;
|
ulong ncmd, cmdsz, ty, sz, off;
|
||||||
Macho *m;
|
Macho *m;
|
||||||
|
|
||||||
if(seek(fd, 0, 0) < 0 || readn(fd, hdr, sizeof hdr) != sizeof hdr)
|
if(seek(fd, 0, 0) < 0 || readn(fd, hdr, sizeof hdr) != sizeof hdr)
|
||||||
return nil;
|
return nil;
|
||||||
|
|
||||||
if(beload4(hdr) == 0xFEEDFACE)
|
if((beload4(hdr)&~1) == 0xFEEDFACE){
|
||||||
|
e2 = beload2;
|
||||||
e4 = beload4;
|
e4 = beload4;
|
||||||
else if(leload4(hdr) == 0xFEEDFACE)
|
e8 = beload8;
|
||||||
|
}else if((leload4(hdr)&~1) == 0xFEEDFACE){
|
||||||
|
e2 = leload2;
|
||||||
e4 = leload4;
|
e4 = leload4;
|
||||||
else{
|
e8 = leload8;
|
||||||
|
}else{
|
||||||
werrstr("bad magic - not mach-o file");
|
werrstr("bad magic - not mach-o file");
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
is64 = e4(hdr) == 0xFEEDFACF;
|
||||||
ncmd = e4(hdr+4*4);
|
ncmd = e4(hdr+4*4);
|
||||||
cmdsz = e4(hdr+5*4);
|
cmdsz = e4(hdr+5*4);
|
||||||
if(ncmd > 0x10000 || cmdsz >= 0x01000000){
|
if(ncmd > 0x10000 || cmdsz >= 0x01000000){
|
||||||
werrstr("implausible mach-o header ncmd=%lud cmdsz=%lud", ncmd, cmdsz);
|
werrstr("implausible mach-o header ncmd=%lud cmdsz=%lud", ncmd, cmdsz);
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
if(is64)
|
||||||
|
readn(fd, tmp, 4); // skip reserved word in header
|
||||||
|
|
||||||
m = mallocz(sizeof(*m)+ncmd*sizeof(MachoCmd)+cmdsz, 1);
|
m = mallocz(sizeof(*m)+ncmd*sizeof(MachoCmd)+cmdsz, 1);
|
||||||
if(m == nil)
|
if(m == nil)
|
||||||
return nil;
|
return nil;
|
||||||
|
|
||||||
m->fd = fd;
|
m->fd = fd;
|
||||||
|
m->e2 = e2;
|
||||||
m->e4 = e4;
|
m->e4 = e4;
|
||||||
|
m->e8 = e8;
|
||||||
m->cputype = e4(hdr+1*4);
|
m->cputype = e4(hdr+1*4);
|
||||||
m->subcputype = e4(hdr+2*4);
|
m->subcputype = e4(hdr+2*4);
|
||||||
m->filetype = e4(hdr+3*4);
|
m->filetype = e4(hdr+3*4);
|
||||||
m->ncmd = ncmd;
|
m->ncmd = ncmd;
|
||||||
m->flags = e4(hdr+6*4);
|
m->flags = e4(hdr+6*4);
|
||||||
|
m->is64 = is64;
|
||||||
|
|
||||||
m->cmd = (MachoCmd*)(m+1);
|
m->cmd = (MachoCmd*)(m+1);
|
||||||
off = sizeof hdr;
|
off = sizeof hdr;
|
||||||
|
|
@ -112,11 +335,10 @@ machoinit(int fd)
|
||||||
ty = e4(cmdp);
|
ty = e4(cmdp);
|
||||||
sz = e4(cmdp+4);
|
sz = e4(cmdp+4);
|
||||||
m->cmd[i].off = off;
|
m->cmd[i].off = off;
|
||||||
unpackseg(cmdp, m, &m->cmd[i], ty, sz);
|
unpackcmd(cmdp, m, &m->cmd[i], ty, sz);
|
||||||
cmdp += sz;
|
cmdp += sz;
|
||||||
off += sz;
|
off += sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,18 @@
|
||||||
typedef struct Macho Macho;
|
typedef struct Macho Macho;
|
||||||
typedef struct MachoCmd MachoCmd;
|
typedef struct MachoCmd MachoCmd;
|
||||||
|
typedef struct MachoSeg MachoSeg;
|
||||||
|
typedef struct MachoSect MachoSect;
|
||||||
|
typedef struct MachoRel MachoRel;
|
||||||
|
typedef struct MachoSymtab MachoSymtab;
|
||||||
|
typedef struct MachoSym MachoSym;
|
||||||
|
typedef struct MachoDysymtab MachoDysymtab;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
MachoCpuVax = 1,
|
MachoCpuVax = 1,
|
||||||
MachoCpu68000 = 6,
|
MachoCpu68000 = 6,
|
||||||
MachoCpu386 = 7,
|
MachoCpu386 = 7,
|
||||||
|
MachoCpuAmd64 = 0x1000007,
|
||||||
MachoCpuMips = 8,
|
MachoCpuMips = 8,
|
||||||
MachoCpu98000 = 10,
|
MachoCpu98000 = 10,
|
||||||
MachoCpuHppa = 11,
|
MachoCpuHppa = 11,
|
||||||
|
|
@ -20,6 +27,8 @@ enum
|
||||||
MachoCmdSymtab = 2,
|
MachoCmdSymtab = 2,
|
||||||
MachoCmdSymseg = 3,
|
MachoCmdSymseg = 3,
|
||||||
MachoCmdThread = 4,
|
MachoCmdThread = 4,
|
||||||
|
MachoCmdDysymtab = 11,
|
||||||
|
MachoCmdSegment64 = 25,
|
||||||
|
|
||||||
MachoFileObject = 1,
|
MachoFileObject = 1,
|
||||||
MachoFileExecutable = 2,
|
MachoFileExecutable = 2,
|
||||||
|
|
@ -28,40 +37,111 @@ enum
|
||||||
MachoFilePreload = 5
|
MachoFilePreload = 5
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MachoSeg
|
||||||
|
{
|
||||||
|
char name[16+1];
|
||||||
|
uint64 vmaddr;
|
||||||
|
uint64 vmsize;
|
||||||
|
uint32 fileoff;
|
||||||
|
uint32 filesz;
|
||||||
|
uint32 maxprot;
|
||||||
|
uint32 initprot;
|
||||||
|
uint32 nsect;
|
||||||
|
uint32 flags;
|
||||||
|
MachoSect *sect;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MachoSect
|
||||||
|
{
|
||||||
|
char name[16+1];
|
||||||
|
char segname[16+1];
|
||||||
|
uint64 addr;
|
||||||
|
uint64 size;
|
||||||
|
uint32 offset;
|
||||||
|
uint32 align;
|
||||||
|
uint32 reloff;
|
||||||
|
uint32 nreloc;
|
||||||
|
uint32 flags;
|
||||||
|
|
||||||
|
MachoRel *rel;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MachoRel
|
||||||
|
{
|
||||||
|
uint32 addr;
|
||||||
|
uint32 symnum;
|
||||||
|
uint8 pcrel;
|
||||||
|
uint8 length;
|
||||||
|
uint8 extrn;
|
||||||
|
uint8 type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MachoSymtab
|
||||||
|
{
|
||||||
|
uint32 symoff;
|
||||||
|
uint32 nsym;
|
||||||
|
uint32 stroff;
|
||||||
|
uint32 strsize;
|
||||||
|
|
||||||
|
char *str;
|
||||||
|
MachoSym *sym;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MachoSym
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
uint8 type;
|
||||||
|
uint8 sectnum;
|
||||||
|
uint16 desc;
|
||||||
|
char kind;
|
||||||
|
uint64 value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MachoDysymtab
|
||||||
|
{
|
||||||
|
uint32 ilocalsym;
|
||||||
|
uint32 nlocalsym;
|
||||||
|
uint32 iextdefsym;
|
||||||
|
uint32 nextdefsym;
|
||||||
|
uint32 iundefsym;
|
||||||
|
uint32 nundefsym;
|
||||||
|
uint32 tocoff;
|
||||||
|
uint32 ntoc;
|
||||||
|
uint32 modtaboff;
|
||||||
|
uint32 nmodtab;
|
||||||
|
uint32 extrefsymoff;
|
||||||
|
uint32 nextrefsyms;
|
||||||
|
uint32 indirectsymoff;
|
||||||
|
uint32 nindirectsyms;
|
||||||
|
uint32 extreloff;
|
||||||
|
uint32 nextrel;
|
||||||
|
uint32 locreloff;
|
||||||
|
uint32 nlocrel;
|
||||||
|
};
|
||||||
|
|
||||||
struct MachoCmd
|
struct MachoCmd
|
||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
ulong off;
|
uint32 off;
|
||||||
ulong size;
|
uint32 size;
|
||||||
struct {
|
MachoSeg seg;
|
||||||
char name[16+1];
|
MachoSymtab sym;
|
||||||
ulong vmaddr;
|
MachoDysymtab dsym;
|
||||||
ulong vmsize;
|
|
||||||
ulong fileoff;
|
|
||||||
ulong filesz;
|
|
||||||
ulong maxprot;
|
|
||||||
ulong initprot;
|
|
||||||
ulong nsect;
|
|
||||||
ulong flags;
|
|
||||||
} seg;
|
|
||||||
struct {
|
|
||||||
ulong symoff;
|
|
||||||
ulong nsyms;
|
|
||||||
ulong stroff;
|
|
||||||
ulong strsize;
|
|
||||||
} sym;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Macho
|
struct Macho
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
int is64;
|
||||||
uint cputype;
|
uint cputype;
|
||||||
uint subcputype;
|
uint subcputype;
|
||||||
ulong filetype;
|
uint32 filetype;
|
||||||
ulong flags;
|
uint32 flags;
|
||||||
MachoCmd *cmd;
|
MachoCmd *cmd;
|
||||||
uint ncmd;
|
uint ncmd;
|
||||||
u32int (*e4)(uchar*);
|
uint16 (*e2)(uchar*);
|
||||||
|
uint32 (*e4)(uchar*);
|
||||||
|
uint64 (*e8)(uchar*);
|
||||||
int (*coreregs)(Macho*, uchar**);
|
int (*coreregs)(Macho*, uchar**);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -69,3 +149,5 @@ Macho *machoopen(char*);
|
||||||
Macho *machoinit(int);
|
Macho *machoinit(int);
|
||||||
void machoclose(Macho*);
|
void machoclose(Macho*);
|
||||||
int coreregsmachopower(Macho*, uchar**);
|
int coreregsmachopower(Macho*, uchar**);
|
||||||
|
int macholoadrel(Macho*, MachoSect*);
|
||||||
|
int macholoadsym(Macho*, MachoSymtab*);
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,9 @@ elfnm: elfnm.o $LIBDIR/$LIB
|
||||||
demangler: demangler.o $LIBDIR/$LIB
|
demangler: demangler.o $LIBDIR/$LIB
|
||||||
$LD -o $target $prereq -l9
|
$LD -o $target $prereq -l9
|
||||||
|
|
||||||
|
machodump: machodump.o $LIBDIR/$LIB
|
||||||
|
$LD -o $target $prereq -l9
|
||||||
|
|
||||||
|
|
||||||
SunOS.$O: nosys.c
|
SunOS.$O: nosys.c
|
||||||
Darwin.$O: nosys.c
|
Darwin.$O: nosys.c
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue