diff options
Diffstat (limited to 'src/cmd/ld/symtab.c')
-rw-r--r-- | src/cmd/ld/symtab.c | 69 |
1 files changed, 62 insertions, 7 deletions
diff --git a/src/cmd/ld/symtab.c b/src/cmd/ld/symtab.c index 89a594872..7c8ba642f 100644 --- a/src/cmd/ld/symtab.c +++ b/src/cmd/ld/symtab.c @@ -121,18 +121,53 @@ putelfsym(Sym *x, char *s, int t, vlong addr, vlong size, int ver, Sym *go) // One pass for each binding: STB_LOCAL, STB_GLOBAL, // maybe one day STB_WEAK. - bind = (ver || (x->type & SHIDDEN)) ? STB_LOCAL : STB_GLOBAL; + bind = STB_GLOBAL; + if(ver || (x->type & SHIDDEN)) + bind = STB_LOCAL; + + // In external linking mode, we have to invoke gcc with -rdynamic + // to get the exported symbols put into the dynamic symbol table. + // To avoid filling the dynamic table with lots of unnecessary symbols, + // mark all Go symbols local (not global) in the final executable. + if(linkmode == LinkExternal && !(x->cgoexport&CgoExportStatic)) + bind = STB_LOCAL; + if(bind != elfbind) return; off = putelfstr(s); - if(isobj) + if(linkmode == LinkExternal) addr -= xo->sect->vaddr; putelfsyment(off, addr, size, (bind<<4)|(type&0xf), xo->sect->elfsect->shnum, (x->type & SHIDDEN) ? 2 : 0); x->elfsym = numelfsym++; } void +putelfsectionsym(Sym* s, int shndx) +{ + putelfsyment(0, 0, 0, (STB_LOCAL<<4)|STT_SECTION, shndx, 0); + s->elfsym = numelfsym++; +} + +void +putelfsymshndx(vlong sympos, int shndx) +{ + vlong here; + + here = cpos(); + switch(thechar) { + case '6': + cseek(sympos+6); + break; + default: + cseek(sympos+14); + break; + } + WPUT(shndx); + cseek(here); +} + +void asmelfsym(void) { Sym *s; @@ -140,8 +175,30 @@ asmelfsym(void) // the first symbol entry is reserved putelfsyment(0, 0, 0, (STB_LOCAL<<4)|STT_NOTYPE, 0, 0); + dwarfaddelfsectionsyms(); + elfbind = STB_LOCAL; genasmsym(putelfsym); + + if(linkmode == LinkExternal && HEADTYPE != Hopenbsd) { + s = lookup("runtime.m", 0); + if(s->sect == nil) { + cursym = nil; + diag("missing section for %s", s->name); + errorexit(); + } + putelfsyment(putelfstr(s->name), 0, PtrSize, (STB_LOCAL<<4)|STT_TLS, s->sect->elfsect->shnum, 0); + s->elfsym = numelfsym++; + + s = lookup("runtime.g", 0); + if(s->sect == nil) { + cursym = nil; + diag("missing section for %s", s->name); + errorexit(); + } + putelfsyment(putelfstr(s->name), PtrSize, PtrSize, (STB_LOCAL<<4)|STT_TLS, s->sect->elfsect->shnum, 0); + s->elfsym = numelfsym++; + } elfbind = STB_GLOBAL; elfglobalsymndx = numelfsym; @@ -317,7 +374,7 @@ putsymb(Sym *s, char *name, int t, vlong v, vlong size, int ver, Sym *typ) // type byte if('A' <= t && t <= 'Z') - c = t - 'A'; + c = t - 'A' + (ver ? 26 : 0); else if('a' <= t && t <= 'z') c = t - 'a' + 26; else { @@ -424,10 +481,8 @@ symtab(void) xdefine("datarelro", SDATARELRO, 0); xdefine("edatarelro", SDATARELRO, 0); } - xdefine("gcdata", SGCDATA, 0); - xdefine("egcdata", SGCDATA, 0); - xdefine("gcbss", SGCBSS, 0); - xdefine("egcbss", SGCBSS, 0); + xdefine("egcdata", STYPE, 0); + xdefine("egcbss", STYPE, 0); xdefine("noptrdata", SNOPTRDATA, 0); xdefine("enoptrdata", SNOPTRDATA, 0); xdefine("data", SDATA, 0); |