mirror of
https://github.com/golang/go.git
synced 2024-09-29 22:37:06 +00:00
step toward darwin ffi: factor out macho code
R=r DELTA=771 (374 added, 287 deleted, 110 changed) OCL=35187 CL=35187
This commit is contained in:
parent
399d23d4f4
commit
2157025ef0
@ -14,6 +14,7 @@ OFILES=\
|
|||||||
enam.$O\
|
enam.$O\
|
||||||
go.$O\
|
go.$O\
|
||||||
list.$O\
|
list.$O\
|
||||||
|
macho.$O\
|
||||||
obj.$O\
|
obj.$O\
|
||||||
optab.$O\
|
optab.$O\
|
||||||
pass.$O\
|
pass.$O\
|
||||||
@ -23,6 +24,7 @@ HFILES=\
|
|||||||
l.h\
|
l.h\
|
||||||
../6l/6.out.h\
|
../6l/6.out.h\
|
||||||
../ld/elf.h\
|
../ld/elf.h\
|
||||||
|
../ld/macho.h\
|
||||||
../6l/compat.h\
|
../6l/compat.h\
|
||||||
|
|
||||||
|
|
||||||
@ -41,5 +43,5 @@ install: $(TARG)
|
|||||||
cp $(TARG) $(GOBIN)/$(TARG)
|
cp $(TARG) $(GOBIN)/$(TARG)
|
||||||
|
|
||||||
go.o: ../ld/go.c
|
go.o: ../ld/go.c
|
||||||
|
|
||||||
elf.o: ../ld/elf.c
|
elf.o: ../ld/elf.c
|
||||||
|
macho.o: ../ld/macho.c
|
||||||
|
260
src/cmd/6l/asm.c
260
src/cmd/6l/asm.c
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include "l.h"
|
#include "l.h"
|
||||||
#include "../ld/elf.h"
|
#include "../ld/elf.h"
|
||||||
|
#include "../ld/macho.h"
|
||||||
|
|
||||||
#define Dbufslop 100
|
#define Dbufslop 100
|
||||||
|
|
||||||
@ -422,13 +423,18 @@ asmb(void)
|
|||||||
{
|
{
|
||||||
Prog *p;
|
Prog *p;
|
||||||
int32 v, magic;
|
int32 v, magic;
|
||||||
int a, nl, dynsym;
|
int a, dynsym;
|
||||||
uchar *op1;
|
uchar *op1;
|
||||||
vlong vl, va, startva, fo, w, symo;
|
vlong vl, va, startva, fo, w, symo;
|
||||||
vlong symdatva = 0x99LL<<32;
|
vlong symdatva = 0x99LL<<32;
|
||||||
ElfEhdr *eh;
|
ElfEhdr *eh;
|
||||||
ElfPhdr *ph, *pph;
|
ElfPhdr *ph, *pph;
|
||||||
ElfShdr *sh;
|
ElfShdr *sh;
|
||||||
|
MachoHdr *mh;
|
||||||
|
MachoSect *msect;
|
||||||
|
MachoSeg *ms;
|
||||||
|
MachoDebug *md;
|
||||||
|
MachoLoad *ml;
|
||||||
|
|
||||||
if(debug['v'])
|
if(debug['v'])
|
||||||
Bprint(&bso, "%5.2f asmb\n", cputime());
|
Bprint(&bso, "%5.2f asmb\n", cputime());
|
||||||
@ -602,71 +608,91 @@ asmb(void)
|
|||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
/* apple MACH */
|
/* apple MACH */
|
||||||
va = 4096;
|
va = HEADR;
|
||||||
|
mh = getMachoHdr();
|
||||||
|
mh->cpu = MACHO_CPU_AMD64;
|
||||||
|
mh->subcpu = MACHO_SUBCPU_X86;
|
||||||
|
|
||||||
lputl(0xfeedfacf); /* 64-bit */
|
/* segment for zero page */
|
||||||
lputl((1<<24)|7); /* cputype - x86/ABI64 */
|
ms = newMachoSeg("__PAGEZERO", 0);
|
||||||
lputl(3); /* subtype - x86 */
|
ms->vsize = va;
|
||||||
lputl(2); /* file type - mach executable */
|
|
||||||
nl = 4;
|
|
||||||
if (!debug['s'])
|
|
||||||
nl += 3;
|
|
||||||
if (!debug['d']) // -d = turn off "dynamic loader"
|
|
||||||
nl += 3;
|
|
||||||
lputl(nl); /* number of loads */
|
|
||||||
lputl(machheadr()-32); /* size of loads */
|
|
||||||
lputl(1); /* flags - no undefines */
|
|
||||||
lputl(0); /* reserved */
|
|
||||||
|
|
||||||
machseg("__PAGEZERO",
|
|
||||||
0,va, /* vaddr vsize */
|
|
||||||
0,0, /* fileoffset filesize */
|
|
||||||
0,0, /* protects */
|
|
||||||
0,0); /* sections flags */
|
|
||||||
|
|
||||||
|
/* text */
|
||||||
v = rnd(HEADR+textsize, INITRND);
|
v = rnd(HEADR+textsize, INITRND);
|
||||||
machseg("__TEXT",
|
ms = newMachoSeg("__TEXT", 1);
|
||||||
va, /* vaddr */
|
ms->vaddr = va;
|
||||||
v, /* vsize */
|
ms->vsize = v;
|
||||||
0,v, /* fileoffset filesize */
|
ms->filesize = v;
|
||||||
7,5, /* protects */
|
ms->prot1 = 7;
|
||||||
1,0); /* sections flags */
|
ms->prot2 = 5;
|
||||||
machsect("__text", "__TEXT",
|
|
||||||
va+HEADR,v-HEADR, /* addr size */
|
|
||||||
HEADR,0,0,0, /* offset align reloc nreloc */
|
|
||||||
0|0x400); /* flag - some instructions */
|
|
||||||
|
|
||||||
|
msect = newMachoSect(ms, "__text");
|
||||||
|
msect->addr = va+HEADR;
|
||||||
|
msect->size = v - HEADR;
|
||||||
|
msect->off = HEADR;
|
||||||
|
msect->flag = 0x400; /* flag - some instructions */
|
||||||
|
|
||||||
|
/* data */
|
||||||
w = datsize+bsssize;
|
w = datsize+bsssize;
|
||||||
machseg("__DATA",
|
ms = newMachoSeg("__DATA", 2);
|
||||||
va+v, /* vaddr */
|
ms->vaddr = va+v;
|
||||||
w, /* vsize */
|
ms->vsize = w;
|
||||||
v,datsize, /* fileoffset filesize */
|
ms->fileoffset = v;
|
||||||
7,3, /* protects */
|
ms->filesize = datsize;
|
||||||
2,0); /* sections flags */
|
ms->prot1 = 7;
|
||||||
machsect("__data", "__DATA",
|
ms->prot2 = 3;
|
||||||
va+v,datsize, /* addr size */
|
|
||||||
v,0,0,0, /* offset align reloc nreloc */
|
|
||||||
0); /* flag */
|
|
||||||
machsect("__bss", "__DATA",
|
|
||||||
va+v+datsize,bsssize, /* addr size */
|
|
||||||
0,0,0,0, /* offset align reloc nreloc */
|
|
||||||
1); /* flag - zero fill */
|
|
||||||
|
|
||||||
machdylink();
|
msect = newMachoSect(ms, "__data");
|
||||||
machstack(entryvalue());
|
msect->addr = va+v;
|
||||||
|
msect->size = datsize;
|
||||||
|
msect->off = v;
|
||||||
|
|
||||||
|
msect = newMachoSect(ms, "__bss");
|
||||||
|
msect->addr = va+v+datsize;
|
||||||
|
msect->size = bsssize;
|
||||||
|
msect->flag = 1; /* flag - zero fill */
|
||||||
|
|
||||||
|
ml = newMachoLoad(5, 42+2); /* unix thread */
|
||||||
|
ml->data[0] = 4; /* thread type */
|
||||||
|
ml->data[1] = 42; /* word count */
|
||||||
|
ml->data[2+32] = entryvalue(); /* start pc */
|
||||||
|
ml->data[2+32+1] = entryvalue()>>32;
|
||||||
|
|
||||||
|
if(!debug['d']) {
|
||||||
|
ml = newMachoLoad(2, 4); /* LC_SYMTAB */
|
||||||
|
USED(ml);
|
||||||
|
|
||||||
|
ml = newMachoLoad(11, 18); /* LC_DYSYMTAB */
|
||||||
|
USED(ml);
|
||||||
|
|
||||||
|
ml = newMachoLoad(14, 6); /* LC_LOAD_DYLINKER */
|
||||||
|
ml->data[0] = 12; /* offset to string */
|
||||||
|
strcpy((char*)&ml->data[1], "/usr/lib/dyld");
|
||||||
|
}
|
||||||
|
|
||||||
if(!debug['s']) {
|
if(!debug['s']) {
|
||||||
machseg("__SYMDAT",
|
ms = newMachoSeg("__SYMDAT", 1);
|
||||||
symdatva, /* vaddr */
|
ms->vaddr = symdatva;
|
||||||
8+symsize+lcsize, /* vsize */
|
ms->vsize = 8+symsize+lcsize;
|
||||||
symo, 8+symsize+lcsize, /* fileoffset filesize */
|
ms->fileoffset = symo;
|
||||||
7, 5, /* protects */
|
ms->filesize = 8+symsize+lcsize;
|
||||||
0, 0); /* sections flags */
|
ms->prot1 = 7;
|
||||||
|
ms->prot2 = 5;
|
||||||
|
|
||||||
machsymseg(symo+8,symsize); /* fileoffset,filesize */
|
md = newMachoDebug();
|
||||||
machsymseg(symo+8+symsize,lcsize); /* fileoffset,filesize */
|
md->fileoffset = symo+8;
|
||||||
|
md->filesize = symsize;
|
||||||
|
|
||||||
|
md = newMachoDebug();
|
||||||
|
md->fileoffset = symo+8+symsize;
|
||||||
|
md->filesize = lcsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a = machowrite();
|
||||||
|
if(a > MACHORESERVE)
|
||||||
|
diag("MACHORESERVE too small: %d > %d", a, MACHORESERVE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7:
|
case 7:
|
||||||
/* elf amd-64 */
|
/* elf amd-64 */
|
||||||
|
|
||||||
@ -889,11 +915,8 @@ asmb(void)
|
|||||||
a += elfwritehdr();
|
a += elfwritehdr();
|
||||||
a += elfwritephdrs();
|
a += elfwritephdrs();
|
||||||
a += elfwriteshdrs();
|
a += elfwriteshdrs();
|
||||||
if (a > ELFRESERVE) {
|
if (a > ELFRESERVE)
|
||||||
diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
|
diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
|
||||||
}
|
|
||||||
cflush();
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cflush();
|
cflush();
|
||||||
@ -1079,122 +1102,3 @@ rnd(vlong v, vlong r)
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
machseg(char *name, vlong vaddr, vlong vsize, vlong foff, vlong fsize,
|
|
||||||
uint32 prot1, uint32 prot2, uint32 nsect, uint32 flag)
|
|
||||||
{
|
|
||||||
lputl(25); /* segment 64 */
|
|
||||||
lputl(72 + 80*nsect);
|
|
||||||
strnput(name, 16);
|
|
||||||
vputl(vaddr);
|
|
||||||
vputl(vsize);
|
|
||||||
vputl(foff);
|
|
||||||
vputl(fsize);
|
|
||||||
lputl(prot1);
|
|
||||||
lputl(prot2);
|
|
||||||
lputl(nsect);
|
|
||||||
lputl(flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
machsymseg(uint32 foffset, uint32 fsize)
|
|
||||||
{
|
|
||||||
lputl(3); /* obsolete gdb debug info */
|
|
||||||
lputl(16); /* size of symseg command */
|
|
||||||
lputl(foffset);
|
|
||||||
lputl(fsize);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
machsect(char *name, char *seg, vlong addr, vlong size, uint32 off,
|
|
||||||
uint32 align, uint32 reloc, uint32 nreloc, uint32 flag)
|
|
||||||
{
|
|
||||||
strnput(name, 16);
|
|
||||||
strnput(seg, 16);
|
|
||||||
vputl(addr);
|
|
||||||
vputl(size);
|
|
||||||
lputl(off);
|
|
||||||
lputl(align);
|
|
||||||
lputl(reloc);
|
|
||||||
lputl(nreloc);
|
|
||||||
lputl(flag);
|
|
||||||
lputl(0); /* reserved */
|
|
||||||
lputl(0); /* reserved */
|
|
||||||
lputl(0); /* reserved */
|
|
||||||
}
|
|
||||||
|
|
||||||
// Emit a section requesting the dynamic loader
|
|
||||||
// but giving it no work to do (an empty dynamic symbol table).
|
|
||||||
// This is enough to make the Apple tracing programs (like dtrace)
|
|
||||||
// accept the binary, so that one can run dtruss on a 6.out.
|
|
||||||
// The dynamic linker loads at 0x8fe00000, so if we want to
|
|
||||||
// be able to build >2GB binaries, we're going to need to move
|
|
||||||
// the text segment to 4G like Apple does.
|
|
||||||
void
|
|
||||||
machdylink(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if(debug['d'])
|
|
||||||
return;
|
|
||||||
|
|
||||||
lputl(2); /* LC_SYMTAB */
|
|
||||||
lputl(24); /* byte count - 6 words*/
|
|
||||||
for(i=0; i<4; i++)
|
|
||||||
lputl(0);
|
|
||||||
|
|
||||||
lputl(11); /* LC_DYSYMTAB */
|
|
||||||
lputl(80); /* byte count - 20 words */
|
|
||||||
for(i=0; i<18; i++)
|
|
||||||
lputl(0);
|
|
||||||
|
|
||||||
lputl(14); /* LC_LOAD_DYLINKER */
|
|
||||||
lputl(32); /* byte count */
|
|
||||||
lputl(12); /* offset to string */
|
|
||||||
strnput("/usr/lib/dyld", 32-12);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
machstack(vlong e)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
lputl(5); /* unix thread */
|
|
||||||
lputl((42+4)*4); /* total byte count */
|
|
||||||
|
|
||||||
lputl(4); /* thread type */
|
|
||||||
lputl(42); /* word count */
|
|
||||||
|
|
||||||
for(i=0; i<32; i++)
|
|
||||||
lputl(0);
|
|
||||||
vputl(e);
|
|
||||||
for(i=0; i<8; i++)
|
|
||||||
lputl(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32
|
|
||||||
machheadr(void)
|
|
||||||
{
|
|
||||||
uint32 a;
|
|
||||||
|
|
||||||
a = 8; /* a.out header */
|
|
||||||
a += 18; /* page zero seg */
|
|
||||||
a += 18; /* text seg */
|
|
||||||
a += 20; /* text sect */
|
|
||||||
a += 18; /* data seg */
|
|
||||||
a += 20; /* data sect */
|
|
||||||
a += 20; /* bss sect */
|
|
||||||
a += 46; /* stack sect */
|
|
||||||
if (!debug['d']) {
|
|
||||||
a += 6; /* symtab */
|
|
||||||
a += 20; /* dysymtab */
|
|
||||||
a += 8; /* load dylinker */
|
|
||||||
}
|
|
||||||
if (!debug['s']) {
|
|
||||||
a += 18; /* symdat seg */
|
|
||||||
a += 4; /* symtab seg */
|
|
||||||
a += 4; /* lctab seg */
|
|
||||||
}
|
|
||||||
|
|
||||||
return a*4;
|
|
||||||
}
|
|
||||||
|
6
src/cmd/6l/macho.c
Normal file
6
src/cmd/6l/macho.c
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "l.h"
|
||||||
|
#include "../ld/macho.c"
|
@ -31,6 +31,7 @@
|
|||||||
#define EXTERN
|
#define EXTERN
|
||||||
#include "l.h"
|
#include "l.h"
|
||||||
#include "../ld/elf.h"
|
#include "../ld/elf.h"
|
||||||
|
#include "../ld/macho.h"
|
||||||
#include <ar.h>
|
#include <ar.h>
|
||||||
|
|
||||||
char *noname = "<none>";
|
char *noname = "<none>";
|
||||||
@ -188,7 +189,8 @@ main(int argc, char *argv[])
|
|||||||
INITRND = 4096;
|
INITRND = 4096;
|
||||||
break;
|
break;
|
||||||
case 6: /* apple MACH */
|
case 6: /* apple MACH */
|
||||||
HEADR = machheadr();
|
machoinit();
|
||||||
|
HEADR = MACHORESERVE;
|
||||||
if(INITTEXT == -1)
|
if(INITTEXT == -1)
|
||||||
INITTEXT = 4096+HEADR;
|
INITTEXT = 4096+HEADR;
|
||||||
if(INITDAT == -1)
|
if(INITDAT == -1)
|
||||||
|
@ -13,6 +13,7 @@ OFILES=\
|
|||||||
elf.$O\
|
elf.$O\
|
||||||
enam.$O\
|
enam.$O\
|
||||||
list.$O\
|
list.$O\
|
||||||
|
macho.$O\
|
||||||
obj.$O\
|
obj.$O\
|
||||||
optab.$O\
|
optab.$O\
|
||||||
pass.$O\
|
pass.$O\
|
||||||
@ -23,6 +24,7 @@ HFILES=\
|
|||||||
l.h\
|
l.h\
|
||||||
../8l/8.out.h\
|
../8l/8.out.h\
|
||||||
../ld/elf.h\
|
../ld/elf.h\
|
||||||
|
../ld/macho.h\
|
||||||
|
|
||||||
|
|
||||||
$(TARG): $(OFILES)
|
$(TARG): $(OFILES)
|
||||||
@ -41,3 +43,4 @@ install: $(TARG)
|
|||||||
|
|
||||||
go.o: ../ld/go.c
|
go.o: ../ld/go.c
|
||||||
elf.o: ../ld/elf.c
|
elf.o: ../ld/elf.c
|
||||||
|
macho.o: ../ld/macho.c
|
||||||
|
282
src/cmd/8l/asm.c
282
src/cmd/8l/asm.c
@ -30,26 +30,12 @@
|
|||||||
|
|
||||||
#include "l.h"
|
#include "l.h"
|
||||||
#include "../ld/elf.h"
|
#include "../ld/elf.h"
|
||||||
|
#include "../ld/macho.h"
|
||||||
|
|
||||||
#define Dbufslop 100
|
#define Dbufslop 100
|
||||||
|
|
||||||
char linuxdynld[] = "/lib/ld-linux.so.2";
|
char linuxdynld[] = "/lib/ld-linux.so.2";
|
||||||
|
|
||||||
uint32 symdatva = 0x99<<24;
|
uint32 symdatva = 0x99<<24;
|
||||||
uint32 stroffset;
|
|
||||||
uint32 strtabsize;
|
|
||||||
|
|
||||||
uint32 machheadr(void);
|
|
||||||
uint32 elfheadr(void);
|
|
||||||
void elfphdr(int type, int flags, uint32 foff, uint32 vaddr, uint32 paddr, uint32 filesize, uint32 memsize, uint32 align);
|
|
||||||
void elfshdr(char *name, uint32 type, uint32 flags, uint32 addr, uint32 off, uint32 size, uint32 link, uint32 info, uint32 align, uint32 entsize);
|
|
||||||
int elfstrtable(void);
|
|
||||||
void machdylink(void);
|
|
||||||
uint32 machheadr(void);
|
|
||||||
void machsect(char *name, char *seg, vlong addr, vlong size, uint32 off, uint32 align, uint32 reloc, uint32 nreloc, uint32 flag);
|
|
||||||
void machseg(char *name, uint32 vaddr, uint32 vsize, uint32 foff, uint32 fsize, uint32 prot1, uint32 prot2, uint32 nsect, uint32 flag);
|
|
||||||
void machstack(vlong e);
|
|
||||||
void machsymseg(uint32 foffset, uint32 fsize);
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
entryvalue(void)
|
entryvalue(void)
|
||||||
@ -428,13 +414,18 @@ asmb(void)
|
|||||||
{
|
{
|
||||||
Prog *p;
|
Prog *p;
|
||||||
int32 v, magic;
|
int32 v, magic;
|
||||||
int a, nl, dynsym;
|
int a, dynsym;
|
||||||
uint32 va, fo, w, symo, startva;
|
uint32 va, fo, w, symo, startva;
|
||||||
uchar *op1;
|
uchar *op1;
|
||||||
ulong expectpc;
|
ulong expectpc;
|
||||||
Elf64_Ehdr *eh;
|
ElfEhdr *eh;
|
||||||
Elf64_Phdr *ph, *pph;
|
ElfPhdr *ph, *pph;
|
||||||
Elf64_Shdr *sh;
|
ElfShdr *sh;
|
||||||
|
MachoHdr *mh;
|
||||||
|
MachoSect *msect;
|
||||||
|
MachoSeg *ms;
|
||||||
|
MachoDebug *md;
|
||||||
|
MachoLoad *ml;
|
||||||
|
|
||||||
if(debug['v'])
|
if(debug['v'])
|
||||||
Bprint(&bso, "%5.2f asmb\n", cputime());
|
Bprint(&bso, "%5.2f asmb\n", cputime());
|
||||||
@ -585,7 +576,7 @@ asmb(void)
|
|||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
case 8:
|
case 8:
|
||||||
symo = rnd(HEADR+textsize, INITRND)+datsize+strtabsize;
|
symo = rnd(HEADR+textsize, INITRND)+datsize;
|
||||||
symo = rnd(symo, INITRND);
|
symo = rnd(symo, INITRND);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -750,69 +741,88 @@ asmb(void)
|
|||||||
|
|
||||||
case 6:
|
case 6:
|
||||||
/* apple MACH */
|
/* apple MACH */
|
||||||
va = 4096;
|
va = HEADR;
|
||||||
|
mh = getMachoHdr();
|
||||||
|
mh->cpu = MACHO_CPU_386;
|
||||||
|
mh->subcpu = MACHO_SUBCPU_X86;
|
||||||
|
|
||||||
lputl(0xfeedface); /* 32-bit */
|
/* segment for zero page */
|
||||||
lputl(7); /* cputype - x86 */
|
ms = newMachoSeg("__PAGEZERO", 0);
|
||||||
lputl(3); /* subtype - x86 */
|
ms->vsize = va;
|
||||||
lputl(2); /* file type - mach executable */
|
|
||||||
nl = 4;
|
|
||||||
if (!debug['s'])
|
|
||||||
nl += 3;
|
|
||||||
if (!debug['d']) // -d = turn off "dynamic loader"
|
|
||||||
nl += 3;
|
|
||||||
lputl(nl); /* number of loads */
|
|
||||||
lputl(machheadr()-28); /* size of loads */
|
|
||||||
lputl(1); /* flags - no undefines */
|
|
||||||
|
|
||||||
machseg("__PAGEZERO",
|
|
||||||
0,va, /* vaddr vsize */
|
|
||||||
0,0, /* fileoffset filesize */
|
|
||||||
0,0, /* protects */
|
|
||||||
0,0); /* sections flags */
|
|
||||||
|
|
||||||
|
/* text */
|
||||||
v = rnd(HEADR+textsize, INITRND);
|
v = rnd(HEADR+textsize, INITRND);
|
||||||
machseg("__TEXT",
|
ms = newMachoSeg("__TEXT", 1);
|
||||||
va, /* vaddr */
|
ms->vaddr = va;
|
||||||
v, /* vsize */
|
ms->vsize = v;
|
||||||
0,v, /* fileoffset filesize */
|
ms->filesize = v;
|
||||||
7,5, /* protects */
|
ms->prot1 = 7;
|
||||||
1,0); /* sections flags */
|
ms->prot2 = 5;
|
||||||
machsect("__text", "__TEXT",
|
|
||||||
va+HEADR,v-HEADR, /* addr size */
|
|
||||||
HEADR,0,0,0, /* offset align reloc nreloc */
|
|
||||||
0|0x400); /* flag - some instructions */
|
|
||||||
|
|
||||||
|
msect = newMachoSect(ms, "__text");
|
||||||
|
msect->addr = va+HEADR;
|
||||||
|
msect->size = v - HEADR;
|
||||||
|
msect->off = HEADR;
|
||||||
|
msect->flag = 0x400; /* flag - some instructions */
|
||||||
|
|
||||||
|
/* data */
|
||||||
w = datsize+bsssize;
|
w = datsize+bsssize;
|
||||||
machseg("__DATA",
|
ms = newMachoSeg("__DATA", 2);
|
||||||
va+v, /* vaddr */
|
ms->vaddr = va+v;
|
||||||
w, /* vsize */
|
ms->vsize = w;
|
||||||
v,datsize, /* fileoffset filesize */
|
ms->fileoffset = v;
|
||||||
7,3, /* protects */
|
ms->filesize = datsize;
|
||||||
2,0); /* sections flags */
|
ms->prot1 = 7;
|
||||||
machsect("__data", "__DATA",
|
ms->prot2 = 3;
|
||||||
va+v,datsize, /* addr size */
|
|
||||||
v,0,0,0, /* offset align reloc nreloc */
|
|
||||||
0); /* flag */
|
|
||||||
machsect("__bss", "__DATA",
|
|
||||||
va+v+datsize,bsssize, /* addr size */
|
|
||||||
0,0,0,0, /* offset align reloc nreloc */
|
|
||||||
1); /* flag - zero fill */
|
|
||||||
|
|
||||||
machdylink();
|
msect = newMachoSect(ms, "__data");
|
||||||
machstack(entryvalue());
|
msect->addr = va+v;
|
||||||
|
msect->size = datsize;
|
||||||
|
msect->off = v;
|
||||||
|
|
||||||
|
msect = newMachoSect(ms, "__bss");
|
||||||
|
msect->addr = va+v+datsize;
|
||||||
|
msect->size = bsssize;
|
||||||
|
msect->flag = 1; /* flag - zero fill */
|
||||||
|
|
||||||
|
ml = newMachoLoad(5, 16+2); /* unix thread */
|
||||||
|
ml->data[0] = 1; /* thread type */
|
||||||
|
ml->data[1] = 16; /* word count */
|
||||||
|
ml->data[2+10] = entryvalue(); /* start pc */
|
||||||
|
|
||||||
|
if(!debug['d']) {
|
||||||
|
ml = newMachoLoad(2, 4); /* LC_SYMTAB */
|
||||||
|
USED(ml);
|
||||||
|
|
||||||
|
ml = newMachoLoad(11, 18); /* LC_DYSYMTAB */
|
||||||
|
USED(ml);
|
||||||
|
|
||||||
|
ml = newMachoLoad(14, 6); /* LC_LOAD_DYLINKER */
|
||||||
|
ml->data[0] = 12; /* offset to string */
|
||||||
|
strcpy((char*)&ml->data[1], "/usr/lib/dyld");
|
||||||
|
}
|
||||||
|
|
||||||
if(!debug['s']) {
|
if(!debug['s']) {
|
||||||
machseg("__SYMDAT",
|
ms = newMachoSeg("__SYMDAT", 1);
|
||||||
symdatva, /* vaddr */
|
ms->vaddr = symdatva;
|
||||||
8+symsize+lcsize, /* vsize */
|
ms->vsize = 8+symsize+lcsize;
|
||||||
symo, 8+symsize+lcsize, /* fileoffset filesize */
|
ms->fileoffset = symo;
|
||||||
7, 5, /* protects */
|
ms->filesize = 8+symsize+lcsize;
|
||||||
0, 0); /* sections flags */
|
ms->prot1 = 7;
|
||||||
|
ms->prot2 = 5;
|
||||||
|
|
||||||
machsymseg(symo+8,symsize); /* fileoffset,filesize */
|
md = newMachoDebug();
|
||||||
machsymseg(symo+8+symsize,lcsize); /* fileoffset,filesize */
|
md->fileoffset = symo+8;
|
||||||
|
md->filesize = symsize;
|
||||||
|
|
||||||
|
md = newMachoDebug();
|
||||||
|
md->fileoffset = symo+8+symsize;
|
||||||
|
md->filesize = lcsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a = machowrite();
|
||||||
|
if(a > MACHORESERVE)
|
||||||
|
diag("MACHORESERVE too small: %d > %d", a, MACHORESERVE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7:
|
case 7:
|
||||||
@ -1242,129 +1252,3 @@ rnd(int32 v, int32 r)
|
|||||||
v -= c;
|
v -= c;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
machseg(char *name, uint32 vaddr, uint32 vsize, uint32 foff, uint32 fsize,
|
|
||||||
uint32 prot1, uint32 prot2, uint32 nsect, uint32 flag)
|
|
||||||
{
|
|
||||||
lputl(1); /* segment 32 */
|
|
||||||
lputl(56 + 68*nsect);
|
|
||||||
strnput(name, 16);
|
|
||||||
lputl(vaddr);
|
|
||||||
lputl(vsize);
|
|
||||||
lputl(foff);
|
|
||||||
lputl(fsize);
|
|
||||||
lputl(prot1);
|
|
||||||
lputl(prot2);
|
|
||||||
lputl(nsect);
|
|
||||||
lputl(flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
machsymseg(uint32 foffset, uint32 fsize)
|
|
||||||
{
|
|
||||||
lputl(3); /* obsolete gdb debug info */
|
|
||||||
lputl(16); /* size of symseg command */
|
|
||||||
lputl(foffset);
|
|
||||||
lputl(fsize);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
machsect(char *name, char *seg, vlong addr, vlong size, uint32 off,
|
|
||||||
uint32 align, uint32 reloc, uint32 nreloc, uint32 flag)
|
|
||||||
{
|
|
||||||
strnput(name, 16);
|
|
||||||
strnput(seg, 16);
|
|
||||||
lputl(addr);
|
|
||||||
lputl(size);
|
|
||||||
lputl(off);
|
|
||||||
lputl(align);
|
|
||||||
lputl(reloc);
|
|
||||||
lputl(nreloc);
|
|
||||||
lputl(flag);
|
|
||||||
lputl(0); /* reserved */
|
|
||||||
lputl(0); /* reserved */
|
|
||||||
}
|
|
||||||
|
|
||||||
// Emit a section requesting the dynamic loader
|
|
||||||
// but giving it no work to do (an empty dynamic symbol table).
|
|
||||||
// This is enough to make the Apple tracing programs (like dtrace)
|
|
||||||
// accept the binary, so that one can run dtruss on an 8.out.
|
|
||||||
void
|
|
||||||
machdylink(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if(debug['d'])
|
|
||||||
return;
|
|
||||||
|
|
||||||
lputl(2); /* LC_SYMTAB */
|
|
||||||
lputl(24); /* byte count - 6 words*/
|
|
||||||
for(i=0; i<4; i++)
|
|
||||||
lputl(0);
|
|
||||||
|
|
||||||
lputl(11); /* LC_DYSYMTAB */
|
|
||||||
lputl(80); /* byte count - 20 words */
|
|
||||||
for(i=0; i<18; i++)
|
|
||||||
lputl(0);
|
|
||||||
|
|
||||||
lputl(14); /* LC_LOAD_DYLINKER */
|
|
||||||
lputl(32); /* byte count */
|
|
||||||
lputl(12); /* offset to string */
|
|
||||||
strnput("/usr/lib/dyld", 32-12);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
machstack(vlong e)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
lputl(5); /* unix thread */
|
|
||||||
lputl((16+4)*4); /* total byte count */
|
|
||||||
|
|
||||||
lputl(1); /* thread type - x86_THREAD_STATE32 */
|
|
||||||
lputl(16); /* word count */
|
|
||||||
|
|
||||||
for(i=0; i<16; i++) /* initial register set */
|
|
||||||
if(i == 10)
|
|
||||||
lputl(e);
|
|
||||||
else
|
|
||||||
lputl(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32
|
|
||||||
machheadr(void)
|
|
||||||
{
|
|
||||||
uint32 a;
|
|
||||||
enum {
|
|
||||||
Header = 28,
|
|
||||||
Seg = 56,
|
|
||||||
Sect = 68,
|
|
||||||
Symtab = 24,
|
|
||||||
Dysymtab = 80,
|
|
||||||
LoadDylinker = 32,
|
|
||||||
Stack = 80,
|
|
||||||
Symseg = 16,
|
|
||||||
};
|
|
||||||
|
|
||||||
a = Header; /* a.out header */
|
|
||||||
a += Seg; /* page zero seg */
|
|
||||||
a += Seg; /* text seg */
|
|
||||||
a += Sect; /* text sect */
|
|
||||||
a += Seg; /* data seg */
|
|
||||||
a += Sect; /* data sect */
|
|
||||||
a += Sect; /* bss sect */
|
|
||||||
if (!debug['d']) {
|
|
||||||
a += Symtab; /* symtab */
|
|
||||||
a += Dysymtab; /* dysymtab */
|
|
||||||
a += LoadDylinker; /* load dylinker */
|
|
||||||
}
|
|
||||||
a += Stack; /* stack sect */
|
|
||||||
if (!debug['s']) {
|
|
||||||
a += Seg; /* symdat seg */
|
|
||||||
a += Symseg; /* symtab seg */
|
|
||||||
a += Symseg; /* lctab seg */
|
|
||||||
}
|
|
||||||
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
@ -371,6 +371,7 @@ Sym* lookup(char*, int);
|
|||||||
void lput(int32);
|
void lput(int32);
|
||||||
void lputl(int32);
|
void lputl(int32);
|
||||||
void vputl(uvlong);
|
void vputl(uvlong);
|
||||||
|
void strnput(char*, int);
|
||||||
void main(int, char*[]);
|
void main(int, char*[]);
|
||||||
void mkfwd(void);
|
void mkfwd(void);
|
||||||
void* mal(uint32);
|
void* mal(uint32);
|
||||||
|
6
src/cmd/8l/macho.c
Normal file
6
src/cmd/8l/macho.c
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "l.h"
|
||||||
|
#include "../ld/macho.c"
|
@ -31,6 +31,7 @@
|
|||||||
#define EXTERN
|
#define EXTERN
|
||||||
#include "l.h"
|
#include "l.h"
|
||||||
#include "../ld/elf.h"
|
#include "../ld/elf.h"
|
||||||
|
#include "../ld/macho.h"
|
||||||
#include <ar.h>
|
#include <ar.h>
|
||||||
|
|
||||||
#ifndef DEFAULT
|
#ifndef DEFAULT
|
||||||
@ -212,7 +213,8 @@ main(int argc, char *argv[])
|
|||||||
Bprint(&bso, "HEADR = 0x%ld\n", HEADR);
|
Bprint(&bso, "HEADR = 0x%ld\n", HEADR);
|
||||||
break;
|
break;
|
||||||
case 6: /* apple MACH */
|
case 6: /* apple MACH */
|
||||||
HEADR = machheadr();
|
machoinit();
|
||||||
|
HEADR = MACHORESERVE;
|
||||||
if(INITTEXT == -1)
|
if(INITTEXT == -1)
|
||||||
INITTEXT = 4096+HEADR;
|
INITTEXT = 4096+HEADR;
|
||||||
if(INITDAT == -1)
|
if(INITDAT == -1)
|
||||||
|
@ -963,7 +963,7 @@ extern int numelfphdr;
|
|||||||
extern int numelfshdr;
|
extern int numelfshdr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Total amount of ELF space to reserve at the start of the file
|
* Total amount of space to reserve at the start of the file
|
||||||
* for Header, PHeaders, and SHeaders.
|
* for Header, PHeaders, and SHeaders.
|
||||||
* May waste some.
|
* May waste some.
|
||||||
*/
|
*/
|
||||||
|
207
src/cmd/ld/macho.c
Normal file
207
src/cmd/ld/macho.c
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Mach-O file writing
|
||||||
|
// http://developer.apple.com/mac/library/DOCUMENTATION/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html
|
||||||
|
|
||||||
|
#include "../ld/macho.h"
|
||||||
|
|
||||||
|
static int macho64;
|
||||||
|
static MachoHdr hdr;
|
||||||
|
static MachoLoad load[16];
|
||||||
|
static MachoSeg seg[16];
|
||||||
|
static MachoDebug xdebug[16];
|
||||||
|
static int nload, nseg, ndebug, nsect;
|
||||||
|
|
||||||
|
void
|
||||||
|
machoinit(void)
|
||||||
|
{
|
||||||
|
switch(thechar) {
|
||||||
|
// 64-bit architectures
|
||||||
|
case '6':
|
||||||
|
macho64 = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// 32-bit architectures
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MachoHdr*
|
||||||
|
getMachoHdr(void)
|
||||||
|
{
|
||||||
|
return &hdr;
|
||||||
|
}
|
||||||
|
|
||||||
|
MachoLoad*
|
||||||
|
newMachoLoad(uint32 type, uint32 ndata)
|
||||||
|
{
|
||||||
|
MachoLoad *l;
|
||||||
|
|
||||||
|
if(nload >= nelem(load)) {
|
||||||
|
diag("too many loads");
|
||||||
|
errorexit();
|
||||||
|
}
|
||||||
|
l = &load[nload++];
|
||||||
|
l->type = type;
|
||||||
|
l->ndata = ndata;
|
||||||
|
l->data = mal(ndata*4);
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
MachoSeg*
|
||||||
|
newMachoSeg(char *name, int msect)
|
||||||
|
{
|
||||||
|
MachoSeg *s;
|
||||||
|
|
||||||
|
if(nseg >= nelem(seg)) {
|
||||||
|
diag("too many segs");
|
||||||
|
errorexit();
|
||||||
|
}
|
||||||
|
s = &seg[nseg++];
|
||||||
|
s->name = name;
|
||||||
|
s->msect = msect;
|
||||||
|
s->sect = mal(msect*sizeof s->sect[0]);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
MachoSect*
|
||||||
|
newMachoSect(MachoSeg *seg, char *name)
|
||||||
|
{
|
||||||
|
MachoSect *s;
|
||||||
|
|
||||||
|
if(seg->nsect >= seg->msect) {
|
||||||
|
diag("too many sects in segment %s", seg->name);
|
||||||
|
errorexit();
|
||||||
|
}
|
||||||
|
s = &seg->sect[seg->nsect++];
|
||||||
|
s->name = name;
|
||||||
|
nsect++;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
MachoDebug*
|
||||||
|
newMachoDebug(void)
|
||||||
|
{
|
||||||
|
if(ndebug >= nelem(xdebug)) {
|
||||||
|
diag("too many debugs");
|
||||||
|
errorexit();
|
||||||
|
}
|
||||||
|
return &xdebug[ndebug++];
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
machowrite(void)
|
||||||
|
{
|
||||||
|
vlong o1;
|
||||||
|
int loadsize;
|
||||||
|
int i, j;
|
||||||
|
MachoSeg *s;
|
||||||
|
MachoSect *t;
|
||||||
|
MachoDebug *d;
|
||||||
|
MachoLoad *l;
|
||||||
|
|
||||||
|
o1 = Boffset(&bso);
|
||||||
|
|
||||||
|
loadsize = 4*4*ndebug;
|
||||||
|
for(i=0; i<nload; i++)
|
||||||
|
loadsize += 4*(load[i].ndata+2);
|
||||||
|
if(macho64) {
|
||||||
|
loadsize += 18*4*nseg;
|
||||||
|
loadsize += 20*4*nsect;
|
||||||
|
} else {
|
||||||
|
loadsize += 14*4*nseg;
|
||||||
|
loadsize += 17*4*nsect;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(macho64)
|
||||||
|
LPUT(0xfeedfacf);
|
||||||
|
else
|
||||||
|
LPUT(0xfeedface);
|
||||||
|
LPUT(hdr.cpu);
|
||||||
|
LPUT(hdr.subcpu);
|
||||||
|
LPUT(2); /* file type - mach executable */
|
||||||
|
LPUT(nload+nseg+ndebug);
|
||||||
|
LPUT(loadsize);
|
||||||
|
LPUT(1); /* flags - no undefines */
|
||||||
|
if(macho64)
|
||||||
|
LPUT(0); /* reserved */
|
||||||
|
|
||||||
|
for(i=0; i<nseg; i++) {
|
||||||
|
s = &seg[i];
|
||||||
|
if(macho64) {
|
||||||
|
LPUT(25); /* segment 64 */
|
||||||
|
LPUT(72+80*s->nsect);
|
||||||
|
strnput(s->name, 16);
|
||||||
|
VPUT(s->vaddr);
|
||||||
|
VPUT(s->vsize);
|
||||||
|
VPUT(s->fileoffset);
|
||||||
|
VPUT(s->filesize);
|
||||||
|
LPUT(s->prot1);
|
||||||
|
LPUT(s->prot2);
|
||||||
|
LPUT(s->nsect);
|
||||||
|
LPUT(s->flag);
|
||||||
|
} else {
|
||||||
|
LPUT(1); /* segment 32 */
|
||||||
|
LPUT(56+68*s->nsect);
|
||||||
|
strnput(s->name, 16);
|
||||||
|
LPUT(s->vaddr);
|
||||||
|
LPUT(s->vsize);
|
||||||
|
LPUT(s->fileoffset);
|
||||||
|
LPUT(s->filesize);
|
||||||
|
LPUT(s->prot1);
|
||||||
|
LPUT(s->prot2);
|
||||||
|
LPUT(s->nsect);
|
||||||
|
LPUT(s->flag);
|
||||||
|
}
|
||||||
|
for(j=0; j<s->nsect; j++) {
|
||||||
|
t = &s->sect[j];
|
||||||
|
if(macho64) {
|
||||||
|
strnput(t->name, 16);
|
||||||
|
strnput(s->name, 16);
|
||||||
|
VPUT(t->addr);
|
||||||
|
VPUT(t->size);
|
||||||
|
LPUT(t->off);
|
||||||
|
LPUT(t->align);
|
||||||
|
LPUT(t->reloc);
|
||||||
|
LPUT(t->nreloc);
|
||||||
|
LPUT(t->flag);
|
||||||
|
LPUT(0); /* reserved */
|
||||||
|
LPUT(0); /* reserved */
|
||||||
|
LPUT(0); /* reserved */
|
||||||
|
} else {
|
||||||
|
strnput(t->name, 16);
|
||||||
|
strnput(s->name, 16);
|
||||||
|
LPUT(t->addr);
|
||||||
|
LPUT(t->size);
|
||||||
|
LPUT(t->off);
|
||||||
|
LPUT(t->align);
|
||||||
|
LPUT(t->reloc);
|
||||||
|
LPUT(t->nreloc);
|
||||||
|
LPUT(t->flag);
|
||||||
|
LPUT(0); /* reserved */
|
||||||
|
LPUT(0); /* reserved */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0; i<nload; i++) {
|
||||||
|
l = &load[i];
|
||||||
|
LPUT(l->type);
|
||||||
|
LPUT(4*(l->ndata+2));
|
||||||
|
for(j=0; j<l->ndata; j++)
|
||||||
|
LPUT(l->data[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0; i<ndebug; i++) {
|
||||||
|
d = &xdebug[i];
|
||||||
|
LPUT(3); /* obsolete gdb debug info */
|
||||||
|
LPUT(16); /* size of symseg command */
|
||||||
|
LPUT(d->fileoffset);
|
||||||
|
LPUT(d->filesize);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Boffset(&bso) - o1;
|
||||||
|
}
|
70
src/cmd/ld/macho.h
Normal file
70
src/cmd/ld/macho.h
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
typedef struct MachoHdr MachoHdr;
|
||||||
|
struct MachoHdr {
|
||||||
|
uint32 cpu;
|
||||||
|
uint32 subcpu;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct MachoSect MachoSect;
|
||||||
|
struct MachoSect {
|
||||||
|
char* name;
|
||||||
|
uint64 addr;
|
||||||
|
uint64 size;
|
||||||
|
uint32 off;
|
||||||
|
uint32 align;
|
||||||
|
uint32 reloc;
|
||||||
|
uint32 nreloc;
|
||||||
|
uint32 flag;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct MachoSeg MachoSeg;
|
||||||
|
struct MachoSeg {
|
||||||
|
char* name;
|
||||||
|
uint64 vsize;
|
||||||
|
uint64 vaddr;
|
||||||
|
uint64 fileoffset;
|
||||||
|
uint64 filesize;
|
||||||
|
uint32 prot1;
|
||||||
|
uint32 prot2;
|
||||||
|
uint32 nsect;
|
||||||
|
uint32 msect;
|
||||||
|
MachoSect *sect;
|
||||||
|
uint32 flag;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct MachoLoad MachoLoad;
|
||||||
|
struct MachoLoad {
|
||||||
|
uint32 type;
|
||||||
|
uint32 ndata;
|
||||||
|
uint32 *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct MachoDebug MachoDebug;
|
||||||
|
struct MachoDebug {
|
||||||
|
uint32 fileoffset;
|
||||||
|
uint32 filesize;
|
||||||
|
};
|
||||||
|
|
||||||
|
MachoHdr* getMachoHdr();
|
||||||
|
MachoSeg* newMachoSeg(char*, int);
|
||||||
|
MachoSect* newMachoSect(MachoSeg*, char*);
|
||||||
|
MachoLoad* newMachoLoad(uint32, uint32);
|
||||||
|
MachoDebug* newMachoDebug(void);
|
||||||
|
int machowrite(void);
|
||||||
|
void machoinit(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Total amount of space to reserve at the start of the file
|
||||||
|
* for Header, PHeaders, and SHeaders.
|
||||||
|
* May waste some.
|
||||||
|
*/
|
||||||
|
#define MACHORESERVE 4096
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MACHO_CPU_AMD64 = (1<<24)|7,
|
||||||
|
MACHO_CPU_386 = 7,
|
||||||
|
MACHO_SUBCPU_X86 = 3,
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user