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) { 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 elfdynhash(void) { LSym *s, *sy, *dynstr; int i, j, nbucket, b, nfile; uint32 hc, *chain, *buckets; int nsym; char *name; Elfaux **need; Elflib *needlib; Elflib *l; Elfaux *x; if(!iself) return; nsym = nelfsym; s = linklookup(ctxt, ".hash", 0); s->type = SELFROSECT; s->reachable = 1; i = nsym; nbucket = 1; while(i > 0) { ++nbucket; i >>= 1; } needlib = nil; need = malloc(nsym * sizeof need[0]); chain = malloc(nsym * sizeof chain[0]); buckets = malloc(nbucket * sizeof buckets[0]); if(need == nil || chain == nil || buckets == nil) { ctxt->cursym = nil; diag("out of memory"); errorexit(); } memset(need, 0, nsym * sizeof need[0]); memset(chain, 0, nsym * sizeof chain[0]); memset(buckets, 0, nbucket * sizeof buckets[0]); for(sy=ctxt->allsym; sy!=S; sy=sy->allsym) { if (sy->dynid <= 0) continue; if(sy->dynimpvers) need[sy->dynid] = addelflib(&needlib, sy->dynimplib, sy->dynimpvers); name = sy->extname; hc = elfhash((uchar*)name); b = hc % nbucket; chain[sy->dynid] = buckets[b]; buckets[b] = sy->dynid; } adduint32(ctxt, s, nbucket); adduint32(ctxt, s, nsym); for(i = 0; i<nbucket; i++) adduint32(ctxt, s, buckets[i]); for(i = 0; i<nsym; i++) adduint32(ctxt, s, chain[i]); free(chain); free(buckets); // version symbols dynstr = linklookup(ctxt, ".dynstr", 0); s = linklookup(ctxt, ".gnu.version_r", 0); i = 2; nfile = 0; for(l=needlib; l; l=l->next) { nfile++; // header adduint16(ctxt, s, 1); // table version j = 0; for(x=l->aux; x; x=x->next) j++; adduint16(ctxt, s, j); // aux count adduint32(ctxt, s, addstring(dynstr, l->file)); // file string offset adduint32(ctxt, s, 16); // offset from header to first aux if(l->next) adduint32(ctxt, s, 16+j*16); // offset from this header to next else adduint32(ctxt, s, 0); for(x=l->aux; x; x=x->next) { x->num = i++; // aux struct adduint32(ctxt, s, elfhash((uchar*)x->vers)); // hash adduint16(ctxt, s, 0); // flags adduint16(ctxt, s, x->num); // other - index we refer to this by adduint32(ctxt, s, addstring(dynstr, x->vers)); // version string offset if(x->next) adduint32(ctxt, s, 16); // offset from this aux to next else adduint32(ctxt, s, 0); } } // version references s = linklookup(ctxt, ".gnu.version", 0); for(i=0; i<nsym; i++) { if(i == 0) adduint16(ctxt, s, 0); // first entry - no symbol else if(need[i] == nil) adduint16(ctxt, s, 1); // global else adduint16(ctxt, s, need[i]->num); } free(need); s = linklookup(ctxt, ".dynamic", 0); elfverneed = nfile; if(elfverneed) { elfwritedynentsym(s, DT_VERNEED, linklookup(ctxt, ".gnu.version_r", 0)); elfwritedynent(s, DT_VERNEEDNUM, nfile); elfwritedynentsym(s, DT_VERSYM, linklookup(ctxt, ".gnu.version", 0)); } if(thechar == '6') { sy = linklookup(ctxt, ".rela.plt", 0); if(sy->size > 0) { elfwritedynent(s, DT_PLTREL, DT_RELA); elfwritedynentsymsize(s, DT_PLTRELSZ, sy); elfwritedynentsym(s, DT_JMPREL, sy); } } else { sy = linklookup(ctxt, ".rel.plt", 0); if(sy->size > 0) { elfwritedynent(s, DT_PLTREL, DT_REL); elfwritedynentsymsize(s, DT_PLTRELSZ, sy); elfwritedynentsym(s, DT_JMPREL, sy); } } elfwritedynent(s, DT_NULL, 0); }
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 = 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, ".rodata"); addstring(shstrtab, ".gosymtab"); addstring(shstrtab, ".gopclntab"); if(!debug['s']) { elfstr[ElfStrSymtab] = addstring(shstrtab, ".symtab"); elfstr[ElfStrStrtab] = addstring(shstrtab, ".strtab"); } 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; // TODO: rodata /* dynamic symbol table - first entry all zeros */ s = lookup(".dynsym", 0); s->type = SELFDATA; s->reachable = 1; s->value += ELF32SYMSIZE; /* dynamic string table */ s = lookup(".dynstr", 0); s->type = SELFDATA; s->reachable = 1; 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 = 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); } }