diff options
| author | Shenghou Ma <minux@golang.org> | 2014-12-26 00:15:07 -0500 |
|---|---|---|
| committer | Minux Ma <minux@golang.org> | 2015-02-06 05:41:15 +0000 |
| commit | 1083715b7f2cb89e90a9ef04012a427aabe4e648 (patch) | |
| tree | 524919ef007b2125b19e2ed27c85fc9ae7691b78 /src/cmd/5l | |
| parent | db0d3892e0f3b246475c473685249427f86e3a56 (diff) | |
| download | go-1083715b7f2cb89e90a9ef04012a427aabe4e648.tar.xz | |
liblink, cmd/ld, cmd/5l: darwin/arm support
liblink:
- set dummy value for ctxt->tlsoffset.
cmd/ld:
- always do external linking when using cgo on darwin/arm,
as our linker might not generate codesign-compatible binary.
cmd/5l:
- support generate ARM Mach-O binaries
- add machoreloc1() that translate our internal relocation to
macho relocations used by external linking.
Change-Id: Ic5454aeb87009aaf8f1453ec7fe33e6da55d5f06
Reviewed-on: https://go-review.googlesource.com/3273
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Diffstat (limited to 'src/cmd/5l')
| -rw-r--r-- | src/cmd/5l/asm.c | 94 | ||||
| -rw-r--r-- | src/cmd/5l/obj.c | 13 |
2 files changed, 102 insertions, 5 deletions
diff --git a/src/cmd/5l/asm.c b/src/cmd/5l/asm.c index 5993079126..3ed5b673d4 100644 --- a/src/cmd/5l/asm.c +++ b/src/cmd/5l/asm.c @@ -33,9 +33,9 @@ #include "l.h" #include "../ld/lib.h" #include "../ld/elf.h" +#include "../ld/macho.h" #include "../ld/dwarf.h" - char linuxdynld[] = "/lib/ld-linux.so.3"; // 2 for OABI, 3 for EABI char freebsddynld[] = "/usr/libexec/ld-elf.so.1"; char openbsddynld[] = "XXX"; @@ -301,10 +301,58 @@ elfsetupplt(void) int machoreloc1(Reloc *r, vlong sectoff) { - USED(r); - USED(sectoff); + uint32 v; + LSym *rs; - return -1; + rs = r->xsym; + + if(rs->type == SHOSTOBJ || r->type == R_CALLARM) { + if(rs->dynid < 0) { + diag("reloc %d to non-macho symbol %s type=%d", r->type, rs->name, rs->type); + return -1; + } + v = rs->dynid; + v |= 1<<27; // external relocation + } else { + v = rs->sect->extnum; + if(v == 0) { + diag("reloc %d to symbol %s in non-macho section %s type=%d", r->type, rs->name, rs->sect->name, rs->type); + return -1; + } + } + + switch(r->type) { + default: + return -1; + case R_ADDR: + v |= MACHO_GENERIC_RELOC_VANILLA<<28; + break; + case R_CALLARM: + v |= 1<<24; // pc-relative bit + v |= MACHO_ARM_RELOC_BR24<<28; + break; + } + + switch(r->siz) { + default: + return -1; + case 1: + v |= 0<<25; + break; + case 2: + v |= 1<<25; + break; + case 4: + v |= 2<<25; + break; + case 8: + v |= 3<<25; + break; + } + + LPUT(sectoff); + LPUT(v); + return 0; } @@ -333,6 +381,14 @@ archreloc(Reloc *r, LSym *s, vlong *val) diag("missing section for %s", rs->name); r->xsym = rs; + // ld64 for arm seems to want the symbol table to contain offset + // into the section rather than pseudo virtual address that contains + // the section load address. + // we need to compensate that by removing the instruction's address + // from addend. + if(HEADTYPE == Hdarwin) + r->xadd -= symaddr(s) + r->off; + *val = braddoff((0xff000000U & (uint32)r->add), (0xffffff & (uint32)(r->xadd / 4))); return 0; @@ -539,6 +595,8 @@ adddynlib(char *lib) if(s->size == 0) addstring(s, ""); elfwritedynent(linklookup(ctxt, ".dynamic", 0), DT_NEEDED, addstring(s, lib)); + } else if(HEADTYPE == Hdarwin) { + machoadddynlib(lib); } else { diag("adddynlib: unsupported binary format"); } @@ -547,7 +605,7 @@ adddynlib(char *lib) void asmb(void) { - uint32 symo; + uint32 symo, dwarfoff, machlink; Section *sect; LSym *sym; int i; @@ -583,6 +641,22 @@ asmb(void) cseek(segdata.fileoff); datblk(segdata.vaddr, segdata.filelen); + machlink = 0; + if(HEADTYPE == Hdarwin) { + if(debug['v']) + Bprint(&bso, "%5.2f dwarf\n", cputime()); + + if(!debug['w']) { // TODO(minux): enable DWARF Support + dwarfoff = rnd(HEADR+segtext.len, INITRND) + rnd(segdata.filelen, INITRND); + cseek(dwarfoff); + + segdwarf.fileoff = cpos(); + dwarfemitdebugsections(); + segdwarf.filelen = cpos() - segdwarf.fileoff; + } + machlink = domacholink(); + } + /* output symbol table */ symsize = 0; lcsize = 0; @@ -599,6 +673,9 @@ asmb(void) case Hplan9: symo = segdata.fileoff+segdata.filelen; break; + case Hdarwin: + symo = rnd(HEADR+segtext.filelen, INITRND)+rnd(segdata.filelen, INITRND)+machlink; + break; ElfSym: symo = segdata.fileoff+segdata.filelen; symo = rnd(symo, INITRND); @@ -635,6 +712,10 @@ asmb(void) cflush(); } break; + case Hdarwin: + if(linkmode == LinkExternal) + machoemitreloc(); + break; } } @@ -662,6 +743,9 @@ asmb(void) case Hnacl: asmbelf(symo); break; + case Hdarwin: + asmbmacho(); + break; } cflush(); if(debug['c']){ diff --git a/src/cmd/5l/obj.c b/src/cmd/5l/obj.c index c6f60ee7c8..73ff751487 100644 --- a/src/cmd/5l/obj.c +++ b/src/cmd/5l/obj.c @@ -33,6 +33,7 @@ #include "l.h" #include "../ld/lib.h" #include "../ld/elf.h" +#include "../ld/macho.h" #include "../ld/dwarf.h" #include <ar.h> @@ -64,6 +65,7 @@ archinit(void) case Hlinux: case Hfreebsd: case Hnacl: + case Hdarwin: break; } @@ -104,6 +106,17 @@ archinit(void) if(INITRND == -1) INITRND = 0x10000; break; + case Hdarwin: /* apple MACH */ + debug['w'] = 1; // disable DWARF generataion + machoinit(); + HEADR = INITIAL_MACHO_HEADR; + if(INITTEXT == -1) + INITTEXT = 4096+HEADR; + if(INITDAT == -1) + INITDAT = 0; + if(INITRND == -1) + INITRND = 4096; + break; } if(INITDAT != 0 && INITRND != 0) print("warning: -D0x%ux is ignored because of -R0x%ux\n", |
