aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/6l
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2013-03-07 09:19:02 -0500
committerRuss Cox <rsc@golang.org>2013-03-07 09:19:02 -0500
commit60f783d92bc07fa7ca78e8efccbbc841d9f9cbcb (patch)
tree8677601561fbb007429777514911480aa4c871fd /src/cmd/6l
parent8aafb44b0bbba85535feb67e7ae0f4f254524c0f (diff)
downloadgo-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.c26
-rw-r--r--src/cmd/6l/l.h2
-rw-r--r--src/cmd/6l/obj.c6
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);