void adddynsym(Link *ctxt, LSym *s) { LSym *d; int t; char *name; if(s->dynid >= 0) return; if(iself) { s->dynid = nelfsym++; d = linklookup(ctxt, ".dynsym", 0); name = s->extname; adduint32(ctxt, d, addstring(linklookup(ctxt, ".dynstr", 0), name)); /* type */ t = STB_GLOBAL << 4; if(s->cgoexport && (s->type&SMASK) == STEXT) t |= STT_FUNC; else t |= STT_OBJECT; adduint8(ctxt, d, t); /* reserved */ adduint8(ctxt, d, 0); /* section where symbol is defined */ if(s->type == SDYNIMPORT) adduint16(ctxt, d, SHN_UNDEF); else adduint16(ctxt, d, 1); /* value */ if(s->type == SDYNIMPORT) adduint64(ctxt, d, 0); else addaddr(ctxt, d, s); /* size of object */ adduint64(ctxt, d, s->size); if(!(s->cgoexport & CgoExportDynamic) && s->dynimplib && needlib(s->dynimplib)) { elfwritedynent(linklookup(ctxt, ".dynamic", 0), DT_NEEDED, addstring(linklookup(ctxt, ".dynstr", 0), s->dynimplib)); } } else if(HEADTYPE == Hdarwin) { diag("adddynsym: missed symbol %s (%s)", s->name, s->extname); } else if(HEADTYPE == Hwindows) { // already taken care of } else { diag("adddynsym: unsupported binary format"); } }
void adddynlib(char *lib) { Sym *s; if(!needlib(lib)) return; if(iself) { s = lookup(".dynstr", 0); if(s->size == 0) addstring(s, ""); elfwritedynent(lookup(".dynamic", 0), DT_NEEDED, addstring(s, lib)); } else { diag("adddynlib: unsupported binary format"); } }
void adddynlib(char *lib) { LSym *s; if(!needlib(lib)) return; if(iself) { s = linklookup(ctxt, ".dynstr", 0); if(s->size == 0) addstring(s, ""); elfwritedynent(linklookup(ctxt, ".dynamic", 0), DT_NEEDED, addstring(s, lib)); } else if(HEADTYPE == Hdarwin) { machoadddynlib(lib); } else { diag("adddynlib: unsupported binary format"); } }
void adddynsym(Sym *s) { Sym *d, *str; int t; char *name; vlong off; if(s->dynid >= 0) return; if(s->dynimpname == nil) diag("adddynsym: no dynamic name for %s", s->name); if(iself) { s->dynid = nelfsym++; d = lookup(".dynsym", 0); name = s->dynimpname; if(name == nil) name = s->name; adduint32(d, addstring(lookup(".dynstr", 0), name)); /* type */ t = STB_GLOBAL << 4; if(s->dynexport && (s->type&SMASK) == STEXT) t |= STT_FUNC; else t |= STT_OBJECT; adduint8(d, t); /* reserved */ adduint8(d, 0); /* section where symbol is defined */ if(!s->dynexport && s->dynimpname != nil) adduint16(d, SHN_UNDEF); else { switch(s->type) { default: case STEXT: t = 11; break; case SRODATA: t = 12; break; case SDATA: t = 13; break; case SBSS: t = 14; break; } adduint16(d, t); } /* value */ if(s->type == SDYNIMPORT) adduint64(d, 0); else addaddr(d, s); /* size of object */ adduint64(d, s->size); if(!s->dynexport && s->dynimplib && needlib(s->dynimplib)) { elfwritedynent(lookup(".dynamic", 0), DT_NEEDED, addstring(lookup(".dynstr", 0), s->dynimplib)); } } else if(HEADTYPE == Hdarwin) { // Mach-o symbol nlist64 d = lookup(".dynsym", 0); name = s->dynimpname; if(name == nil) name = s->name; if(d->size == 0 && ndynexp > 0) { // pre-allocate for dynexps symgrow(d, ndynexp*16); } if(s->dynid <= -100) { // pre-allocated, see cmd/ld/go.c:^sortdynexp() s->dynid = -s->dynid-100; off = s->dynid*16; } else { off = d->size; s->dynid = off/16; } // darwin still puts _ prefixes on all C symbols str = lookup(".dynstr", 0); setuint32(d, off, str->size); off += 4; adduint8(str, '_'); addstring(str, name); if(s->type == SDYNIMPORT) { setuint8(d, off, 0x01); // type - N_EXT - external symbol off++; setuint8(d, off, 0); // section off++; } else { setuint8(d, off, 0x0f); off++; switch(s->type) { default: case STEXT: setuint8(d, off, 1); break; case SDATA: setuint8(d, off, 2); break; case SBSS: setuint8(d, off, 4); break; } off++; } setuint16(d, off, 0); // desc off += 2; if(s->type == SDYNIMPORT) setuint64(d, off, 0); // value else setaddr(d, off, s); off += 8; } else if(HEADTYPE != Hwindows) { diag("adddynsym: unsupported binary format"); } }
void adddynsym(Sym *s) { Sym *d, *str; int t; char *name; if(s->dynid >= 0) return; if(s->dynimpname == nil) diag("adddynsym: no dynamic name for %s", s->name); if(iself) { s->dynid = nelfsym++; d = lookup(".dynsym", 0); name = s->dynimpname; if(name == nil) name = s->name; adduint32(d, addstring(lookup(".dynstr", 0), name)); /* type */ t = STB_GLOBAL << 4; if(s->dynexport && s->type == STEXT) t |= STT_FUNC; else t |= STT_OBJECT; adduint8(d, t); /* reserved */ adduint8(d, 0); /* section where symbol is defined */ if(!s->dynexport && s->dynimpname != nil) adduint16(d, SHN_UNDEF); else { switch(s->type) { default: case STEXT: t = 11; break; case SRODATA: t = 12; break; case SDATA: t = 13; break; case SBSS: t = 14; break; } adduint16(d, t); } /* value */ if(s->type == SDYNIMPORT) adduint64(d, 0); else addaddr(d, s); /* size of object */ adduint64(d, 0); if(!s->dynexport && s->dynimplib && needlib(s->dynimplib)) { elfwritedynent(lookup(".dynamic", 0), DT_NEEDED, addstring(lookup(".dynstr", 0), s->dynimplib)); } } else if(HEADTYPE == Hdarwin) { // Mach-o symbol nlist64 d = lookup(".dynsym", 0); name = s->dynimpname; if(name == nil) name = s->name; s->dynid = d->size/16; // darwin still puts _ prefixes on all C symbols str = lookup(".dynstr", 0); adduint32(d, str->size); adduint8(str, '_'); addstring(str, name); if(s->type == SDYNIMPORT) { adduint8(d, 0x01); // type - N_EXT - external symbol adduint8(d, 0); // section } else { adduint8(d, 0x0f); switch(s->type) { default: case STEXT: adduint8(d, 1); break; case SDATA: adduint8(d, 2); break; case SBSS: adduint8(d, 4); break; } } adduint16(d, 0); // desc if(s->type == SDYNIMPORT) adduint64(d, 0); // value else addaddr(d, s); } else if(HEADTYPE != Hwindows) { diag("adddynsym: unsupported binary format"); } }