From: Rui Ueyama Date: Tue, 25 Sep 2018 19:26:58 +0000 (+0000) Subject: Reset input section pointers to null on each linker invocation. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4e247522ac8dc1ee1046df2c54c84e6bcc2bc1a9;p=platform%2Fupstream%2Fllvm.git Reset input section pointers to null on each linker invocation. Previously, if you invoke lld's `main` more than once in the same process, the second invocation could fail or produce a wrong result due to a stale pointer values of the previous run. Differential Revision: https://reviews.llvm.org/D52506 llvm-svn: 343009 --- diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp index 39f6c65..59c8d157 100644 --- a/lld/ELF/Arch/AArch64.cpp +++ b/lld/ELF/Arch/AArch64.cpp @@ -156,7 +156,7 @@ RelType AArch64::getDynRel(RelType Type) const { } void AArch64::writeGotPlt(uint8_t *Buf, const Symbol &) const { - write64le(Buf, InX::Plt->getVA()); + write64le(Buf, In.Plt->getVA()); } void AArch64::writePltHeader(uint8_t *Buf) const { @@ -172,8 +172,8 @@ void AArch64::writePltHeader(uint8_t *Buf) const { }; memcpy(Buf, PltData, sizeof(PltData)); - uint64_t Got = InX::GotPlt->getVA(); - uint64_t Plt = InX::Plt->getVA(); + uint64_t Got = In.GotPlt->getVA(); + uint64_t Plt = In.Plt->getVA(); relocateOne(Buf + 4, R_AARCH64_ADR_PREL_PG_HI21, getAArch64Page(Got + 16) - getAArch64Page(Plt + 4)); relocateOne(Buf + 8, R_AARCH64_LDST64_ABS_LO12_NC, Got + 16); diff --git a/lld/ELF/Arch/ARM.cpp b/lld/ELF/Arch/ARM.cpp index b12c649..1fa2acd 100644 --- a/lld/ELF/Arch/ARM.cpp +++ b/lld/ELF/Arch/ARM.cpp @@ -147,7 +147,7 @@ RelType ARM::getDynRel(RelType Type) const { } void ARM::writeGotPlt(uint8_t *Buf, const Symbol &) const { - write32le(Buf, InX::Plt->getVA()); + write32le(Buf, In.Plt->getVA()); } void ARM::writeIgotPlt(uint8_t *Buf, const Symbol &S) const { @@ -168,8 +168,8 @@ static void writePltHeaderLong(uint8_t *Buf) { 0xd4, 0xd4, 0xd4, 0xd4, // Pad to 32-byte boundary 0xd4, 0xd4, 0xd4, 0xd4}; memcpy(Buf, PltData, sizeof(PltData)); - uint64_t GotPlt = InX::GotPlt->getVA(); - uint64_t L1 = InX::Plt->getVA() + 8; + uint64_t GotPlt = In.GotPlt->getVA(); + uint64_t L1 = In.Plt->getVA() + 8; write32le(Buf + 16, GotPlt - L1 - 8); } @@ -187,7 +187,7 @@ void ARM::writePltHeader(uint8_t *Buf) const { 0xe5bef000, // ldr pc, [lr, #0x00000NNN] &(.got.plt -L1 - 4) }; - uint64_t Offset = InX::GotPlt->getVA() - InX::Plt->getVA() - 4; + uint64_t Offset = In.GotPlt->getVA() - In.Plt->getVA() - 4; if (!llvm::isUInt<27>(Offset)) { // We cannot encode the Offset, use the long form. writePltHeaderLong(Buf); diff --git a/lld/ELF/Arch/Mips.cpp b/lld/ELF/Arch/Mips.cpp index dc70401..6fb4531 100644 --- a/lld/ELF/Arch/Mips.cpp +++ b/lld/ELF/Arch/Mips.cpp @@ -185,7 +185,7 @@ template RelType MIPS::getDynRel(RelType Type) const { template void MIPS::writeGotPlt(uint8_t *Buf, const Symbol &) const { - uint64_t VA = InX::Plt->getVA(); + uint64_t VA = In.Plt->getVA(); if (isMicroMips()) VA |= 1; write32(Buf, VA); @@ -239,8 +239,8 @@ static void writeMicroRelocation16(uint8_t *Loc, uint64_t V, uint8_t BitsSize, template void MIPS::writePltHeader(uint8_t *Buf) const { const endianness E = ELFT::TargetEndianness; if (isMicroMips()) { - uint64_t GotPlt = InX::GotPlt->getVA(); - uint64_t Plt = InX::Plt->getVA(); + uint64_t GotPlt = In.GotPlt->getVA(); + uint64_t Plt = In.Plt->getVA(); // Overwrite trap instructions written by Writer::writeTrapInstr. memset(Buf, 0, PltHeaderSize); @@ -292,7 +292,7 @@ template void MIPS::writePltHeader(uint8_t *Buf) const { write32(Buf + 24, JalrInst); // jalr.hb $25 or jalr $25 write32(Buf + 28, 0x2718fffe); // subu $24, $24, 2 - uint64_t GotPlt = InX::GotPlt->getVA(); + uint64_t GotPlt = In.GotPlt->getVA(); writeValue(Buf, GotPlt + 0x8000, 16, 16); writeValue(Buf + 4, GotPlt, 16, 0); writeValue(Buf + 8, GotPlt, 16, 0); diff --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp index 7d0fe0b..25dc8a6 100644 --- a/lld/ELF/Arch/PPC64.cpp +++ b/lld/ELF/Arch/PPC64.cpp @@ -65,7 +65,7 @@ uint64_t elf::getPPC64TocBase() { // TOC starts where the first of these sections starts. We always create a // .got when we see a relocation that uses it, so for us the start is always // the .got. - uint64_t TocVA = InX::Got->getVA(); + uint64_t TocVA = In.Got->getVA(); // Per the ppc64-elf-linux ABI, The TOC base is TOC value plus 0x8000 // thus permitting a full 64 Kbytes segment. Note that the glibc startup @@ -502,7 +502,7 @@ void PPC64::writePltHeader(uint8_t *Buf) const { // The 'bcl' instruction will set the link register to the address of the // following instruction ('mflr r11'). Here we store the offset from that // instruction to the first entry in the GotPlt section. - int64_t GotPltOffset = InX::GotPlt->getVA() - (InX::Plt->getVA() + 8); + int64_t GotPltOffset = In.GotPlt->getVA() - (In.Plt->getVA() + 8); write64(Buf + 52, GotPltOffset); } diff --git a/lld/ELF/Arch/X86.cpp b/lld/ELF/Arch/X86.cpp index 0624fe7..a0921cd 100644 --- a/lld/ELF/Arch/X86.cpp +++ b/lld/ELF/Arch/X86.cpp @@ -156,7 +156,7 @@ RelExpr X86::adjustRelaxExpr(RelType Type, const uint8_t *Data, } void X86::writeGotPltHeader(uint8_t *Buf) const { - write32le(Buf, InX::Dynamic->getVA()); + write32le(Buf, In.Dynamic->getVA()); } void X86::writeGotPlt(uint8_t *Buf, const Symbol &S) const { @@ -187,8 +187,8 @@ void X86::writePltHeader(uint8_t *Buf) const { }; memcpy(Buf, V, sizeof(V)); - uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize(); - uint32_t GotPlt = InX::GotPlt->getVA() - Ebx; + uint32_t Ebx = In.Got->getVA() + In.Got->getSize(); + uint32_t GotPlt = In.GotPlt->getVA() - Ebx; write32le(Buf + 2, GotPlt + 4); write32le(Buf + 8, GotPlt + 8); return; @@ -200,7 +200,7 @@ void X86::writePltHeader(uint8_t *Buf) const { 0x90, 0x90, 0x90, 0x90, // nop }; memcpy(Buf, PltData, sizeof(PltData)); - uint32_t GotPlt = InX::GotPlt->getVA(); + uint32_t GotPlt = In.GotPlt->getVA(); write32le(Buf + 2, GotPlt + 4); write32le(Buf + 8, GotPlt + 8); } @@ -217,7 +217,7 @@ void X86::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, if (Config->Pic) { // jmp *foo@GOT(%ebx) - uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize(); + uint32_t Ebx = In.Got->getVA() + In.Got->getSize(); Buf[1] = 0xa3; write32le(Buf + 2, GotPltEntryAddr - Ebx); } else { @@ -451,8 +451,8 @@ void RetpolinePic::writePltHeader(uint8_t *Buf) const { }; memcpy(Buf, Insn, sizeof(Insn)); - uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize(); - uint32_t GotPlt = InX::GotPlt->getVA() - Ebx; + uint32_t Ebx = In.Got->getVA() + In.Got->getSize(); + uint32_t GotPlt = In.GotPlt->getVA() - Ebx; write32le(Buf + 2, GotPlt + 4); write32le(Buf + 9, GotPlt + 8); } @@ -471,7 +471,7 @@ void RetpolinePic::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, }; memcpy(Buf, Insn, sizeof(Insn)); - uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize(); + uint32_t Ebx = In.Got->getVA() + In.Got->getSize(); unsigned Off = getPltEntryOffset(Index); write32le(Buf + 3, GotPltEntryAddr - Ebx); write32le(Buf + 8, -Off - 12 + 32); @@ -510,7 +510,7 @@ void RetpolineNoPic::writePltHeader(uint8_t *Buf) const { }; memcpy(Buf, Insn, sizeof(Insn)); - uint32_t GotPlt = InX::GotPlt->getVA(); + uint32_t GotPlt = In.GotPlt->getVA(); write32le(Buf + 2, GotPlt + 4); write32le(Buf + 8, GotPlt + 8); } diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp index 795de8d..3e7f04d 100644 --- a/lld/ELF/Arch/X86_64.cpp +++ b/lld/ELF/Arch/X86_64.cpp @@ -124,7 +124,7 @@ template void X86_64::writeGotPltHeader(uint8_t *Buf) const { // required, but it is documented in the psabi and the glibc dynamic linker // seems to use it (note that this is relevant for linking ld.so, not any // other program). - write64le(Buf, InX::Dynamic->getVA()); + write64le(Buf, In.Dynamic->getVA()); } template @@ -140,8 +140,8 @@ template void X86_64::writePltHeader(uint8_t *Buf) const { 0x0f, 0x1f, 0x40, 0x00, // nop }; memcpy(Buf, PltData, sizeof(PltData)); - uint64_t GotPlt = InX::GotPlt->getVA(); - uint64_t Plt = InX::Plt->getVA(); + uint64_t GotPlt = In.GotPlt->getVA(); + uint64_t Plt = In.Plt->getVA(); write32le(Buf + 2, GotPlt - Plt + 2); // GOTPLT+8 write32le(Buf + 8, GotPlt - Plt + 4); // GOTPLT+16 } @@ -569,8 +569,8 @@ template void Retpoline::writePltHeader(uint8_t *Buf) const { }; memcpy(Buf, Insn, sizeof(Insn)); - uint64_t GotPlt = InX::GotPlt->getVA(); - uint64_t Plt = InX::Plt->getVA(); + uint64_t GotPlt = In.GotPlt->getVA(); + uint64_t Plt = In.Plt->getVA(); write32le(Buf + 2, GotPlt - Plt - 6 + 8); write32le(Buf + 9, GotPlt - Plt - 13 + 16); } diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 519589f..1181018 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -85,7 +85,6 @@ bool elf::link(ArrayRef Args, bool CanExitEarly, InputSections.clear(); OutputSections.clear(); - Tar = nullptr; BinaryFiles.clear(); BitcodeFiles.clear(); ObjectFiles.clear(); @@ -95,6 +94,10 @@ bool elf::link(ArrayRef Args, bool CanExitEarly, Driver = make(); Script = make(); Symtab = make(); + + Tar = nullptr; + memset(&In, 0, sizeof(In)); + Config->ProgName = Args[0]; Driver->main(Args); @@ -1399,6 +1402,9 @@ static const char *LibcallRoutineNames[] = { // all linker scripts have already been parsed. template void LinkerDriver::link(opt::InputArgList &Args) { Target = getTarget(); + InX::VerDef = nullptr; + InX::VerSym = nullptr; + InX::VerNeed = nullptr; Config->MaxPageSize = getMaxPageSize(Args); Config->ImageBase = getImageBase(Args); diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index c56687a..36d559f 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -620,9 +620,9 @@ InputSectionBase *ObjFile::createInputSection(const Elf_Shdr &Sec) { // FIXME: Retain the first attribute section we see. The eglibc ARM // dynamic loaders require the presence of an attribute section for dlopen // to work. In a full implementation we would merge all attribute sections. - if (InX::ARMAttributes == nullptr) { - InX::ARMAttributes = make(*this, Sec, Name); - return InX::ARMAttributes; + if (In.ARMAttributes == nullptr) { + In.ARMAttributes = make(*this, Sec, Name); + return In.ARMAttributes; } return &InputSection::Discarded; } diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 88c71cc..ca57629 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -356,7 +356,7 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef Rels) { // Output section VA is zero for -r, so r_offset is an offset within the // section, but for --emit-relocs it is an virtual address. P->r_offset = Sec->getVA(Rel.r_offset); - P->setSymbolAndType(InX::SymTab->getSymbolIndex(&Sym), Type, + P->setSymbolAndType(In.SymTab->getSymbolIndex(&Sym), Type, Config->IsMips64EL); if (Sym.Type == STT_SECTION) { @@ -525,16 +525,16 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A, case R_RELAX_TLS_GD_TO_IE_ABS: return Sym.getGotVA() + A; case R_GOTONLY_PC: - return InX::Got->getVA() + A - P; + return In.Got->getVA() + A - P; case R_GOTONLY_PC_FROM_END: - return InX::Got->getVA() + A - P + InX::Got->getSize(); + return In.Got->getVA() + A - P + In.Got->getSize(); case R_GOTREL: - return Sym.getVA(A) - InX::Got->getVA(); + return Sym.getVA(A) - In.Got->getVA(); case R_GOTREL_FROM_END: - return Sym.getVA(A) - InX::Got->getVA() - InX::Got->getSize(); + return Sym.getVA(A) - In.Got->getVA() - In.Got->getSize(); case R_GOT_FROM_END: case R_RELAX_TLS_GD_TO_IE_END: - return Sym.getGotOffset() + A - InX::Got->getSize(); + return Sym.getGotOffset() + A - In.Got->getSize(); case R_TLSLD_GOT_OFF: case R_GOT_OFF: case R_RELAX_TLS_GD_TO_IE_GOT_OFF: @@ -546,9 +546,9 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A, case R_RELAX_TLS_GD_TO_IE: return Sym.getGotVA() + A - P; case R_MIPS_GOTREL: - return Sym.getVA(A) - InX::MipsGot->getGp(File); + return Sym.getVA(A) - In.MipsGot->getGp(File); case R_MIPS_GOT_GP: - return InX::MipsGot->getGp(File) + A; + return In.MipsGot->getGp(File) + A; case R_MIPS_GOT_GP_PC: { // R_MIPS_LO16 expression has R_MIPS_GOT_GP_PC type iif the target // is _gp_disp symbol. In that case we should use the following @@ -557,7 +557,7 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A, // microMIPS variants of these relocations use slightly different // expressions: AHL + GP - P + 3 for %lo() and AHL + GP - P - 1 for %hi() // to correctly handle less-sugnificant bit of the microMIPS symbol. - uint64_t V = InX::MipsGot->getGp(File) + A - P; + uint64_t V = In.MipsGot->getGp(File) + A - P; if (Type == R_MIPS_LO16 || Type == R_MICROMIPS_LO16) V += 4; if (Type == R_MICROMIPS_LO16 || Type == R_MICROMIPS_HI16) @@ -568,23 +568,21 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A, // If relocation against MIPS local symbol requires GOT entry, this entry // should be initialized by 'page address'. This address is high 16-bits // of sum the symbol's value and the addend. - return InX::MipsGot->getVA() + - InX::MipsGot->getPageEntryOffset(File, Sym, A) - - InX::MipsGot->getGp(File); + return In.MipsGot->getVA() + In.MipsGot->getPageEntryOffset(File, Sym, A) - + In.MipsGot->getGp(File); case R_MIPS_GOT_OFF: case R_MIPS_GOT_OFF32: // In case of MIPS if a GOT relocation has non-zero addend this addend // should be applied to the GOT entry content not to the GOT entry offset. // That is why we use separate expression type. - return InX::MipsGot->getVA() + - InX::MipsGot->getSymEntryOffset(File, Sym, A) - - InX::MipsGot->getGp(File); + return In.MipsGot->getVA() + In.MipsGot->getSymEntryOffset(File, Sym, A) - + In.MipsGot->getGp(File); case R_MIPS_TLSGD: - return InX::MipsGot->getVA() + InX::MipsGot->getGlobalDynOffset(File, Sym) - - InX::MipsGot->getGp(File); + return In.MipsGot->getVA() + In.MipsGot->getGlobalDynOffset(File, Sym) - + In.MipsGot->getGp(File); case R_MIPS_TLSLD: - return InX::MipsGot->getVA() + InX::MipsGot->getTlsIndexOffset(File) - - InX::MipsGot->getGp(File); + return In.MipsGot->getVA() + In.MipsGot->getTlsIndexOffset(File) - + In.MipsGot->getGp(File); case R_PAGE_PC: case R_PLT_PAGE_PC: { uint64_t Dest; @@ -677,22 +675,22 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A, case R_SIZE: return Sym.getSize() + A; case R_TLSDESC: - return InX::Got->getGlobalDynAddr(Sym) + A; + return In.Got->getGlobalDynAddr(Sym) + A; case R_TLSDESC_PAGE: - return getAArch64Page(InX::Got->getGlobalDynAddr(Sym) + A) - + return getAArch64Page(In.Got->getGlobalDynAddr(Sym) + A) - getAArch64Page(P); case R_TLSGD_GOT: - return InX::Got->getGlobalDynOffset(Sym) + A; + return In.Got->getGlobalDynOffset(Sym) + A; case R_TLSGD_GOT_FROM_END: - return InX::Got->getGlobalDynOffset(Sym) + A - InX::Got->getSize(); + return In.Got->getGlobalDynOffset(Sym) + A - In.Got->getSize(); case R_TLSGD_PC: - return InX::Got->getGlobalDynAddr(Sym) + A - P; + return In.Got->getGlobalDynAddr(Sym) + A - P; case R_TLSLD_GOT_FROM_END: - return InX::Got->getTlsIndexOff() + A - InX::Got->getSize(); + return In.Got->getTlsIndexOff() + A - In.Got->getSize(); case R_TLSLD_GOT: - return InX::Got->getTlsIndexOff() + A; + return In.Got->getTlsIndexOff() + A; case R_TLSLD_PC: - return InX::Got->getTlsIndexVA() + A - P; + return In.Got->getTlsIndexVA() + A - P; default: llvm_unreachable("invalid expression"); } diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 9c35bb7..d189862 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -415,18 +415,18 @@ LinkerScript::computeInputSections(const InputSectionDescription *Cmd) { void LinkerScript::discard(ArrayRef V) { for (InputSection *S : V) { - if (S == InX::ShStrTab || S == InX::Dynamic || S == InX::DynSymTab || - S == InX::DynStrTab || S == InX::RelaPlt || S == InX::RelaDyn || - S == InX::RelrDyn) + if (S == In.ShStrTab || S == In.Dynamic || S == In.DynSymTab || + S == In.DynStrTab || S == In.RelaPlt || S == In.RelaDyn || + S == In.RelrDyn) error("discarding " + S->Name + " section is not allowed"); // You can discard .hash and .gnu.hash sections by linker scripts. Since // they are synthesized sections, we need to handle them differently than // other regular sections. - if (S == InX::GnuHashTab) - InX::GnuHashTab = nullptr; - if (S == InX::HashTab) - InX::HashTab = nullptr; + if (S == In.GnuHashTab) + In.GnuHashTab = nullptr; + if (S == In.HashTab) + In.HashTab = nullptr; S->Assigned = false; S->Live = false; diff --git a/lld/ELF/MapFile.cpp b/lld/ELF/MapFile.cpp index 54fddfb..870705c 100644 --- a/lld/ELF/MapFile.cpp +++ b/lld/ELF/MapFile.cpp @@ -126,7 +126,7 @@ static void printEhFrame(raw_ostream &OS, OutputSection *OSec) { }; // Gather section pieces. - for (const CieRecord *Rec : InX::EhFrame->getCieRecords()) { + for (const CieRecord *Rec : In.EhFrame->getCieRecords()) { Add(*Rec->Cie); for (const EhSectionPiece *Fde : Rec->Fdes) Add(*Fde); @@ -181,7 +181,7 @@ void elf::writeMapFile() { for (BaseCommand *Base : OSec->SectionCommands) { if (auto *ISD = dyn_cast(Base)) { for (InputSection *IS : ISD->Sections) { - if (IS == InX::EhFrame) { + if (IS == In.EhFrame) { printEhFrame(OS, OSec); continue; } diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 8253b18..0e8e406 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -270,13 +270,13 @@ static void finalizeShtGroup(OutputSection *OS, // sh_link field for SHT_GROUP sections should contain the section index of // the symbol table. - OS->Link = InX::SymTab->getParent()->SectionIndex; + OS->Link = In.SymTab->getParent()->SectionIndex; // sh_info then contain index of an entry in symbol table section which // provides signature of the section group. ObjFile *Obj = Section->getFile(); ArrayRef Symbols = Obj->getSymbols(); - OS->Info = InX::SymTab->getSymbolIndex(Symbols[Section->Info]); + OS->Info = In.SymTab->getSymbolIndex(Symbols[Section->Info]); } template void OutputSection::finalize() { @@ -308,7 +308,7 @@ template void OutputSection::finalize() { if (isa(First)) return; - Link = InX::SymTab->getParent()->SectionIndex; + Link = In.SymTab->getParent()->SectionIndex; // sh_info for SHT_REL[A] sections should contain the section header index of // the section to which the relocation applies. InputSectionBase *S = First->getRelocatedSection(); diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 9d8fb2e..139cd39 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -90,12 +90,12 @@ static unsigned handleMipsTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C, uint64_t Offset, int64_t Addend, RelExpr Expr) { if (Expr == R_MIPS_TLSLD) { - InX::MipsGot->addTlsIndex(*C.File); + In.MipsGot->addTlsIndex(*C.File); C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); return 1; } if (Expr == R_MIPS_TLSGD) { - InX::MipsGot->addDynTlsEntry(*C.File, Sym); + In.MipsGot->addDynTlsEntry(*C.File, Sym); C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); return 1; } @@ -128,17 +128,17 @@ static unsigned handleARMTlsRelocation(RelType Type, Symbol &Sym, auto AddTlsReloc = [&](uint64_t Off, RelType Type, Symbol *Dest, bool Dyn) { if (Dyn) - InX::RelaDyn->addReloc(Type, InX::Got, Off, Dest); + In.RelaDyn->addReloc(Type, In.Got, Off, Dest); else - InX::Got->Relocations.push_back({R_ABS, Type, Off, 0, Dest}); + In.Got->Relocations.push_back({R_ABS, Type, Off, 0, Dest}); }; // Local Dynamic is for access to module local TLS variables, while still // being suitable for being dynamically loaded via dlopen. // GOT[e0] is the module index, with a special value of 0 for the current // module. GOT[e1] is unused. There only needs to be one module index entry. - if (Expr == R_TLSLD_PC && InX::Got->addTlsIndex()) { - AddTlsReloc(InX::Got->getTlsIndexOff(), Target->TlsModuleIndexRel, + if (Expr == R_TLSLD_PC && In.Got->addTlsIndex()) { + AddTlsReloc(In.Got->getTlsIndexOff(), Target->TlsModuleIndexRel, NeedDynId ? nullptr : &Sym, NeedDynId); C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); return 1; @@ -148,8 +148,8 @@ static unsigned handleARMTlsRelocation(RelType Type, Symbol &Sym, // the module index and offset of symbol in TLS block we can fill these in // using static GOT relocations. if (Expr == R_TLSGD_PC) { - if (InX::Got->addDynTlsEntry(Sym)) { - uint64_t Off = InX::Got->getGlobalDynOffset(Sym); + if (In.Got->addDynTlsEntry(Sym)) { + uint64_t Off = In.Got->getGlobalDynOffset(Sym); AddTlsReloc(Off, Target->TlsModuleIndexRel, &Sym, NeedDynId); AddTlsReloc(Off + Config->Wordsize, Target->TlsOffsetRel, &Sym, NeedDynOff); @@ -175,10 +175,10 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C, if (isRelExprOneOf(Expr) && Config->Shared) { - if (InX::Got->addDynTlsEntry(Sym)) { - uint64_t Off = InX::Got->getGlobalDynOffset(Sym); - InX::RelaDyn->addReloc( - {Target->TlsDescRel, InX::Got, Off, !Sym.IsPreemptible, &Sym, 0}); + if (In.Got->addDynTlsEntry(Sym)) { + uint64_t Off = In.Got->getGlobalDynOffset(Sym); + In.RelaDyn->addReloc( + {Target->TlsDescRel, In.Got, Off, !Sym.IsPreemptible, &Sym, 0}); } if (Expr != R_TLSDESC_CALL) C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); @@ -196,9 +196,9 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C, } if (Expr == R_TLSLD_HINT) return 1; - if (InX::Got->addTlsIndex()) - InX::RelaDyn->addReloc(Target->TlsModuleIndexRel, InX::Got, - InX::Got->getTlsIndexOff(), nullptr); + if (In.Got->addTlsIndex()) + In.RelaDyn->addReloc(Target->TlsModuleIndexRel, In.Got, + In.Got->getTlsIndexOff(), nullptr); C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); return 1; } @@ -220,9 +220,10 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C, return 1; } if (!Sym.isInGot()) { - InX::Got->addEntry(Sym); + In.Got->addEntry(Sym); uint64_t Off = Sym.getGotOffset(); - InX::Got->Relocations.push_back({R_ABS, Target->TlsOffsetRel, Off, 0, &Sym}); + In.Got->Relocations.push_back( + {R_ABS, Target->TlsOffsetRel, Off, 0, &Sym}); } C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); return 1; @@ -231,18 +232,17 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C, if (isRelExprOneOf(Expr)) { if (Config->Shared) { - if (InX::Got->addDynTlsEntry(Sym)) { - uint64_t Off = InX::Got->getGlobalDynOffset(Sym); - InX::RelaDyn->addReloc(Target->TlsModuleIndexRel, InX::Got, Off, &Sym); + if (In.Got->addDynTlsEntry(Sym)) { + uint64_t Off = In.Got->getGlobalDynOffset(Sym); + In.RelaDyn->addReloc(Target->TlsModuleIndexRel, In.Got, Off, &Sym); // If the symbol is preemptible we need the dynamic linker to write // the offset too. uint64_t OffsetOff = Off + Config->Wordsize; if (Sym.IsPreemptible) - InX::RelaDyn->addReloc(Target->TlsOffsetRel, InX::Got, OffsetOff, - &Sym); + In.RelaDyn->addReloc(Target->TlsOffsetRel, In.Got, OffsetOff, &Sym); else - InX::Got->Relocations.push_back( + In.Got->Relocations.push_back( {R_ABS, Target->TlsOffsetRel, OffsetOff, 0, &Sym}); } C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); @@ -256,9 +256,9 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C, {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_GD_TO_IE), Type, Offset, Addend, &Sym}); if (!Sym.isInGot()) { - InX::Got->addEntry(Sym); - InX::RelaDyn->addReloc(Target->TlsGotRel, InX::Got, Sym.getGotOffset(), - &Sym); + In.Got->addEntry(Sym); + In.RelaDyn->addReloc(Target->TlsGotRel, In.Got, Sym.getGotOffset(), + &Sym); } } else { C.Relocations.push_back( @@ -547,9 +547,9 @@ template static void addCopyRelSymbol(SharedSymbol &SS) { BssSection *Sec = make(IsReadOnly ? ".bss.rel.ro" : ".bss", SymSize, SS.Alignment); if (IsReadOnly) - InX::BssRelRo->getParent()->addSection(Sec); + In.BssRelRo->getParent()->addSection(Sec); else - InX::Bss->getParent()->addSection(Sec); + In.Bss->getParent()->addSection(Sec); // Look through the DSO's dynamic symbol table for aliases and create a // dynamic symbol for each one. This causes the copy relocation to correctly @@ -557,7 +557,7 @@ template static void addCopyRelSymbol(SharedSymbol &SS) { for (SharedSymbol *Sym : getSymbolsAt(SS)) replaceWithDefined(*Sym, Sec, 0, Sym->Size); - InX::RelaDyn->addReloc(Target->CopyRel, Sec, 0, &SS); + In.RelaDyn->addReloc(Target->CopyRel, Sec, 0, &SS); } // MIPS has an odd notion of "paired" relocations to calculate addends. @@ -721,13 +721,13 @@ static void addRelativeReloc(InputSectionBase *IS, uint64_t OffsetInSec, // RelrDyn sections don't support odd offsets. Also, RelrDyn sections // don't store the addend values, so we must write it to the relocated // address. - if (InX::RelrDyn && IS->Alignment >= 2 && OffsetInSec % 2 == 0) { + if (In.RelrDyn && IS->Alignment >= 2 && OffsetInSec % 2 == 0) { IS->Relocations.push_back({Expr, Type, OffsetInSec, Addend, Sym}); - InX::RelrDyn->Relocs.push_back({IS, OffsetInSec}); + In.RelrDyn->Relocs.push_back({IS, OffsetInSec}); return; } - InX::RelaDyn->addReloc(Target->RelativeRel, IS, OffsetInSec, Sym, Addend, - Expr, Type); + In.RelaDyn->addReloc(Target->RelativeRel, IS, OffsetInSec, Sym, Addend, Expr, + Type); } template @@ -740,7 +740,7 @@ static void addPltEntry(PltSection *Plt, GotPltSection *GotPlt, } template static void addGotEntry(Symbol &Sym) { - InX::Got->addEntry(Sym); + In.Got->addEntry(Sym); RelExpr Expr = Sym.isTls() ? R_TLS : R_ABS; uint64_t Off = Sym.getGotOffset(); @@ -755,19 +755,19 @@ template static void addGotEntry(Symbol &Sym) { bool IsLinkTimeConstant = !Sym.IsPreemptible && (!Config->Pic || isAbsolute(Sym)); if (IsLinkTimeConstant) { - InX::Got->Relocations.push_back({Expr, Target->GotRel, Off, 0, &Sym}); + In.Got->Relocations.push_back({Expr, Target->GotRel, Off, 0, &Sym}); return; } // Otherwise, we emit a dynamic relocation to .rel[a].dyn so that // the GOT slot will be fixed at load-time. if (!Sym.isTls() && !Sym.IsPreemptible && Config->Pic && !isAbsolute(Sym)) { - addRelativeReloc(InX::Got, Off, &Sym, 0, R_ABS, Target->GotRel); + addRelativeReloc(In.Got, Off, &Sym, 0, R_ABS, Target->GotRel); return; } - InX::RelaDyn->addReloc(Sym.isTls() ? Target->TlsGotRel : Target->GotRel, - InX::Got, Off, &Sym, 0, - Sym.IsPreemptible ? R_ADDEND : R_ABS, Target->GotRel); + In.RelaDyn->addReloc(Sym.isTls() ? Target->TlsGotRel : Target->GotRel, In.Got, + Off, &Sym, 0, Sym.IsPreemptible ? R_ADDEND : R_ABS, + Target->GotRel); } // Return true if we can define a symbol in the executable that @@ -820,7 +820,7 @@ static void processRelocAux(InputSectionBase &Sec, RelExpr Expr, RelType Type, addRelativeReloc(&Sec, Offset, &Sym, Addend, Expr, Type); return; } else if (RelType Rel = Target->getDynRel(Type)) { - InX::RelaDyn->addReloc(Rel, &Sec, Offset, &Sym, Addend, R_ADDEND, Type); + In.RelaDyn->addReloc(Rel, &Sec, Offset, &Sym, Addend, R_ADDEND, Type); // MIPS ABI turns using of GOT and dynamic relocations inside out. // While regular ABI uses dynamic relocations to fill up GOT entries @@ -838,7 +838,7 @@ static void processRelocAux(InputSectionBase &Sec, RelExpr Expr, RelType Type, // a dynamic relocation. // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf p.4-19 if (Config->EMachine == EM_MIPS) - InX::MipsGot->addEntry(*Sec.File, Sym, Addend, Expr); + In.MipsGot->addEntry(*Sec.File, Sym, Addend, Expr); return; } } @@ -925,10 +925,9 @@ static void processRelocAux(InputSectionBase &Sec, RelExpr Expr, RelType Type, "' cannot be preempted; recompile with -fPIE" + getLocation(Sec, Sym, Offset)); if (!Sym.isInPlt()) - addPltEntry(InX::Plt, InX::GotPlt, InX::RelaPlt, Target->PltRel, - Sym); + addPltEntry(In.Plt, In.GotPlt, In.RelaPlt, Target->PltRel, Sym); if (!Sym.isDefined()) - replaceWithDefined(Sym, InX::Plt, Sym.getPltOffset(), 0); + replaceWithDefined(Sym, In.Plt, Sym.getPltOffset(), 0); Sym.NeedsPltAddr = true; Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); return; @@ -991,7 +990,7 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I, // needs it to be created. Here we request for that. if (isRelExprOneOf(Expr)) - InX::Got->HasGotOffRel = true; + In.Got->HasGotOffRel = true; // Read an addend. int64_t Addend = computeAddend(Rel, End, Sec, Expr, Sym.isLocal()); @@ -1007,11 +1006,10 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I, // If a relocation needs PLT, we create PLT and GOTPLT slots for the symbol. if (needsPlt(Expr) && !Sym.isInPlt()) { if (Sym.isGnuIFunc() && !Sym.IsPreemptible) - addPltEntry(InX::Iplt, InX::IgotPlt, InX::RelaIplt, - Target->IRelativeRel, Sym); - else - addPltEntry(InX::Plt, InX::GotPlt, InX::RelaPlt, Target->PltRel, + addPltEntry(In.Iplt, In.IgotPlt, In.RelaIplt, Target->IRelativeRel, Sym); + else + addPltEntry(In.Plt, In.GotPlt, In.RelaPlt, Target->PltRel, Sym); } // Create a GOT slot if a relocation needs GOT. @@ -1024,7 +1022,7 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I, // See "Global Offset Table" in Chapter 5 in the following document // for detailed description: // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf - InX::MipsGot->addEntry(*Sec.File, Sym, Addend, Expr); + In.MipsGot->addEntry(*Sec.File, Sym, Addend, Expr); } else if (!Sym.isInGot()) { addGotEntry(Sym); } diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp index c37d20c..92674b9 100644 --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -119,7 +119,7 @@ uint64_t Symbol::getVA(int64_t Addend) const { return OutVA + Addend; } -uint64_t Symbol::getGotVA() const { return InX::Got->getVA() + getGotOffset(); } +uint64_t Symbol::getGotVA() const { return In.Got->getVA() + getGotOffset(); } uint64_t Symbol::getGotOffset() const { return GotIndex * Target->GotEntrySize; @@ -127,8 +127,8 @@ uint64_t Symbol::getGotOffset() const { uint64_t Symbol::getGotPltVA() const { if (this->IsInIgot) - return InX::IgotPlt->getVA() + getGotPltOffset(); - return InX::GotPlt->getVA() + getGotPltOffset(); + return In.IgotPlt->getVA() + getGotPltOffset(); + return In.GotPlt->getVA() + getGotPltOffset(); } uint64_t Symbol::getGotPltOffset() const { @@ -139,8 +139,8 @@ uint64_t Symbol::getGotPltOffset() const { uint64_t Symbol::getPltVA() const { if (this->IsInIplt) - return InX::Iplt->getVA() + PltIndex * Target->PltEntrySize; - return InX::Plt->getVA() + Target->getPltEntryOffset(PltIndex); + return In.Iplt->getVA() + PltIndex * Target->PltEntrySize; + return In.Plt->getVA() + Target->getPltEntryOffset(PltIndex); } uint64_t Symbol::getPltOffset() const { diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index a12a506..1f86571 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -154,7 +154,7 @@ template void MipsOptionsSection::writeTo(uint8_t *Buf) { Options->size = getSize(); if (!Config->Relocatable) - Reginfo.ri_gp_value = InX::MipsGot->getGp(); + Reginfo.ri_gp_value = In.MipsGot->getGp(); memcpy(Buf + sizeof(Elf_Mips_Options), &Reginfo, sizeof(Reginfo)); } @@ -211,7 +211,7 @@ MipsReginfoSection::MipsReginfoSection(Elf_Mips_RegInfo Reginfo) template void MipsReginfoSection::writeTo(uint8_t *Buf) { if (!Config->Relocatable) - Reginfo.ri_gp_value = InX::MipsGot->getGp(); + Reginfo.ri_gp_value = In.MipsGot->getGp(); memcpy(Buf, &Reginfo, sizeof(Reginfo)); } @@ -261,8 +261,8 @@ Defined *elf::addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value, uint64_t Size, InputSectionBase &Section) { auto *S = make(Section.File, Name, STB_LOCAL, STV_DEFAULT, Type, Value, Size, &Section); - if (InX::SymTab) - InX::SymTab->addSymbol(S); + if (In.SymTab) + In.SymTab->addSymbol(S); return S; } @@ -503,7 +503,7 @@ std::vector EhFrameSection::getFdeData() const { uint8_t *Buf = getParent()->Loc + OutSecOff; std::vector Ret; - uint64_t VA = InX::EhFrameHdr->getVA(); + uint64_t VA = In.EhFrameHdr->getVA(); for (CieRecord *Rec : CieRecords) { uint8_t Enc = getFdeEncoding(Rec->Cie); for (EhSectionPiece *Fde : Rec->Fdes) { @@ -938,7 +938,7 @@ template void MipsGotSection::build() { Symbol *S = P.first; uint64_t Offset = P.second * Config->Wordsize; if (S->IsPreemptible) - InX::RelaDyn->addReloc(Target->TlsGotRel, this, Offset, S); + In.RelaDyn->addReloc(Target->TlsGotRel, this, Offset, S); } for (std::pair &P : Got.DynTlsSymbols) { Symbol *S = P.first; @@ -946,7 +946,7 @@ template void MipsGotSection::build() { if (S == nullptr) { if (!Config->Pic) continue; - InX::RelaDyn->addReloc(Target->TlsModuleIndexRel, this, Offset, S); + In.RelaDyn->addReloc(Target->TlsModuleIndexRel, this, Offset, S); } else { // When building a shared library we still need a dynamic relocation // for the module index. Therefore only checking for @@ -954,13 +954,13 @@ template void MipsGotSection::build() { // thread-locals that have been marked as local through a linker script) if (!S->IsPreemptible && !Config->Pic) continue; - InX::RelaDyn->addReloc(Target->TlsModuleIndexRel, this, Offset, S); + In.RelaDyn->addReloc(Target->TlsModuleIndexRel, this, Offset, S); // However, we can skip writing the TLS offset reloc for non-preemptible // symbols since it is known even in shared libraries if (!S->IsPreemptible) continue; Offset += Config->Wordsize; - InX::RelaDyn->addReloc(Target->TlsOffsetRel, this, Offset, S); + In.RelaDyn->addReloc(Target->TlsOffsetRel, this, Offset, S); } } @@ -972,7 +972,7 @@ template void MipsGotSection::build() { // Dynamic relocations for "global" entries. for (const std::pair &P : Got.Global) { uint64_t Offset = P.second * Config->Wordsize; - InX::RelaDyn->addReloc(Target->RelativeRel, this, Offset, P.first); + In.RelaDyn->addReloc(Target->RelativeRel, this, Offset, P.first); } if (!Config->Pic) continue; @@ -982,14 +982,14 @@ template void MipsGotSection::build() { size_t PageCount = L.second.Count; for (size_t PI = 0; PI < PageCount; ++PI) { uint64_t Offset = (L.second.FirstIndex + PI) * Config->Wordsize; - InX::RelaDyn->addReloc({Target->RelativeRel, this, Offset, L.first, - int64_t(PI * 0x10000)}); + In.RelaDyn->addReloc({Target->RelativeRel, this, Offset, L.first, + int64_t(PI * 0x10000)}); } } for (const std::pair &P : Got.Local16) { uint64_t Offset = P.second * Config->Wordsize; - InX::RelaDyn->addReloc({Target->RelativeRel, this, Offset, true, - P.first.first, P.first.second}); + In.RelaDyn->addReloc({Target->RelativeRel, this, Offset, true, + P.first.first, P.first.second}); } } } @@ -1201,21 +1201,21 @@ DynamicSection::DynamicSection() // Add strings to .dynstr early so that .dynstr's size will be // fixed early. for (StringRef S : Config->FilterList) - addInt(DT_FILTER, InX::DynStrTab->addString(S)); + addInt(DT_FILTER, In.DynStrTab->addString(S)); for (StringRef S : Config->AuxiliaryList) - addInt(DT_AUXILIARY, InX::DynStrTab->addString(S)); + addInt(DT_AUXILIARY, In.DynStrTab->addString(S)); if (!Config->Rpath.empty()) addInt(Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH, - InX::DynStrTab->addString(Config->Rpath)); + In.DynStrTab->addString(Config->Rpath)); for (InputFile *File : SharedFiles) { SharedFile *F = cast>(File); if (F->IsNeeded) - addInt(DT_NEEDED, InX::DynStrTab->addString(F->SoName)); + addInt(DT_NEEDED, In.DynStrTab->addString(F->SoName)); } if (!Config->SoName.empty()) - addInt(DT_SONAME, InX::DynStrTab->addString(Config->SoName)); + addInt(DT_SONAME, In.DynStrTab->addString(Config->SoName)); } template @@ -1302,10 +1302,10 @@ template void DynamicSection::finalizeContents() { if (!Config->Shared && !Config->Relocatable && !Config->ZRodynamic) addInt(DT_DEBUG, 0); - this->Link = InX::DynStrTab->getParent()->SectionIndex; - if (!InX::RelaDyn->empty()) { - addInSec(InX::RelaDyn->DynamicTag, InX::RelaDyn); - addSize(InX::RelaDyn->SizeDynamicTag, InX::RelaDyn->getParent()); + this->Link = In.DynStrTab->getParent()->SectionIndex; + if (!In.RelaDyn->empty()) { + addInSec(In.RelaDyn->DynamicTag, In.RelaDyn); + addSize(In.RelaDyn->SizeDynamicTag, In.RelaDyn->getParent()); bool IsRela = Config->IsRela; addInt(IsRela ? DT_RELAENT : DT_RELENT, @@ -1315,16 +1315,16 @@ template void DynamicSection::finalizeContents() { // The problem is in the tight relation between dynamic // relocations and GOT. So do not emit this tag on MIPS. if (Config->EMachine != EM_MIPS) { - size_t NumRelativeRels = InX::RelaDyn->getRelativeRelocCount(); + size_t NumRelativeRels = In.RelaDyn->getRelativeRelocCount(); if (Config->ZCombreloc && NumRelativeRels) addInt(IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels); } } - if (InX::RelrDyn && !InX::RelrDyn->Relocs.empty()) { + if (In.RelrDyn && !In.RelrDyn->Relocs.empty()) { addInSec(Config->UseAndroidRelrTags ? DT_ANDROID_RELR : DT_RELR, - InX::RelrDyn); + In.RelrDyn); addSize(Config->UseAndroidRelrTags ? DT_ANDROID_RELRSZ : DT_RELRSZ, - InX::RelrDyn->getParent()); + In.RelrDyn->getParent()); addInt(Config->UseAndroidRelrTags ? DT_ANDROID_RELRENT : DT_RELRENT, sizeof(Elf_Relr)); } @@ -1334,33 +1334,33 @@ template void DynamicSection::finalizeContents() { // as RelaIplt have. And we still want to emit proper dynamic tags for that // case, so here we always use RelaPlt as marker for the begining of // .rel[a].plt section. - if (InX::RelaPlt->getParent()->Live) { - addInSec(DT_JMPREL, InX::RelaPlt); - addSize(DT_PLTRELSZ, InX::RelaPlt->getParent()); + if (In.RelaPlt->getParent()->Live) { + addInSec(DT_JMPREL, In.RelaPlt); + addSize(DT_PLTRELSZ, In.RelaPlt->getParent()); switch (Config->EMachine) { case EM_MIPS: - addInSec(DT_MIPS_PLTGOT, InX::GotPlt); + addInSec(DT_MIPS_PLTGOT, In.GotPlt); break; case EM_SPARCV9: - addInSec(DT_PLTGOT, InX::Plt); + addInSec(DT_PLTGOT, In.Plt); break; default: - addInSec(DT_PLTGOT, InX::GotPlt); + addInSec(DT_PLTGOT, In.GotPlt); break; } addInt(DT_PLTREL, Config->IsRela ? DT_RELA : DT_REL); } - addInSec(DT_SYMTAB, InX::DynSymTab); + addInSec(DT_SYMTAB, In.DynSymTab); addInt(DT_SYMENT, sizeof(Elf_Sym)); - addInSec(DT_STRTAB, InX::DynStrTab); - addInt(DT_STRSZ, InX::DynStrTab->getSize()); + addInSec(DT_STRTAB, In.DynStrTab); + addInt(DT_STRSZ, In.DynStrTab->getSize()); if (!Config->ZText) addInt(DT_TEXTREL, 0); - if (InX::GnuHashTab) - addInSec(DT_GNU_HASH, InX::GnuHashTab); - if (InX::HashTab) - addInSec(DT_HASH, InX::HashTab); + if (In.GnuHashTab) + addInSec(DT_GNU_HASH, In.GnuHashTab); + if (In.HashTab) + addInSec(DT_HASH, In.HashTab); if (Out::PreinitArray) { addOutSec(DT_PREINIT_ARRAY, Out::PreinitArray); @@ -1382,47 +1382,47 @@ template void DynamicSection::finalizeContents() { if (B->isDefined()) addSym(DT_FINI, B); - bool HasVerNeed = In::VerNeed->getNeedNum() != 0; - if (HasVerNeed || In::VerDef) - addInSec(DT_VERSYM, In::VerSym); - if (In::VerDef) { - addInSec(DT_VERDEF, In::VerDef); + bool HasVerNeed = InX::VerNeed->getNeedNum() != 0; + if (HasVerNeed || InX::VerDef) + addInSec(DT_VERSYM, InX::VerSym); + if (InX::VerDef) { + addInSec(DT_VERDEF, InX::VerDef); addInt(DT_VERDEFNUM, getVerDefNum()); } if (HasVerNeed) { - addInSec(DT_VERNEED, In::VerNeed); - addInt(DT_VERNEEDNUM, In::VerNeed->getNeedNum()); + addInSec(DT_VERNEED, InX::VerNeed); + addInt(DT_VERNEEDNUM, InX::VerNeed->getNeedNum()); } if (Config->EMachine == EM_MIPS) { addInt(DT_MIPS_RLD_VERSION, 1); addInt(DT_MIPS_FLAGS, RHF_NOTPOT); addInt(DT_MIPS_BASE_ADDRESS, Target->getImageBase()); - addInt(DT_MIPS_SYMTABNO, InX::DynSymTab->getNumSymbols()); + addInt(DT_MIPS_SYMTABNO, In.DynSymTab->getNumSymbols()); - add(DT_MIPS_LOCAL_GOTNO, [] { return InX::MipsGot->getLocalEntriesNum(); }); + add(DT_MIPS_LOCAL_GOTNO, [] { return In.MipsGot->getLocalEntriesNum(); }); - if (const Symbol *B = InX::MipsGot->getFirstGlobalEntry()) + if (const Symbol *B = In.MipsGot->getFirstGlobalEntry()) addInt(DT_MIPS_GOTSYM, B->DynsymIndex); else - addInt(DT_MIPS_GOTSYM, InX::DynSymTab->getNumSymbols()); - addInSec(DT_PLTGOT, InX::MipsGot); - if (InX::MipsRldMap) { + addInt(DT_MIPS_GOTSYM, In.DynSymTab->getNumSymbols()); + addInSec(DT_PLTGOT, In.MipsGot); + if (In.MipsRldMap) { if (!Config->Pie) - addInSec(DT_MIPS_RLD_MAP, InX::MipsRldMap); + addInSec(DT_MIPS_RLD_MAP, In.MipsRldMap); // Store the offset to the .rld_map section // relative to the address of the tag. - addInSecRelative(DT_MIPS_RLD_MAP_REL, InX::MipsRldMap); + addInSecRelative(DT_MIPS_RLD_MAP_REL, In.MipsRldMap); } } // Glink dynamic tag is required by the V2 abi if the plt section isn't empty. - if (Config->EMachine == EM_PPC64 && !InX::Plt->empty()) { + if (Config->EMachine == EM_PPC64 && !In.Plt->empty()) { // The Glink tag points to 32 bytes before the first lazy symbol resolution // stub, which starts directly after the header. Entries.push_back({DT_PPC64_GLINK, [=] { unsigned Offset = Target->PltHeaderSize - 32; - return InX::Plt->getVA(0) + Offset; + return In.Plt->getVA(0) + Offset; }}); } @@ -1494,7 +1494,7 @@ void RelocationBaseSection::finalizeContents() { // If all relocations are R_*_RELATIVE they don't refer to any // dynamic symbol and we don't need a dynamic symbol table. If that // is the case, just use 0 as the link. - Link = InX::DynSymTab ? InX::DynSymTab->getParent()->SectionIndex : 0; + Link = In.DynSymTab ? In.DynSymTab->getParent()->SectionIndex : 0; // Set required output section properties. getParent()->Link = Link; @@ -1862,9 +1862,9 @@ void SymbolTableBaseSection::finalizeContents() { // Because the first symbol entry is a null entry, 1 is the first. getParent()->Info = 1; - if (InX::GnuHashTab) { + if (In.GnuHashTab) { // NB: It also sorts Symbols to meet the GNU hash table requirements. - InX::GnuHashTab->addSymbols(Symbols); + In.GnuHashTab->addSymbols(Symbols); } else if (Config->EMachine == EM_MIPS) { std::stable_sort(Symbols.begin(), Symbols.end(), sortMipsSymbols); } @@ -2044,7 +2044,7 @@ void SymtabShndxSection::writeTo(uint8_t *Buf) { // with an entry in .symtab. If the corresponding entry contains SHN_XINDEX, // we need to write actual index, otherwise, we must write SHN_UNDEF(0). Buf += 4; // Ignore .symtab[0] entry. - for (const SymbolTableEntry &Entry : InX::SymTab->getSymbols()) { + for (const SymbolTableEntry &Entry : In.SymTab->getSymbols()) { if (getSymSectionIndex(Entry.Sym) == SHN_XINDEX) write32(Buf, Entry.Sym->getOutputSection()->SectionIndex); Buf += 4; @@ -2065,11 +2065,11 @@ bool SymtabShndxSection::empty() const { } void SymtabShndxSection::finalizeContents() { - getParent()->Link = InX::SymTab->getParent()->SectionIndex; + getParent()->Link = In.SymTab->getParent()->SectionIndex; } size_t SymtabShndxSection::getSize() const { - return InX::SymTab->getNumSymbols() * 4; + return In.SymTab->getNumSymbols() * 4; } // .hash and .gnu.hash sections contain on-disk hash tables that map @@ -2108,7 +2108,7 @@ GnuHashTableSection::GnuHashTableSection() } void GnuHashTableSection::finalizeContents() { - getParent()->Link = InX::DynSymTab->getParent()->SectionIndex; + getParent()->Link = In.DynSymTab->getParent()->SectionIndex; // Computes bloom filter size in word size. We want to allocate 12 // bits for each symbol. It must be a power of two. @@ -2133,7 +2133,7 @@ void GnuHashTableSection::writeTo(uint8_t *Buf) { // Write a header. write32(Buf, NBuckets); - write32(Buf + 4, InX::DynSymTab->getNumSymbols() - Symbols.size()); + write32(Buf + 4, In.DynSymTab->getNumSymbols() - Symbols.size()); write32(Buf + 8, MaskWords); write32(Buf + 12, Shift2); Buf += 16; @@ -2238,13 +2238,13 @@ HashTableSection::HashTableSection() } void HashTableSection::finalizeContents() { - getParent()->Link = InX::DynSymTab->getParent()->SectionIndex; + getParent()->Link = In.DynSymTab->getParent()->SectionIndex; unsigned NumEntries = 2; // nbucket and nchain. - NumEntries += InX::DynSymTab->getNumSymbols(); // The chain entries. + NumEntries += In.DynSymTab->getNumSymbols(); // The chain entries. // Create as many buckets as there are symbols. - NumEntries += InX::DynSymTab->getNumSymbols(); + NumEntries += In.DynSymTab->getNumSymbols(); this->Size = NumEntries * 4; } @@ -2252,7 +2252,7 @@ void HashTableSection::writeTo(uint8_t *Buf) { // See comment in GnuHashTableSection::writeTo. memset(Buf, 0, Size); - unsigned NumSymbols = InX::DynSymTab->getNumSymbols(); + unsigned NumSymbols = In.DynSymTab->getNumSymbols(); uint32_t *P = reinterpret_cast(Buf); write32(P++, NumSymbols); // nbucket @@ -2261,7 +2261,7 @@ void HashTableSection::writeTo(uint8_t *Buf) { uint32_t *Buckets = P; uint32_t *Chains = P + NumSymbols; - for (const SymbolTableEntry &S : InX::DynSymTab->getSymbols()) { + for (const SymbolTableEntry &S : In.DynSymTab->getSymbols()) { Symbol *Sym = S.Sym; StringRef Name = Sym->getName(); unsigned I = Sym->DynsymIndex; @@ -2304,9 +2304,9 @@ void PltSection::writeTo(uint8_t *Buf) { template void PltSection::addEntry(Symbol &Sym) { Sym.PltIndex = Entries.size(); - RelocationBaseSection *PltRelocSection = InX::RelaPlt; + RelocationBaseSection *PltRelocSection = In.RelaPlt; if (IsIplt) { - PltRelocSection = InX::RelaIplt; + PltRelocSection = In.RelaIplt; Sym.IsInIplt = true; } unsigned RelOff = @@ -2332,7 +2332,7 @@ void PltSection::addSymbols() { } unsigned PltSection::getPltRelocOff() const { - return IsIplt ? InX::Plt->getSize() : 0; + return IsIplt ? In.Plt->getSize() : 0; } // The string hash function for .gdb_index. @@ -2603,13 +2603,13 @@ EhFrameHeader::EhFrameHeader() void EhFrameHeader::writeTo(uint8_t *Buf) { typedef EhFrameSection::FdeData FdeData; - std::vector Fdes = InX::EhFrame->getFdeData(); + std::vector Fdes = In.EhFrame->getFdeData(); Buf[0] = 1; Buf[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4; Buf[2] = DW_EH_PE_udata4; Buf[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4; - write32(Buf + 4, InX::EhFrame->getParent()->Addr - this->getVA() - 4); + write32(Buf + 4, In.EhFrame->getParent()->Addr - this->getVA() - 4); write32(Buf + 8, Fdes.size()); Buf += 12; @@ -2622,10 +2622,10 @@ void EhFrameHeader::writeTo(uint8_t *Buf) { size_t EhFrameHeader::getSize() const { // .eh_frame_hdr has a 12 bytes header followed by an array of FDEs. - return 12 + InX::EhFrame->NumFdes * 8; + return 12 + In.EhFrame->NumFdes * 8; } -bool EhFrameHeader::empty() const { return InX::EhFrame->empty(); } +bool EhFrameHeader::empty() const { return In.EhFrame->empty(); } template VersionDefinitionSection::VersionDefinitionSection() @@ -2639,11 +2639,11 @@ static StringRef getFileDefName() { } template void VersionDefinitionSection::finalizeContents() { - FileDefNameOff = InX::DynStrTab->addString(getFileDefName()); + FileDefNameOff = In.DynStrTab->addString(getFileDefName()); for (VersionDefinition &V : Config->VersionDefinitions) - V.NameOff = InX::DynStrTab->addString(V.Name); + V.NameOff = In.DynStrTab->addString(V.Name); - getParent()->Link = InX::DynStrTab->getParent()->SectionIndex; + getParent()->Link = In.DynStrTab->getParent()->SectionIndex; // sh_info should be set to the number of definitions. This fact is missed in // documentation, but confirmed by binutils community: @@ -2696,23 +2696,23 @@ VersionTableSection::VersionTableSection() template void VersionTableSection::finalizeContents() { // At the moment of june 2016 GNU docs does not mention that sh_link field // should be set, but Sun docs do. Also readelf relies on this field. - getParent()->Link = InX::DynSymTab->getParent()->SectionIndex; + getParent()->Link = In.DynSymTab->getParent()->SectionIndex; } template size_t VersionTableSection::getSize() const { - return sizeof(Elf_Versym) * (InX::DynSymTab->getSymbols().size() + 1); + return sizeof(Elf_Versym) * (In.DynSymTab->getSymbols().size() + 1); } template void VersionTableSection::writeTo(uint8_t *Buf) { auto *OutVersym = reinterpret_cast(Buf) + 1; - for (const SymbolTableEntry &S : InX::DynSymTab->getSymbols()) { + for (const SymbolTableEntry &S : In.DynSymTab->getSymbols()) { OutVersym->vs_index = S.Sym->VersionId; ++OutVersym; } } template bool VersionTableSection::empty() const { - return !In::VerDef && In::VerNeed->empty(); + return !InX::VerDef && InX::VerNeed->empty(); } template @@ -2736,7 +2736,7 @@ template void VersionNeedSection::addSymbol(Symbol *SS) { // to create one by adding it to our needed list and creating a dynstr entry // for the soname. if (File.VerdefMap.empty()) - Needed.push_back({&File, InX::DynStrTab->addString(File.SoName)}); + Needed.push_back({&File, In.DynStrTab->addString(File.SoName)}); const typename ELFT::Verdef *Ver = File.Verdefs[SS->VerdefIndex]; typename SharedFile::NeededVer &NV = File.VerdefMap[Ver]; @@ -2744,8 +2744,8 @@ template void VersionNeedSection::addSymbol(Symbol *SS) { // prepare to create one by allocating a version identifier and creating a // dynstr entry for the version name. if (NV.Index == 0) { - NV.StrTab = InX::DynStrTab->addString(File.getStringTable().data() + - Ver->getAux()->vda_name); + NV.StrTab = In.DynStrTab->addString(File.getStringTable().data() + + Ver->getAux()->vda_name); NV.Index = NextIndex++; } SS->VersionId = NV.Index; @@ -2787,7 +2787,7 @@ template void VersionNeedSection::writeTo(uint8_t *Buf) { } template void VersionNeedSection::finalizeContents() { - getParent()->Link = InX::DynStrTab->getParent()->SectionIndex; + getParent()->Link = In.DynStrTab->getParent()->SectionIndex; getParent()->Info = Needed.size(); } @@ -3047,34 +3047,7 @@ bool ThunkSection::assignOffsets() { return Changed; } -InputSection *InX::ARMAttributes; -BssSection *InX::Bss; -BssSection *InX::BssRelRo; -BuildIdSection *InX::BuildId; -EhFrameHeader *InX::EhFrameHdr; -EhFrameSection *InX::EhFrame; -SyntheticSection *InX::Dynamic; -StringTableSection *InX::DynStrTab; -SymbolTableBaseSection *InX::DynSymTab; -InputSection *InX::Interp; -GdbIndexSection *InX::GdbIndex; -GotSection *InX::Got; -GotPltSection *InX::GotPlt; -GnuHashTableSection *InX::GnuHashTab; -HashTableSection *InX::HashTab; -IgotPltSection *InX::IgotPlt; -MipsGotSection *InX::MipsGot; -MipsRldMapSection *InX::MipsRldMap; -PltSection *InX::Plt; -PltSection *InX::Iplt; -RelocationBaseSection *InX::RelaDyn; -RelrBaseSection *InX::RelrDyn; -RelocationBaseSection *InX::RelaPlt; -RelocationBaseSection *InX::RelaIplt; -StringTableSection *InX::ShStrTab; -StringTableSection *InX::StrTab; -SymbolTableBaseSection *InX::SymTab; -SymtabShndxSection *InX::SymTabShndx; +InStruct elf::In; template GdbIndexSection *GdbIndexSection::create(); template GdbIndexSection *GdbIndexSection::create(); diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 30d158a..cd1eb64 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -983,46 +983,48 @@ Defined *addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value, uint64_t Size, InputSectionBase &Section); // Linker generated sections which can be used as inputs. -struct InX { - static InputSection *ARMAttributes; - static BssSection *Bss; - static BssSection *BssRelRo; - static BuildIdSection *BuildId; - static EhFrameHeader *EhFrameHdr; - static EhFrameSection *EhFrame; - static SyntheticSection *Dynamic; - static StringTableSection *DynStrTab; - static SymbolTableBaseSection *DynSymTab; - static GnuHashTableSection *GnuHashTab; - static HashTableSection *HashTab; - static InputSection *Interp; - static GdbIndexSection *GdbIndex; - static GotSection *Got; - static GotPltSection *GotPlt; - static IgotPltSection *IgotPlt; - static MipsGotSection *MipsGot; - static MipsRldMapSection *MipsRldMap; - static PltSection *Plt; - static PltSection *Iplt; - static RelocationBaseSection *RelaDyn; - static RelrBaseSection *RelrDyn; - static RelocationBaseSection *RelaPlt; - static RelocationBaseSection *RelaIplt; - static StringTableSection *ShStrTab; - static StringTableSection *StrTab; - static SymbolTableBaseSection *SymTab; - static SymtabShndxSection* SymTabShndx; +struct InStruct { + InputSection *ARMAttributes; + BssSection *Bss; + BssSection *BssRelRo; + BuildIdSection *BuildId; + EhFrameHeader *EhFrameHdr; + EhFrameSection *EhFrame; + SyntheticSection *Dynamic; + StringTableSection *DynStrTab; + SymbolTableBaseSection *DynSymTab; + GnuHashTableSection *GnuHashTab; + HashTableSection *HashTab; + InputSection *Interp; + GdbIndexSection *GdbIndex; + GotSection *Got; + GotPltSection *GotPlt; + IgotPltSection *IgotPlt; + MipsGotSection *MipsGot; + MipsRldMapSection *MipsRldMap; + PltSection *Plt; + PltSection *Iplt; + RelocationBaseSection *RelaDyn; + RelrBaseSection *RelrDyn; + RelocationBaseSection *RelaPlt; + RelocationBaseSection *RelaIplt; + StringTableSection *ShStrTab; + StringTableSection *StrTab; + SymbolTableBaseSection *SymTab; + SymtabShndxSection *SymTabShndx; }; -template struct In { +extern InStruct In; + +template struct InX { static VersionDefinitionSection *VerDef; static VersionTableSection *VerSym; static VersionNeedSection *VerNeed; }; -template VersionDefinitionSection *In::VerDef; -template VersionTableSection *In::VerSym; -template VersionNeedSection *In::VerNeed; +template VersionDefinitionSection *InX::VerDef; +template VersionTableSection *InX::VerSym; +template VersionNeedSection *InX::VerNeed; } // namespace elf } // namespace lld diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index b3ea81b..be7aa93 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -156,7 +156,7 @@ template static void combineEhFrameSections() { if (!ES || !ES->Live) continue; - InX::EhFrame->addSection(ES); + In.EhFrame->addSection(ES); S = nullptr; } @@ -260,54 +260,52 @@ template static void createSyntheticSections() { auto Add = [](InputSectionBase *Sec) { InputSections.push_back(Sec); }; - InX::DynStrTab = make(".dynstr", true); - InX::Dynamic = make>(); + In.DynStrTab = make(".dynstr", true); + In.Dynamic = make>(); if (Config->AndroidPackDynRelocs) { - InX::RelaDyn = make>( + In.RelaDyn = make>( Config->IsRela ? ".rela.dyn" : ".rel.dyn"); } else { - InX::RelaDyn = make>( + In.RelaDyn = make>( Config->IsRela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc); } - InX::ShStrTab = make(".shstrtab", false); + In.ShStrTab = make(".shstrtab", false); Out::ProgramHeaders = make("", 0, SHF_ALLOC); Out::ProgramHeaders->Alignment = Config->Wordsize; if (needsInterpSection()) { - InX::Interp = createInterpSection(); - Add(InX::Interp); - } else { - InX::Interp = nullptr; + In.Interp = createInterpSection(); + Add(In.Interp); } if (Config->Strip != StripPolicy::All) { - InX::StrTab = make(".strtab", false); - InX::SymTab = make>(*InX::StrTab); - InX::SymTabShndx = make(); + In.StrTab = make(".strtab", false); + In.SymTab = make>(*In.StrTab); + In.SymTabShndx = make(); } if (Config->BuildId != BuildIdKind::None) { - InX::BuildId = make(); - Add(InX::BuildId); + In.BuildId = make(); + Add(In.BuildId); } - InX::Bss = make(".bss", 0, 1); - Add(InX::Bss); + In.Bss = make(".bss", 0, 1); + Add(In.Bss); // If there is a SECTIONS command and a .data.rel.ro section name use name // .data.rel.ro.bss so that we match in the .data.rel.ro output section. // This makes sure our relro is contiguous. bool HasDataRelRo = Script->HasSectionsCommand && findSection(".data.rel.ro"); - InX::BssRelRo = + In.BssRelRo = make(HasDataRelRo ? ".data.rel.ro.bss" : ".bss.rel.ro", 0, 1); - Add(InX::BssRelRo); + Add(In.BssRelRo); // Add MIPS-specific sections. if (Config->EMachine == EM_MIPS) { if (!Config->Shared && Config->HasDynSymTab) { - InX::MipsRldMap = make(); - Add(InX::MipsRldMap); + In.MipsRldMap = make(); + Add(In.MipsRldMap); } if (auto *Sec = MipsAbiFlagsSection::create()) Add(Sec); @@ -318,65 +316,65 @@ template static void createSyntheticSections() { } if (Config->HasDynSymTab) { - InX::DynSymTab = make>(*InX::DynStrTab); - Add(InX::DynSymTab); + In.DynSymTab = make>(*In.DynStrTab); + Add(In.DynSymTab); - In::VerSym = make>(); - Add(In::VerSym); + InX::VerSym = make>(); + Add(InX::VerSym); if (!Config->VersionDefinitions.empty()) { - In::VerDef = make>(); - Add(In::VerDef); + InX::VerDef = make>(); + Add(InX::VerDef); } - In::VerNeed = make>(); - Add(In::VerNeed); + InX::VerNeed = make>(); + Add(InX::VerNeed); if (Config->GnuHash) { - InX::GnuHashTab = make(); - Add(InX::GnuHashTab); + In.GnuHashTab = make(); + Add(In.GnuHashTab); } if (Config->SysvHash) { - InX::HashTab = make(); - Add(InX::HashTab); + In.HashTab = make(); + Add(In.HashTab); } - Add(InX::Dynamic); - Add(InX::DynStrTab); - Add(InX::RelaDyn); + Add(In.Dynamic); + Add(In.DynStrTab); + Add(In.RelaDyn); } if (Config->RelrPackDynRelocs) { - InX::RelrDyn = make>(); - Add(InX::RelrDyn); + In.RelrDyn = make>(); + Add(In.RelrDyn); } // Add .got. MIPS' .got is so different from the other archs, // it has its own class. if (Config->EMachine == EM_MIPS) { - InX::MipsGot = make(); - Add(InX::MipsGot); + In.MipsGot = make(); + Add(In.MipsGot); } else { - InX::Got = make(); - Add(InX::Got); + In.Got = make(); + Add(In.Got); } - InX::GotPlt = make(); - Add(InX::GotPlt); - InX::IgotPlt = make(); - Add(InX::IgotPlt); + In.GotPlt = make(); + Add(In.GotPlt); + In.IgotPlt = make(); + Add(In.IgotPlt); if (Config->GdbIndex) { - InX::GdbIndex = GdbIndexSection::create(); - Add(InX::GdbIndex); + In.GdbIndex = GdbIndexSection::create(); + Add(In.GdbIndex); } // We always need to add rel[a].plt to output if it has entries. // Even for static linking it can contain R_[*]_IRELATIVE relocations. - InX::RelaPlt = make>( + In.RelaPlt = make>( Config->IsRela ? ".rela.plt" : ".rel.plt", false /*Sort*/); - Add(InX::RelaPlt); + Add(In.RelaPlt); // The RelaIplt immediately follows .rel.plt (.rel.dyn for ARM) to ensure // that the IRelative relocations are processed last by the dynamic loader. @@ -384,17 +382,17 @@ template static void createSyntheticSections() { // packing is enabled because that would cause a section type mismatch. // However, because the Android dynamic loader reads .rel.plt after .rel.dyn, // we can get the desired behaviour by placing the iplt section in .rel.plt. - InX::RelaIplt = make>( + In.RelaIplt = make>( (Config->EMachine == EM_ARM && !Config->AndroidPackDynRelocs) ? ".rel.dyn" - : InX::RelaPlt->Name, + : In.RelaPlt->Name, false /*Sort*/); - Add(InX::RelaIplt); + Add(In.RelaIplt); - InX::Plt = make(false); - Add(InX::Plt); - InX::Iplt = make(true); - Add(InX::Iplt); + In.Plt = make(false); + Add(In.Plt); + In.Iplt = make(true); + Add(In.Iplt); // .note.GNU-stack is always added when we are creating a re-linkable // object file. Other linkers are using the presence of this marker @@ -406,20 +404,20 @@ template static void createSyntheticSections() { if (!Config->Relocatable) { if (Config->EhFrameHdr) { - InX::EhFrameHdr = make(); - Add(InX::EhFrameHdr); + In.EhFrameHdr = make(); + Add(In.EhFrameHdr); } - InX::EhFrame = make(); - Add(InX::EhFrame); + In.EhFrame = make(); + Add(In.EhFrame); } - if (InX::SymTab) - Add(InX::SymTab); - if (InX::SymTabShndx) - Add(InX::SymTabShndx); - Add(InX::ShStrTab); - if (InX::StrTab) - Add(InX::StrTab); + if (In.SymTab) + Add(In.SymTab); + if (In.SymTabShndx) + Add(In.SymTabShndx); + Add(In.ShStrTab); + if (In.StrTab) + Add(In.StrTab); if (Config->EMachine == EM_ARM && !Config->Relocatable) // Add a sentinel to terminate .ARM.exidx. It helps an unwinder @@ -567,7 +565,7 @@ static bool includeInSymtab(const Symbol &B) { // Local symbols are not in the linker's symbol table. This function scans // each object file's symbol table to copy local symbols to the output. template void Writer::copyLocalSymbols() { - if (!InX::SymTab) + if (!In.SymTab) return; for (InputFile *File : ObjectFiles) { ObjFile *F = cast>(File); @@ -586,7 +584,7 @@ template void Writer::copyLocalSymbols() { SectionBase *Sec = DR->Section; if (!shouldKeepInSymtab(Sec, B->getName(), *B)) continue; - InX::SymTab->addSymbol(B); + In.SymTab->addSymbol(B); } } } @@ -622,7 +620,7 @@ template void Writer::addSectionSymbols() { auto *Sym = make(IS->File, "", STB_LOCAL, /*StOther=*/0, STT_SECTION, /*Value=*/0, /*Size=*/0, IS); - InX::SymTab->addSymbol(Sym); + In.SymTab->addSymbol(Sym); } } @@ -667,7 +665,7 @@ static bool isRelroSection(const OutputSection *Sec) { // .got contains pointers to external symbols. They are resolved by // the dynamic linker when a module is loaded into memory, and after // that they are not expected to change. So, it can be in RELRO. - if (InX::Got && Sec == InX::Got->getParent()) + if (In.Got && Sec == In.Got->getParent()) return true; if (Sec->Name.equals(".toc")) @@ -677,13 +675,13 @@ static bool isRelroSection(const OutputSection *Sec) { // by default resolved lazily, so we usually cannot put it into RELRO. // However, if "-z now" is given, the lazy symbol resolution is // disabled, which enables us to put it into RELRO. - if (Sec == InX::GotPlt->getParent()) + if (Sec == In.GotPlt->getParent()) return Config->ZNow; // .dynamic section contains data for the dynamic linker, and // there's no need to write to it at runtime, so it's better to put // it into RELRO. - if (Sec == InX::Dynamic->getParent()) + if (Sec == In.Dynamic->getParent()) return true; // Sections with some special names are put into RELRO. This is a @@ -882,11 +880,11 @@ template void Writer::addRelIpltSymbols() { if (needsInterpSection()) return; StringRef S = Config->IsRela ? "__rela_iplt_start" : "__rel_iplt_start"; - addOptionalRegular(S, InX::RelaIplt, 0, STV_HIDDEN, STB_WEAK); + addOptionalRegular(S, In.RelaIplt, 0, STV_HIDDEN, STB_WEAK); S = Config->IsRela ? "__rela_iplt_end" : "__rel_iplt_end"; ElfSym::RelaIpltEnd = - addOptionalRegular(S, InX::RelaIplt, 0, STV_HIDDEN, STB_WEAK); + addOptionalRegular(S, In.RelaIplt, 0, STV_HIDDEN, STB_WEAK); } template @@ -900,7 +898,7 @@ void Writer::forEachRelSec( for (InputSectionBase *IS : InputSections) if (IS->Live && isa(IS) && (IS->Flags & SHF_ALLOC)) Fn(*IS); - for (EhInputSection *ES : InX::EhFrame->Sections) + for (EhInputSection *ES : In.EhFrame->Sections) Fn(*ES); } @@ -913,15 +911,15 @@ template void Writer::setReservedSymbolSections() { if (ElfSym::GlobalOffsetTable) { // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention usually // to the start of the .got or .got.plt section. - InputSection *GotSection = InX::GotPlt; + InputSection *GotSection = In.GotPlt; if (!Target->GotBaseSymInGotPlt) - GotSection = InX::MipsGot ? cast(InX::MipsGot) - : cast(InX::Got); + GotSection = In.MipsGot ? cast(In.MipsGot) + : cast(In.Got); ElfSym::GlobalOffsetTable->Section = GotSection; } if (ElfSym::RelaIpltEnd) - ElfSym::RelaIpltEnd->Value = InX::RelaIplt->getSize(); + ElfSym::RelaIpltEnd->Value = In.RelaIplt->getSize(); PhdrEntry *Last = nullptr; PhdrEntry *LastRO = nullptr; @@ -1552,9 +1550,9 @@ template void Writer::finalizeSections() { // It should be okay as no one seems to care about the type. // Even the author of gold doesn't remember why gold behaves that way. // https://sourceware.org/ml/binutils/2002-03/msg00360.html - if (InX::DynSymTab) + if (In.DynSymTab) Symtab->addRegular("_DYNAMIC", STV_HIDDEN, STT_NOTYPE, 0 /*Value*/, - /*Size=*/0, STB_WEAK, InX::Dynamic, + /*Size=*/0, STB_WEAK, In.Dynamic, /*File=*/nullptr); // Define __rel[a]_iplt_{start,end} symbols if needed. @@ -1572,7 +1570,7 @@ template void Writer::finalizeSections() { // This responsible for splitting up .eh_frame section into // pieces. The relocation scan uses those pieces, so this has to be // earlier. - applySynthetic({InX::EhFrame}, + applySynthetic({In.EhFrame}, [](SyntheticSection *SS) { SS->finalizeContents(); }); for (Symbol *S : Symtab->getSymbols()) @@ -1583,24 +1581,24 @@ template void Writer::finalizeSections() { if (!Config->Relocatable) forEachRelSec(scanRelocations); - if (InX::Plt && !InX::Plt->empty()) - InX::Plt->addSymbols(); - if (InX::Iplt && !InX::Iplt->empty()) - InX::Iplt->addSymbols(); + if (In.Plt && !In.Plt->empty()) + In.Plt->addSymbols(); + if (In.Iplt && !In.Iplt->empty()) + In.Iplt->addSymbols(); // Now that we have defined all possible global symbols including linker- // synthesized ones. Visit all symbols to give the finishing touches. for (Symbol *Sym : Symtab->getSymbols()) { if (!includeInSymtab(*Sym)) continue; - if (InX::SymTab) - InX::SymTab->addSymbol(Sym); + if (In.SymTab) + In.SymTab->addSymbol(Sym); - if (InX::DynSymTab && Sym->includeInDynsym()) { - InX::DynSymTab->addSymbol(Sym); + if (In.DynSymTab && Sym->includeInDynsym()) { + In.DynSymTab->addSymbol(Sym); if (auto *File = dyn_cast_or_null>(Sym->File)) if (File->IsNeeded && !Sym->isUndefined()) - In::VerNeed->addSymbol(Sym); + InX::VerNeed->addSymbol(Sym); } } @@ -1608,8 +1606,8 @@ template void Writer::finalizeSections() { if (errorCount()) return; - if (InX::MipsGot) - InX::MipsGot->build(); + if (In.MipsGot) + In.MipsGot->build(); removeUnusedSyntheticSections(); @@ -1645,7 +1643,7 @@ template void Writer::finalizeSections() { unsigned I = 1; for (OutputSection *Sec : OutputSections) { Sec->SectionIndex = I++; - Sec->ShName = InX::ShStrTab->addString(Sec->Name); + Sec->ShName = In.ShStrTab->addString(Sec->Name); } // Binary and relocatable output does not have PHDRS. @@ -1669,14 +1667,31 @@ template void Writer::finalizeSections() { // Dynamic section must be the last one in this list and dynamic // symbol table section (DynSymTab) must be the first one. - applySynthetic( - {InX::DynSymTab, InX::Bss, InX::BssRelRo, InX::GnuHashTab, - InX::HashTab, InX::SymTabShndx, InX::ShStrTab, InX::StrTab, - In::VerDef, InX::DynStrTab, InX::Got, InX::MipsGot, - InX::IgotPlt, InX::GotPlt, InX::RelaDyn, InX::RelrDyn, - InX::RelaIplt, InX::RelaPlt, InX::Plt, InX::Iplt, - InX::EhFrameHdr, In::VerSym, In::VerNeed, InX::Dynamic}, - [](SyntheticSection *SS) { SS->finalizeContents(); }); + applySynthetic({In.DynSymTab, + In.Bss, + In.BssRelRo, + In.GnuHashTab, + In.HashTab, + In.SymTabShndx, + In.ShStrTab, + In.StrTab, + InX::VerDef, + In.DynStrTab, + In.Got, + In.MipsGot, + In.IgotPlt, + In.GotPlt, + In.RelaDyn, + In.RelrDyn, + In.RelaIplt, + In.RelaPlt, + In.Plt, + In.Iplt, + In.EhFrameHdr, + InX::VerSym, + InX::VerNeed, + In.Dynamic}, + [](SyntheticSection *SS) { SS->finalizeContents(); }); if (!Script->HasSectionsCommand && !Config->Relocatable) fixSectionAlignments(); @@ -1705,16 +1720,16 @@ template void Writer::finalizeSections() { Script->assignAddresses(); Changed |= A64P.createFixes(); } - if (InX::MipsGot) - InX::MipsGot->updateAllocSize(); - Changed |= InX::RelaDyn->updateAllocSize(); - if (InX::RelrDyn) - Changed |= InX::RelrDyn->updateAllocSize(); + if (In.MipsGot) + In.MipsGot->updateAllocSize(); + Changed |= In.RelaDyn->updateAllocSize(); + if (In.RelrDyn) + Changed |= In.RelrDyn->updateAllocSize(); } while (Changed); } // createThunks may have added local symbols to the static symbol table - applySynthetic({InX::SymTab}, + applySynthetic({In.SymTab}, [](SyntheticSection *SS) { SS->finalizeContents(); }); // Fill other section headers. The dynamic table is finalized @@ -1860,9 +1875,9 @@ template std::vector Writer::createPhdrs() { Ret.push_back(TlsHdr); // Add an entry for .dynamic. - if (InX::DynSymTab) - AddHdr(PT_DYNAMIC, InX::Dynamic->getParent()->getPhdrFlags()) - ->add(InX::Dynamic->getParent()); + if (In.DynSymTab) + AddHdr(PT_DYNAMIC, In.Dynamic->getParent()->getPhdrFlags()) + ->add(In.Dynamic->getParent()); // PT_GNU_RELRO includes all sections that should be marked as // read-only by dynamic linker after proccessing relocations. @@ -1890,10 +1905,10 @@ template std::vector Writer::createPhdrs() { Ret.push_back(RelRo); // PT_GNU_EH_FRAME is a special section pointing on .eh_frame_hdr. - if (!InX::EhFrame->empty() && InX::EhFrameHdr && InX::EhFrame->getParent() && - InX::EhFrameHdr->getParent()) - AddHdr(PT_GNU_EH_FRAME, InX::EhFrameHdr->getParent()->getPhdrFlags()) - ->add(InX::EhFrameHdr->getParent()); + if (!In.EhFrame->empty() && In.EhFrameHdr && In.EhFrame->getParent() && + In.EhFrameHdr->getParent()) + AddHdr(PT_GNU_EH_FRAME, In.EhFrameHdr->getParent()->getPhdrFlags()) + ->add(In.EhFrameHdr->getParent()); // PT_OPENBSD_RANDOMIZE is an OpenBSD-specific feature. That makes // the dynamic linker fill the segment with random data. @@ -2306,7 +2321,7 @@ template void Writer::writeHeader() { else EHdr->e_shnum = Num; - uint32_t StrTabIndex = InX::ShStrTab->getParent()->SectionIndex; + uint32_t StrTabIndex = In.ShStrTab->getParent()->SectionIndex; if (StrTabIndex >= SHN_LORESERVE) { SHdrs->sh_link = StrTabIndex; EHdr->e_shstrndx = SHN_XINDEX; @@ -2385,8 +2400,8 @@ template void Writer::writeSections() { uint8_t *Buf = Buffer->getBufferStart(); OutputSection *EhFrameHdr = nullptr; - if (InX::EhFrameHdr && !InX::EhFrameHdr->empty()) - EhFrameHdr = InX::EhFrameHdr->getParent(); + if (In.EhFrameHdr && !In.EhFrameHdr->empty()) + EhFrameHdr = In.EhFrameHdr->getParent(); // In -r or -emit-relocs mode, write the relocation sections first as in // ELf_Rel targets we might find out that we need to modify the relocated @@ -2406,13 +2421,13 @@ template void Writer::writeSections() { } template void Writer::writeBuildId() { - if (!InX::BuildId || !InX::BuildId->getParent()) + if (!In.BuildId || !In.BuildId->getParent()) return; // Compute a hash of all sections of the output file. uint8_t *Start = Buffer->getBufferStart(); uint8_t *End = Start + FileSize; - InX::BuildId->writeBuildId({Start, End}); + In.BuildId->writeBuildId({Start, End}); } template void elf::writeResult();