return;
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)
break;
if(iself) {
break;
case D_PCREL:
- if(r->siz == 4)
- VPUT(R_X86_64_PC32 | (uint64)elfsym<<32);
- else
+ if(r->siz == 4) {
+ if(r->xsym->type == SDYNIMPORT)
+ VPUT(R_X86_64_GOTPCREL | (uint64)elfsym<<32);
+ else
+ VPUT(R_X86_64_PC32 | (uint64)elfsym<<32);
+ } else
return -1;
break;
if(r->type >= 256)
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);
-
if(r->sym != S && r->sym->type != STLSBSS && !r->sym->reachable)
diag("unreachable sym in relocation: %s %s", s->name, r->sym->name);
r->xadd += symaddr(rs) - symaddr(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);
r->xsym = rs;
rs = rs->outer;
}
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);
r->xsym = rs;
asmelfsym(void)
{
LSym *s;
+ char *name;
// the first symbol entry is reserved
putelfsyment(0, 0, 0, (STB_LOCAL<<4)|STT_NOTYPE, 0, 0);
genasmsym(putelfsym);
for(s=ctxt->allsym; s!=S; s=s->allsym) {
- if(s->type != SHOSTOBJ)
+ if(s->type != SHOSTOBJ && s->type != SDYNIMPORT)
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++;
}
}