Commit 4687b541 authored by Shenghou Ma's avatar Shenghou Ma

cmd/ld, cmd/6l: part 2 of solaris/amd64 linker changes.

Second part of the solaris/amd64 linker changes: relocation and symbol table.

LGTM=iant
R=golang-codereviews, iant
CC=golang-codereviews
https://golang.org/cl/61330043
parent 13a5958d
...@@ -207,6 +207,15 @@ adddynrel(LSym *s, Reloc *r) ...@@ -207,6 +207,15 @@ adddynrel(LSym *s, Reloc *r)
return; return;
case D_ADDR: case D_ADDR:
if(s->type == STEXT && iself) {
// The code is asking for the address of an external
// function. We provide it with the address of the
// correspondent GOT symbol.
addgotsym(targ);
r->sym = linklookup(ctxt, ".got", 0);
r->add += targ->got;
return;
}
if(s->type != SDATA) if(s->type != SDATA)
break; break;
if(iself) { if(iself) {
...@@ -273,9 +282,12 @@ elfreloc1(Reloc *r, vlong sectoff) ...@@ -273,9 +282,12 @@ elfreloc1(Reloc *r, vlong sectoff)
break; break;
case D_PCREL: case D_PCREL:
if(r->siz == 4) if(r->siz == 4) {
VPUT(R_X86_64_PC32 | (uint64)elfsym<<32); if(r->xsym->type == SDYNIMPORT)
else VPUT(R_X86_64_GOTPCREL | (uint64)elfsym<<32);
else
VPUT(R_X86_64_PC32 | (uint64)elfsym<<32);
} else
return -1; return -1;
break; break;
......
...@@ -154,9 +154,9 @@ relocsym(LSym *s) ...@@ -154,9 +154,9 @@ relocsym(LSym *s)
if(r->type >= 256) if(r->type >= 256)
continue; continue;
if(r->sym != S && r->sym->type == SDYNIMPORT) // Solaris needs the ability to reference dynimport symbols.
if(HEADTYPE != Hsolaris && r->sym != S && r->sym->type == SDYNIMPORT)
diag("unhandled relocation for %s (type %d rtype %d)", r->sym->name, r->sym->type, r->type); diag("unhandled relocation for %s (type %d rtype %d)", r->sym->name, r->sym->type, r->type);
if(r->sym != S && r->sym->type != STLSBSS && !r->sym->reachable) if(r->sym != S && r->sym->type != STLSBSS && !r->sym->reachable)
diag("unreachable sym in relocation: %s %s", s->name, r->sym->name); diag("unreachable sym in relocation: %s %s", s->name, r->sym->name);
...@@ -194,7 +194,7 @@ relocsym(LSym *s) ...@@ -194,7 +194,7 @@ relocsym(LSym *s)
r->xadd += symaddr(rs) - symaddr(rs->outer); r->xadd += symaddr(rs) - symaddr(rs->outer);
rs = rs->outer; rs = rs->outer;
} }
if(rs->type != SHOSTOBJ && rs->sect == nil) if(rs->type != SHOSTOBJ && rs->type != SDYNIMPORT && rs->sect == nil)
diag("missing section for %s", rs->name); diag("missing section for %s", rs->name);
r->xsym = rs; r->xsym = rs;
...@@ -225,7 +225,7 @@ relocsym(LSym *s) ...@@ -225,7 +225,7 @@ relocsym(LSym *s)
rs = rs->outer; rs = rs->outer;
} }
r->xadd -= r->siz; // relative to address after the relocated chunk r->xadd -= r->siz; // relative to address after the relocated chunk
if(rs->type != SHOSTOBJ && rs->sect == nil) if(rs->type != SHOSTOBJ && rs->type != SDYNIMPORT && rs->sect == nil)
diag("missing section for %s", rs->name); diag("missing section for %s", rs->name);
r->xsym = rs; r->xsym = rs;
......
...@@ -171,6 +171,7 @@ void ...@@ -171,6 +171,7 @@ void
asmelfsym(void) asmelfsym(void)
{ {
LSym *s; LSym *s;
char *name;
// the first symbol entry is reserved // the first symbol entry is reserved
putelfsyment(0, 0, 0, (STB_LOCAL<<4)|STT_NOTYPE, 0, 0); putelfsyment(0, 0, 0, (STB_LOCAL<<4)|STT_NOTYPE, 0, 0);
...@@ -196,9 +197,13 @@ asmelfsym(void) ...@@ -196,9 +197,13 @@ asmelfsym(void)
genasmsym(putelfsym); genasmsym(putelfsym);
for(s=ctxt->allsym; s!=S; s=s->allsym) { for(s=ctxt->allsym; s!=S; s=s->allsym) {
if(s->type != SHOSTOBJ) if(s->type != SHOSTOBJ && s->type != SDYNIMPORT)
continue; continue;
putelfsyment(putelfstr(s->name), 0, 0, (STB_GLOBAL<<4)|STT_NOTYPE, 0, 0); if(s->type == SDYNIMPORT)
name = s->extname;
else
name = s->name;
putelfsyment(putelfstr(name), 0, 0, (STB_GLOBAL<<4)|STT_NOTYPE, 0, 0);
s->elfsym = numelfsym++; s->elfsym = numelfsym++;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment