From 0cb0f6d0902aff683de5535565e923c45f8d5a8a Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Thu, 31 Jan 2013 14:11:32 -0800 Subject: cmd/ld: support for linking with host linker A step toward a fix for issue 4069. To allow linking with arbitrary host object files, add a linker mode that can generate a host object file instead of an executable. Then the host linker can be invoked to generate the final executable. This CL adds a new -hostobj flag that instructs the linker to write a host object file instead of an executable. That is, this works: go tool 6g x.go go tool 6l -hostobj -o x.o x.6 ld -e _rt0_amd64_linux x.o ./a.out as does: go tool 8g x.go go tool 8l -hostld ignored -o x.o x.8 ld -m elf_i386 -e _rt0_386_linux x.o ./a.out Because 5l was never updated to use the standard relocation scheme, it will take more work to get this working on ARM. This is a checkpoint of the basic functionality. It does not work with cgo yet, and cgo is the main reason for the change. The command-line interface will likely change too. The gc linker has other information that needs to be returned to the caller for use when invoking the host linker besides the single object file. R=iant, iant CC=golang-dev https://golang.org/cl/7060044 --- src/cmd/ld/data.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'src/cmd/ld/data.c') diff --git a/src/cmd/ld/data.c b/src/cmd/ld/data.c index 30e1309d24..e557881e94 100644 --- a/src/cmd/ld/data.c +++ b/src/cmd/ld/data.c @@ -146,6 +146,7 @@ void relocsym(Sym *s) { Reloc *r; + Sym *rs; Prog p; int32 i, off, siz, fl; vlong o; @@ -176,18 +177,35 @@ relocsym(Sym *s) switch(r->type) { default: o = 0; - if(archreloc(r, s, &o) < 0) + if(isobj || archreloc(r, s, &o) < 0) diag("unknown reloc %d", r->type); break; case D_ADDR: o = symaddr(r->sym) + r->add; + if(isobj && r->sym->type != SCONST) { + if(thechar == '6') + o = 0; + else { + // set up addend for eventual relocation via outer symbol + rs = r->sym; + while(rs->outer != nil) + rs = rs->outer; + o -= symaddr(rs); + } + } break; case D_PCREL: - // r->sym can be null when CALL $(constant) is transformed from absoulte PC to relative PC call. + // r->sym can be null when CALL $(constant) is transformed from absolute PC to relative PC call. o = 0; if(r->sym) o += symaddr(r->sym); o += r->add - (s->value + r->off + r->siz); + if(isobj && r->sym->type != SCONST) { + if(thechar == '6') + o = 0; + else + o = r->add - r->siz; + } break; case D_SIZE: o = r->sym->size + r->add; -- cgit v1.3-5-g9baa