void doelf(void) { Sym *s, *shstrtab, *dynstr; if(!iself) return; /* predefine strings we need for section headers */ shstrtab = lookup(".shstrtab", 0); shstrtab->type = SELFROSECT; shstrtab->reachable = 1; addstring(shstrtab, ""); addstring(shstrtab, ".text"); addstring(shstrtab, ".noptrdata"); addstring(shstrtab, ".data"); addstring(shstrtab, ".bss"); addstring(shstrtab, ".noptrbss"); if(HEADTYPE == Hnetbsd) addstring(shstrtab, ".note.netbsd.ident"); if(HEADTYPE == Hopenbsd) addstring(shstrtab, ".note.openbsd.ident"); if(buildinfolen > 0) addstring(shstrtab, ".note.gnu.build-id"); addstring(shstrtab, ".elfdata"); addstring(shstrtab, ".rodata"); addstring(shstrtab, ".typelink"); if(flag_shared) addstring(shstrtab, ".data.rel.ro"); addstring(shstrtab, ".gcdata"); addstring(shstrtab, ".gcbss"); addstring(shstrtab, ".gosymtab"); addstring(shstrtab, ".gopclntab"); if(isobj) { debug['s'] = 0; debug['d'] = 1; if(thechar == '6') { addstring(shstrtab, ".rela.text"); addstring(shstrtab, ".rela.rodata"); addstring(shstrtab, ".rela.typelink"); addstring(shstrtab, ".rela.gcdata"); addstring(shstrtab, ".rela.gcbss"); addstring(shstrtab, ".rela.gosymtab"); addstring(shstrtab, ".rela.gopclntab"); addstring(shstrtab, ".rela.noptrdata"); addstring(shstrtab, ".rela.data"); } else { addstring(shstrtab, ".rel.text"); addstring(shstrtab, ".rel.rodata"); addstring(shstrtab, ".rel.typelink"); addstring(shstrtab, ".rel.gcdata"); addstring(shstrtab, ".rel.gcbss"); addstring(shstrtab, ".rel.gosymtab"); addstring(shstrtab, ".rel.gopclntab"); addstring(shstrtab, ".rel.noptrdata"); addstring(shstrtab, ".rel.data"); } } if(!debug['s']) { addstring(shstrtab, ".symtab"); addstring(shstrtab, ".strtab"); dwarfaddshstrings(shstrtab); } addstring(shstrtab, ".shstrtab"); if(!debug['d']) { /* -d suppresses dynamic loader format */ addstring(shstrtab, ".interp"); addstring(shstrtab, ".hash"); addstring(shstrtab, ".got"); addstring(shstrtab, ".got.plt"); addstring(shstrtab, ".dynamic"); addstring(shstrtab, ".dynsym"); addstring(shstrtab, ".dynstr"); if(thechar == '6') { addstring(shstrtab, ".rela"); addstring(shstrtab, ".rela.plt"); } else { addstring(shstrtab, ".rel"); addstring(shstrtab, ".rel.plt"); } addstring(shstrtab, ".plt"); addstring(shstrtab, ".gnu.version"); addstring(shstrtab, ".gnu.version_r"); /* dynamic symbol table - first entry all zeros */ s = lookup(".dynsym", 0); s->type = SELFROSECT; s->reachable = 1; if(thechar == '6') s->size += ELF64SYMSIZE; else s->size += ELF32SYMSIZE; /* dynamic string table */ s = lookup(".dynstr", 0); s->type = SELFROSECT; s->reachable = 1; if(s->size == 0) addstring(s, ""); dynstr = s; /* relocation table */ if(thechar == '6') s = lookup(".rela", 0); else s = lookup(".rel", 0); s->reachable = 1; s->type = SELFROSECT; /* global offset table */ s = lookup(".got", 0); s->reachable = 1; s->type = SELFSECT; // writable /* hash */ s = lookup(".hash", 0); s->reachable = 1; s->type = SELFROSECT; s = lookup(".got.plt", 0); s->reachable = 1; s->type = SELFSECT; // writable s = lookup(".plt", 0); s->reachable = 1; s->type = SELFROSECT; elfsetupplt(); if(thechar == '6') s = lookup(".rela.plt", 0); else s = lookup(".rel.plt", 0); s->reachable = 1; s->type = SELFROSECT; s = lookup(".gnu.version", 0); s->reachable = 1; s->type = SELFROSECT; s = lookup(".gnu.version_r", 0); s->reachable = 1; s->type = SELFROSECT; /* define dynamic elf table */ s = lookup(".dynamic", 0); s->reachable = 1; s->type = SELFSECT; // writable /* * .dynamic table */ elfwritedynentsym(s, DT_HASH, lookup(".hash", 0)); elfwritedynentsym(s, DT_SYMTAB, lookup(".dynsym", 0)); if(thechar == '6') elfwritedynent(s, DT_SYMENT, ELF64SYMSIZE); else elfwritedynent(s, DT_SYMENT, ELF32SYMSIZE); elfwritedynentsym(s, DT_STRTAB, lookup(".dynstr", 0)); elfwritedynentsymsize(s, DT_STRSZ, lookup(".dynstr", 0)); if(thechar == '6') { elfwritedynentsym(s, DT_RELA, lookup(".rela", 0)); elfwritedynentsymsize(s, DT_RELASZ, lookup(".rela", 0)); elfwritedynent(s, DT_RELAENT, ELF64RELASIZE); } else { elfwritedynentsym(s, DT_REL, lookup(".rel", 0)); elfwritedynentsymsize(s, DT_RELSZ, lookup(".rel", 0)); elfwritedynent(s, DT_RELENT, ELF32RELSIZE); } if(rpath) elfwritedynent(s, DT_RUNPATH, addstring(dynstr, rpath)); elfwritedynentsym(s, DT_PLTGOT, lookup(".got.plt", 0)); if(thechar == '6') { elfwritedynent(s, DT_PLTREL, DT_RELA); elfwritedynentsymsize(s, DT_PLTRELSZ, lookup(".rela.plt", 0)); elfwritedynentsym(s, DT_JMPREL, lookup(".rela.plt", 0)); } else { elfwritedynent(s, DT_PLTREL, DT_REL); elfwritedynentsymsize(s, DT_PLTRELSZ, lookup(".rel.plt", 0)); elfwritedynentsym(s, DT_JMPREL, lookup(".rel.plt", 0)); } elfwritedynent(s, DT_DEBUG, 0); if(flag_shared) { Sym *init_sym = lookup(LIBINITENTRY, 0); if(init_sym->type != STEXT) diag("entry not text: %s", init_sym->name); elfwritedynentsym(s, DT_INIT, init_sym); } // Do not write DT_NULL. elfdynhash will finish it. } }
void doelf(void) { LSym *s, *shstrtab, *dynstr; if(!iself) return; /* predefine strings we need for section headers */ shstrtab = linklookup(ctxt, ".shstrtab", 0); shstrtab->type = SELFROSECT; shstrtab->reachable = 1; addstring(shstrtab, ""); addstring(shstrtab, ".text"); addstring(shstrtab, ".noptrdata"); addstring(shstrtab, ".data"); addstring(shstrtab, ".bss"); addstring(shstrtab, ".noptrbss"); // generate .tbss section (except for OpenBSD where it's not supported) // for dynamic internal linker or external linking, so that various // binutils could correctly calculate PT_TLS size. // see http://golang.org/issue/5200. if(HEADTYPE != Hopenbsd) if(!debug['d'] || linkmode == LinkExternal) addstring(shstrtab, ".tbss"); if(HEADTYPE == Hnetbsd) addstring(shstrtab, ".note.netbsd.ident"); if(HEADTYPE == Hopenbsd) addstring(shstrtab, ".note.openbsd.ident"); if(buildinfolen > 0) addstring(shstrtab, ".note.gnu.build-id"); addstring(shstrtab, ".elfdata"); addstring(shstrtab, ".rodata"); addstring(shstrtab, ".typelink"); addstring(shstrtab, ".gosymtab"); addstring(shstrtab, ".gopclntab"); if(linkmode == LinkExternal) { debug_s = debug['s']; debug['s'] = 0; debug['d'] = 1; if(thechar == '6') { addstring(shstrtab, ".rela.text"); addstring(shstrtab, ".rela.rodata"); addstring(shstrtab, ".rela.typelink"); addstring(shstrtab, ".rela.gosymtab"); addstring(shstrtab, ".rela.gopclntab"); addstring(shstrtab, ".rela.noptrdata"); addstring(shstrtab, ".rela.data"); } else { addstring(shstrtab, ".rel.text"); addstring(shstrtab, ".rel.rodata"); addstring(shstrtab, ".rel.typelink"); addstring(shstrtab, ".rel.gosymtab"); addstring(shstrtab, ".rel.gopclntab"); addstring(shstrtab, ".rel.noptrdata"); addstring(shstrtab, ".rel.data"); } // add a .note.GNU-stack section to mark the stack as non-executable addstring(shstrtab, ".note.GNU-stack"); } if(flag_shared) { addstring(shstrtab, ".init_array"); if(thechar == '6') addstring(shstrtab, ".rela.init_array"); else addstring(shstrtab, ".rel.init_array"); } if(!debug['s']) { addstring(shstrtab, ".symtab"); addstring(shstrtab, ".strtab"); dwarfaddshstrings(shstrtab); } addstring(shstrtab, ".shstrtab"); if(!debug['d']) { /* -d suppresses dynamic loader format */ addstring(shstrtab, ".interp"); addstring(shstrtab, ".hash"); addstring(shstrtab, ".got"); addstring(shstrtab, ".got.plt"); addstring(shstrtab, ".dynamic"); addstring(shstrtab, ".dynsym"); addstring(shstrtab, ".dynstr"); if(thechar == '6') { addstring(shstrtab, ".rela"); addstring(shstrtab, ".rela.plt"); } else { addstring(shstrtab, ".rel"); addstring(shstrtab, ".rel.plt"); } addstring(shstrtab, ".plt"); addstring(shstrtab, ".gnu.version"); addstring(shstrtab, ".gnu.version_r"); /* dynamic symbol table - first entry all zeros */ s = linklookup(ctxt, ".dynsym", 0); s->type = SELFROSECT; s->reachable = 1; if(thechar == '6') s->size += ELF64SYMSIZE; else s->size += ELF32SYMSIZE; /* dynamic string table */ s = linklookup(ctxt, ".dynstr", 0); s->type = SELFROSECT; s->reachable = 1; if(s->size == 0) addstring(s, ""); dynstr = s; /* relocation table */ if(thechar == '6') s = linklookup(ctxt, ".rela", 0); else s = linklookup(ctxt, ".rel", 0); s->reachable = 1; s->type = SELFROSECT; /* global offset table */ s = linklookup(ctxt, ".got", 0); s->reachable = 1; s->type = SELFSECT; // writable /* hash */ s = linklookup(ctxt, ".hash", 0); s->reachable = 1; s->type = SELFROSECT; s = linklookup(ctxt, ".got.plt", 0); s->reachable = 1; s->type = SELFSECT; // writable s = linklookup(ctxt, ".plt", 0); s->reachable = 1; s->type = SELFRXSECT; elfsetupplt(); if(thechar == '6') s = linklookup(ctxt, ".rela.plt", 0); else s = linklookup(ctxt, ".rel.plt", 0); s->reachable = 1; s->type = SELFROSECT; s = linklookup(ctxt, ".gnu.version", 0); s->reachable = 1; s->type = SELFROSECT; s = linklookup(ctxt, ".gnu.version_r", 0); s->reachable = 1; s->type = SELFROSECT; /* define dynamic elf table */ s = linklookup(ctxt, ".dynamic", 0); s->reachable = 1; s->type = SELFSECT; // writable /* * .dynamic table */ elfwritedynentsym(s, DT_HASH, linklookup(ctxt, ".hash", 0)); elfwritedynentsym(s, DT_SYMTAB, linklookup(ctxt, ".dynsym", 0)); if(thechar == '6') elfwritedynent(s, DT_SYMENT, ELF64SYMSIZE); else elfwritedynent(s, DT_SYMENT, ELF32SYMSIZE); elfwritedynentsym(s, DT_STRTAB, linklookup(ctxt, ".dynstr", 0)); elfwritedynentsymsize(s, DT_STRSZ, linklookup(ctxt, ".dynstr", 0)); if(thechar == '6') { elfwritedynentsym(s, DT_RELA, linklookup(ctxt, ".rela", 0)); elfwritedynentsymsize(s, DT_RELASZ, linklookup(ctxt, ".rela", 0)); elfwritedynent(s, DT_RELAENT, ELF64RELASIZE); } else { elfwritedynentsym(s, DT_REL, linklookup(ctxt, ".rel", 0)); elfwritedynentsymsize(s, DT_RELSZ, linklookup(ctxt, ".rel", 0)); elfwritedynent(s, DT_RELENT, ELF32RELSIZE); } if(rpath) elfwritedynent(s, DT_RUNPATH, addstring(dynstr, rpath)); elfwritedynentsym(s, DT_PLTGOT, linklookup(ctxt, ".got.plt", 0)); // Solaris dynamic linker can't handle an empty .rela.plt if // DT_JMPREL is emitted so we have to defer generation of DT_PLTREL, // DT_PLTRELSZ, and DT_JMPREL dynamic entries until after we know the // size of .rel(a).plt section. elfwritedynent(s, DT_DEBUG, 0); // Do not write DT_NULL. elfdynhash will finish it. } }
void doelf(void) { Sym *s, *shstrtab, *dynstr; if(!iself) return; /* predefine strings we need for section headers */ shstrtab = lookup(".shstrtab", 0); shstrtab->type = SELFROSECT; shstrtab->reachable = 1; elfstr[ElfStrEmpty] = addstring(shstrtab, ""); elfstr[ElfStrText] = addstring(shstrtab, ".text"); elfstr[ElfStrNoPtrData] = addstring(shstrtab, ".noptrdata"); elfstr[ElfStrData] = addstring(shstrtab, ".data"); elfstr[ElfStrBss] = addstring(shstrtab, ".bss"); elfstr[ElfStrNoPtrBss] = addstring(shstrtab, ".noptrbss"); if(HEADTYPE == Hnetbsd) elfstr[ElfStrNoteNetbsdIdent] = addstring(shstrtab, ".note.netbsd.ident"); if(HEADTYPE == Hopenbsd) elfstr[ElfStrNoteOpenbsdIdent] = addstring(shstrtab, ".note.openbsd.ident"); if(buildinfolen > 0) elfstr[ElfStrNoteBuildInfo] = addstring(shstrtab, ".note.gnu.build-id"); addstring(shstrtab, ".elfdata"); addstring(shstrtab, ".rodata"); addstring(shstrtab, ".typelink"); addstring(shstrtab, ".gcdata"); addstring(shstrtab, ".gcbss"); addstring(shstrtab, ".gosymtab"); addstring(shstrtab, ".gopclntab"); if(!debug['s']) { elfstr[ElfStrSymtab] = addstring(shstrtab, ".symtab"); elfstr[ElfStrStrtab] = addstring(shstrtab, ".strtab"); dwarfaddshstrings(shstrtab); } elfstr[ElfStrShstrtab] = addstring(shstrtab, ".shstrtab"); if(!debug['d']) { /* -d suppresses dynamic loader format */ elfstr[ElfStrInterp] = addstring(shstrtab, ".interp"); elfstr[ElfStrHash] = addstring(shstrtab, ".hash"); elfstr[ElfStrGot] = addstring(shstrtab, ".got"); elfstr[ElfStrGotPlt] = addstring(shstrtab, ".got.plt"); elfstr[ElfStrDynamic] = addstring(shstrtab, ".dynamic"); elfstr[ElfStrDynsym] = addstring(shstrtab, ".dynsym"); elfstr[ElfStrDynstr] = addstring(shstrtab, ".dynstr"); elfstr[ElfStrRel] = addstring(shstrtab, ".rel"); elfstr[ElfStrRelPlt] = addstring(shstrtab, ".rel.plt"); elfstr[ElfStrPlt] = addstring(shstrtab, ".plt"); elfstr[ElfStrGnuVersion] = addstring(shstrtab, ".gnu.version"); elfstr[ElfStrGnuVersionR] = addstring(shstrtab, ".gnu.version_r"); /* dynamic symbol table - first entry all zeros */ s = lookup(".dynsym", 0); s->type = SELFROSECT; s->reachable = 1; s->size += ELF32SYMSIZE; /* dynamic string table */ s = lookup(".dynstr", 0); s->reachable = 1; s->type = SELFROSECT; if(s->size == 0) addstring(s, ""); dynstr = s; /* relocation table */ s = lookup(".rel", 0); s->reachable = 1; s->type = SELFROSECT; /* global offset table */ s = lookup(".got", 0); s->reachable = 1; s->type = SELFSECT; // writable /* hash */ s = lookup(".hash", 0); s->reachable = 1; s->type = SELFROSECT; /* got.plt */ s = lookup(".got.plt", 0); s->reachable = 1; s->type = SELFSECT; // writable s = lookup(".plt", 0); s->reachable = 1; s->type = SELFROSECT; s = lookup(".rel.plt", 0); s->reachable = 1; s->type = SELFROSECT; s = lookup(".gnu.version", 0); s->reachable = 1; s->type = SELFROSECT; s = lookup(".gnu.version_r", 0); s->reachable = 1; s->type = SELFROSECT; elfsetupplt(); /* define dynamic elf table */ s = lookup(".dynamic", 0); s->reachable = 1; s->type = SELFSECT; // writable /* * .dynamic table */ elfwritedynentsym(s, DT_HASH, lookup(".hash", 0)); elfwritedynentsym(s, DT_SYMTAB, lookup(".dynsym", 0)); elfwritedynent(s, DT_SYMENT, ELF32SYMSIZE); elfwritedynentsym(s, DT_STRTAB, lookup(".dynstr", 0)); elfwritedynentsymsize(s, DT_STRSZ, lookup(".dynstr", 0)); elfwritedynentsym(s, DT_REL, lookup(".rel", 0)); elfwritedynentsymsize(s, DT_RELSZ, lookup(".rel", 0)); elfwritedynent(s, DT_RELENT, ELF32RELSIZE); if(rpath) elfwritedynent(s, DT_RUNPATH, addstring(dynstr, rpath)); elfwritedynentsym(s, DT_PLTGOT, lookup(".got.plt", 0)); elfwritedynent(s, DT_PLTREL, DT_REL); elfwritedynentsymsize(s, DT_PLTRELSZ, lookup(".rel.plt", 0)); elfwritedynentsym(s, DT_JMPREL, lookup(".rel.plt", 0)); elfwritedynent(s, DT_DEBUG, 0); // Do not write DT_NULL. elfdynhash will finish it. } }
void doelf(void) { Sym *s, *shstrtab, *dynstr; if(!iself) return; /* predefine strings we need for section headers */ shstrtab = lookup(".shstrtab", 0); shstrtab->type = SELFDATA; shstrtab->reachable = 1; elfstr[ElfStrEmpty] = addstring(shstrtab, ""); elfstr[ElfStrText] = addstring(shstrtab, ".text"); elfstr[ElfStrData] = addstring(shstrtab, ".data"); elfstr[ElfStrBss] = addstring(shstrtab, ".bss"); addstring(shstrtab, ".elfdata"); addstring(shstrtab, ".rodata"); if(!debug['s']) { elfstr[ElfStrGosymcounts] = addstring(shstrtab, ".gosymcounts"); elfstr[ElfStrGosymtab] = addstring(shstrtab, ".gosymtab"); elfstr[ElfStrGopclntab] = addstring(shstrtab, ".gopclntab"); dwarfaddshstrings(shstrtab); } elfstr[ElfStrShstrtab] = addstring(shstrtab, ".shstrtab"); if(!debug['d']) { /* -d suppresses dynamic loader format */ elfstr[ElfStrInterp] = addstring(shstrtab, ".interp"); elfstr[ElfStrHash] = addstring(shstrtab, ".hash"); elfstr[ElfStrGot] = addstring(shstrtab, ".got"); elfstr[ElfStrGotPlt] = addstring(shstrtab, ".got.plt"); elfstr[ElfStrDynamic] = addstring(shstrtab, ".dynamic"); elfstr[ElfStrDynsym] = addstring(shstrtab, ".dynsym"); elfstr[ElfStrDynstr] = addstring(shstrtab, ".dynstr"); elfstr[ElfStrRel] = addstring(shstrtab, ".rel"); elfstr[ElfStrRelPlt] = addstring(shstrtab, ".rel.plt"); elfstr[ElfStrPlt] = addstring(shstrtab, ".plt"); /* interpreter string */ s = lookup(".interp", 0); s->reachable = 1; s->type = SELFDATA; /* dynamic symbol table - first entry all zeros */ s = lookup(".dynsym", 0); s->type = SELFDATA; s->reachable = 1; s->size += ELF32SYMSIZE; /* dynamic string table */ s = lookup(".dynstr", 0); s->reachable = 1; s->type = SELFDATA; if(s->size == 0) addstring(s, ""); dynstr = s; /* relocation table */ s = lookup(".rel", 0); s->reachable = 1; s->type = SELFDATA; /* global offset table */ s = lookup(".got", 0); s->reachable = 1; s->type = SDATA; // writable, so not SELFDATA /* hash */ s = lookup(".hash", 0); s->reachable = 1; s->type = SELFDATA; /* got.plt */ s = lookup(".got.plt", 0); s->reachable = 1; s->type = SDATA; // writable, so not SELFDATA s = lookup(".plt", 0); s->reachable = 1; s->type = SELFDATA; s = lookup(".rel.plt", 0); s->reachable = 1; s->type = SELFDATA; elfsetupplt(); /* define dynamic elf table */ s = lookup(".dynamic", 0); s->reachable = 1; s->type = SELFDATA; /* * .dynamic table */ elfwritedynentsym(s, DT_HASH, lookup(".hash", 0)); elfwritedynentsym(s, DT_SYMTAB, lookup(".dynsym", 0)); elfwritedynent(s, DT_SYMENT, ELF32SYMSIZE); elfwritedynentsym(s, DT_STRTAB, lookup(".dynstr", 0)); elfwritedynentsymsize(s, DT_STRSZ, lookup(".dynstr", 0)); elfwritedynentsym(s, DT_REL, lookup(".rel", 0)); elfwritedynentsymsize(s, DT_RELSZ, lookup(".rel", 0)); elfwritedynent(s, DT_RELENT, ELF32RELSIZE); if(rpath) elfwritedynent(s, DT_RUNPATH, addstring(dynstr, rpath)); elfwritedynentsym(s, DT_PLTGOT, lookup(".got.plt", 0)); elfwritedynent(s, DT_PLTREL, DT_REL); elfwritedynentsymsize(s, DT_PLTRELSZ, lookup(".rel.plt", 0)); elfwritedynentsym(s, DT_JMPREL, lookup(".rel.plt", 0)); elfwritedynent(s, DT_NULL, 0); } }