diff options
| author | Russ Cox <rsc@golang.org> | 2013-03-07 09:19:02 -0500 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2013-03-07 09:19:02 -0500 |
| commit | 60f783d92bc07fa7ca78e8efccbbc841d9f9cbcb (patch) | |
| tree | 8677601561fbb007429777514911480aa4c871fd /src/cmd/6l | |
| parent | 8aafb44b0bbba85535feb67e7ae0f4f254524c0f (diff) | |
| download | go-60f783d92bc07fa7ca78e8efccbbc841d9f9cbcb.tar.xz | |
cmd/ld: host linking support for linux/amd64
Still to do: non-linux and non-amd64.
It may work on other ELF-based amd64 systems too, but untested.
"go test -ldflags -hostobj $GOROOT/misc/cgo/test" passes.
Much may yet change, but this seems a reasonable checkpoint.
R=iant
CC=golang-dev
https://golang.org/cl/7369057
Diffstat (limited to 'src/cmd/6l')
| -rw-r--r-- | src/cmd/6l/asm.c | 26 | ||||
| -rw-r--r-- | src/cmd/6l/l.h | 2 | ||||
| -rw-r--r-- | src/cmd/6l/obj.c | 6 |
3 files changed, 20 insertions, 14 deletions
diff --git a/src/cmd/6l/asm.c b/src/cmd/6l/asm.c index 5fb75ba4d0..627e10af0a 100644 --- a/src/cmd/6l/asm.c +++ b/src/cmd/6l/asm.c @@ -131,7 +131,7 @@ adddynrel(Sym *s, Reloc *r) // Handle relocations found in ELF object files. case 256 + R_X86_64_PC32: - if(targ->dynimpname != nil && !targ->dynexport) + if(targ->dynimpname != nil && !(targ->cgoexport & CgoExportDynamic)) diag("unexpected R_X86_64_PC32 relocation for dynamic symbol %s", targ->name); if(targ->type == 0 || targ->type == SXREF) diag("unknown symbol %s in pcrel", targ->name); @@ -142,7 +142,7 @@ adddynrel(Sym *s, Reloc *r) case 256 + R_X86_64_PLT32: r->type = D_PCREL; r->add += 4; - if(targ->dynimpname != nil && !targ->dynexport) { + if(targ->dynimpname != nil && !(targ->cgoexport & CgoExportDynamic)) { addpltsym(targ); r->sym = lookup(".plt", 0); r->add += targ->plt; @@ -150,7 +150,7 @@ adddynrel(Sym *s, Reloc *r) return; case 256 + R_X86_64_GOTPCREL: - if(targ->dynimpname == nil || targ->dynexport) { + if(targ->dynimpname == nil || (targ->cgoexport & CgoExportDynamic)) { // have symbol if(r->off >= 2 && s->p[r->off-2] == 0x8b) { // turn MOVQ of GOT entry into LEAQ of symbol itself @@ -171,7 +171,7 @@ adddynrel(Sym *s, Reloc *r) return; case 256 + R_X86_64_64: - if(targ->dynimpname != nil && !targ->dynexport) + if(targ->dynimpname != nil && !(targ->cgoexport & CgoExportDynamic)) diag("unexpected R_X86_64_64 relocation for dynamic symbol %s", targ->name); r->type = D_ADDR; return; @@ -182,12 +182,12 @@ adddynrel(Sym *s, Reloc *r) case 512 + MACHO_X86_64_RELOC_BRANCH*2 + 0: // TODO: What is the difference between all these? r->type = D_ADDR; - if(targ->dynimpname != nil && !targ->dynexport) + if(targ->dynimpname != nil && !(targ->cgoexport & CgoExportDynamic)) diag("unexpected reloc for dynamic symbol %s", targ->name); return; case 512 + MACHO_X86_64_RELOC_BRANCH*2 + 1: - if(targ->dynimpname != nil && !targ->dynexport) { + if(targ->dynimpname != nil && !(targ->cgoexport & CgoExportDynamic)) { addpltsym(targ); r->sym = lookup(".plt", 0); r->add = targ->plt; @@ -201,12 +201,12 @@ adddynrel(Sym *s, Reloc *r) case 512 + MACHO_X86_64_RELOC_SIGNED_2*2 + 1: case 512 + MACHO_X86_64_RELOC_SIGNED_4*2 + 1: r->type = D_PCREL; - if(targ->dynimpname != nil && !targ->dynexport) + if(targ->dynimpname != nil && !(targ->cgoexport & CgoExportDynamic)) diag("unexpected pc-relative reloc for dynamic symbol %s", targ->name); return; case 512 + MACHO_X86_64_RELOC_GOT_LOAD*2 + 1: - if(targ->dynimpname == nil || targ->dynexport) { + if(targ->dynimpname == nil || (targ->cgoexport & CgoExportDynamic)) { // have symbol // turn MOVQ of GOT entry into LEAQ of symbol itself if(r->off < 2 || s->p[r->off-2] != 0x8b) { @@ -219,7 +219,7 @@ adddynrel(Sym *s, Reloc *r) } // fall through case 512 + MACHO_X86_64_RELOC_GOT*2 + 1: - if(targ->dynimpname == nil || targ->dynexport) + if(targ->dynimpname == nil || (targ->cgoexport & CgoExportDynamic)) diag("unexpected GOT reloc for non-dynamic symbol %s", targ->name); addgotsym(targ); r->type = D_PCREL; @@ -229,7 +229,7 @@ adddynrel(Sym *s, Reloc *r) } // Handle references to ELF symbols from our own object files. - if(targ->dynimpname == nil || targ->dynexport) + if(targ->dynimpname == nil || (targ->cgoexport & CgoExportDynamic)) return; switch(r->type) { @@ -470,7 +470,7 @@ adddynsym(Sym *s) adduint32(d, addstring(lookup(".dynstr", 0), name)); /* type */ t = STB_GLOBAL << 4; - if(s->dynexport && (s->type&SMASK) == STEXT) + if((s->cgoexport & CgoExportDynamic) && (s->type&SMASK) == STEXT) t |= STT_FUNC; else t |= STT_OBJECT; @@ -480,7 +480,7 @@ adddynsym(Sym *s) adduint8(d, 0); /* section where symbol is defined */ - if(!s->dynexport && s->dynimpname != nil) + if(!(s->cgoexport & CgoExportDynamic) && s->dynimpname != nil) adduint16(d, SHN_UNDEF); else { switch(s->type) { @@ -510,7 +510,7 @@ adddynsym(Sym *s) /* size of object */ adduint64(d, s->size); - if(!s->dynexport && s->dynimplib && needlib(s->dynimplib)) { + if(!(s->cgoexport & CgoExportDynamic) && s->dynimplib && needlib(s->dynimplib)) { elfwritedynent(lookup(".dynamic", 0), DT_NEEDED, addstring(lookup(".dynstr", 0), s->dynimplib)); } diff --git a/src/cmd/6l/l.h b/src/cmd/6l/l.h index ffb8a45522..22fb23b1b7 100644 --- a/src/cmd/6l/l.h +++ b/src/cmd/6l/l.h @@ -144,7 +144,7 @@ struct Sym short version; uchar dupok; uchar reachable; - uchar dynexport; + uchar cgoexport; uchar special; uchar stkcheck; uchar hide; diff --git a/src/cmd/6l/obj.c b/src/cmd/6l/obj.c index 10e4a98601..6ced8be7fd 100644 --- a/src/cmd/6l/obj.c +++ b/src/cmd/6l/obj.c @@ -83,6 +83,7 @@ main(int argc, char *argv[]) INITRND = -1; INITENTRY = 0; LIBINITENTRY = 0; + linkmode = LinkInternal; // TODO: LinkAuto once everything works. nuxiinit(); flagcount("1", "use alternate profiling code", &debug['1']); @@ -122,6 +123,10 @@ main(int argc, char *argv[]) flagcount("shared", "generate shared object", &flag_shared); flagparse(&argc, &argv, usage); + + // TODO: link mode flag instead of isobj + if(isobj) + linkmode = LinkExternal; if(argc != 1) usage(); @@ -282,6 +287,7 @@ main(int argc, char *argv[]) reloc(); asmb(); undef(); + hostlink(); if(debug['v']) { Bprint(&bso, "%5.2f cpu time\n", cputime()); Bprint(&bso, "%d symbols\n", nsymbol); |
