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
This commit is contained in:
Rui Ueyama 2018-09-25 19:26:58 +00:00
parent 10c11b867a
commit 4e247522ac
17 changed files with 388 additions and 396 deletions

View File

@ -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);

View File

@ -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);

View File

@ -185,7 +185,7 @@ template <class ELFT> RelType MIPS<ELFT>::getDynRel(RelType Type) const {
template <class ELFT>
void MIPS<ELFT>::writeGotPlt(uint8_t *Buf, const Symbol &) const {
uint64_t VA = InX::Plt->getVA();
uint64_t VA = In.Plt->getVA();
if (isMicroMips())
VA |= 1;
write32<ELFT::TargetEndianness>(Buf, VA);
@ -239,8 +239,8 @@ static void writeMicroRelocation16(uint8_t *Loc, uint64_t V, uint8_t BitsSize,
template <class ELFT> void MIPS<ELFT>::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 <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *Buf) const {
write32<E>(Buf + 24, JalrInst); // jalr.hb $25 or jalr $25
write32<E>(Buf + 28, 0x2718fffe); // subu $24, $24, 2
uint64_t GotPlt = InX::GotPlt->getVA();
uint64_t GotPlt = In.GotPlt->getVA();
writeValue<E>(Buf, GotPlt + 0x8000, 16, 16);
writeValue<E>(Buf + 4, GotPlt, 16, 0);
writeValue<E>(Buf + 8, GotPlt, 16, 0);

View File

@ -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);
}

View File

@ -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);
}

View File

@ -124,7 +124,7 @@ template <class ELFT> void X86_64<ELFT>::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 <class ELFT>
@ -140,8 +140,8 @@ template <class ELFT> void X86_64<ELFT>::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 <class ELFT> void Retpoline<ELFT>::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);
}

View File

@ -85,7 +85,6 @@ bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly,
InputSections.clear();
OutputSections.clear();
Tar = nullptr;
BinaryFiles.clear();
BitcodeFiles.clear();
ObjectFiles.clear();
@ -95,6 +94,10 @@ bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly,
Driver = make<LinkerDriver>();
Script = make<LinkerScript>();
Symtab = make<SymbolTable>();
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 <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
Target = getTarget();
InX<ELFT>::VerDef = nullptr;
InX<ELFT>::VerSym = nullptr;
InX<ELFT>::VerNeed = nullptr;
Config->MaxPageSize = getMaxPageSize(Args);
Config->ImageBase = getImageBase(Args);

View File

@ -620,9 +620,9 @@ InputSectionBase *ObjFile<ELFT>::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<InputSection>(*this, Sec, Name);
return InX::ARMAttributes;
if (In.ARMAttributes == nullptr) {
In.ARMAttributes = make<InputSection>(*this, Sec, Name);
return In.ARMAttributes;
}
return &InputSection::Discarded;
}

View File

@ -356,7 +356,7 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> 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");
}

View File

@ -415,18 +415,18 @@ LinkerScript::computeInputSections(const InputSectionDescription *Cmd) {
void LinkerScript::discard(ArrayRef<InputSection *> 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;

View File

@ -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<InputSectionDescription>(Base)) {
for (InputSection *IS : ISD->Sections) {
if (IS == InX::EhFrame) {
if (IS == In.EhFrame) {
printEhFrame(OS, OSec);
continue;
}

View File

@ -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<ELFT> *Obj = Section->getFile<ELFT>();
ArrayRef<Symbol *> Symbols = Obj->getSymbols();
OS->Info = InX::SymTab->getSymbolIndex(Symbols[Section->Info]);
OS->Info = In.SymTab->getSymbolIndex(Symbols[Section->Info]);
}
template <class ELFT> void OutputSection::finalize() {
@ -308,7 +308,7 @@ template <class ELFT> void OutputSection::finalize() {
if (isa<SyntheticSection>(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();

View File

@ -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<R_TLSDESC, R_TLSDESC_PAGE, R_TLSDESC_CALL>(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<R_TLSDESC, R_TLSDESC_PAGE, R_TLSDESC_CALL, R_TLSGD_GOT,
R_TLSGD_GOT_FROM_END, R_TLSGD_PC>(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 <class ELFT> static void addCopyRelSymbol(SharedSymbol &SS) {
BssSection *Sec = make<BssSection>(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 <class ELFT> static void addCopyRelSymbol(SharedSymbol &SS) {
for (SharedSymbol *Sym : getSymbolsAt<ELFT>(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 <class ELFT, class GotPltSection>
@ -740,7 +740,7 @@ static void addPltEntry(PltSection *Plt, GotPltSection *GotPlt,
}
template <class ELFT> 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 <class ELFT> 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<ELFT>(InX::Plt, InX::GotPlt, InX::RelaPlt, Target->PltRel,
Sym);
addPltEntry<ELFT>(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<R_GOTONLY_PC, R_GOTONLY_PC_FROM_END, R_GOTREL,
R_GOTREL_FROM_END, R_PPC_TOC>(Expr))
InX::Got->HasGotOffRel = true;
In.Got->HasGotOffRel = true;
// Read an addend.
int64_t Addend = computeAddend<ELFT>(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<ELFT>(InX::Iplt, InX::IgotPlt, InX::RelaIplt,
Target->IRelativeRel, Sym);
else
addPltEntry<ELFT>(InX::Plt, InX::GotPlt, InX::RelaPlt, Target->PltRel,
addPltEntry<ELFT>(In.Iplt, In.IgotPlt, In.RelaIplt, Target->IRelativeRel,
Sym);
else
addPltEntry<ELFT>(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<ELFT>(Sym);
}

View File

@ -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 {

View File

@ -154,7 +154,7 @@ template <class ELFT> void MipsOptionsSection<ELFT>::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<ELFT>::MipsReginfoSection(Elf_Mips_RegInfo Reginfo)
template <class ELFT> void MipsReginfoSection<ELFT>::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<Defined>(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::FdeData> EhFrameSection::getFdeData() const {
uint8_t *Buf = getParent()->Loc + OutSecOff;
std::vector<FdeData> 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 <class ELFT> 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<Symbol *, size_t> &P : Got.DynTlsSymbols) {
Symbol *S = P.first;
@ -946,7 +946,7 @@ template <class ELFT> 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 <class ELFT> 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 <class ELFT> void MipsGotSection::build() {
// Dynamic relocations for "global" entries.
for (const std::pair<Symbol *, size_t> &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 <class ELFT> 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<GotEntry, size_t> &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<ELFT>::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<ELFT> *F = cast<SharedFile<ELFT>>(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 <class ELFT>
@ -1302,10 +1302,10 @@ template <class ELFT> void DynamicSection<ELFT>::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 <class ELFT> void DynamicSection<ELFT>::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 <class ELFT> void DynamicSection<ELFT>::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 <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
if (B->isDefined())
addSym(DT_FINI, B);
bool HasVerNeed = In<ELFT>::VerNeed->getNeedNum() != 0;
if (HasVerNeed || In<ELFT>::VerDef)
addInSec(DT_VERSYM, In<ELFT>::VerSym);
if (In<ELFT>::VerDef) {
addInSec(DT_VERDEF, In<ELFT>::VerDef);
bool HasVerNeed = InX<ELFT>::VerNeed->getNeedNum() != 0;
if (HasVerNeed || InX<ELFT>::VerDef)
addInSec(DT_VERSYM, InX<ELFT>::VerSym);
if (InX<ELFT>::VerDef) {
addInSec(DT_VERDEF, InX<ELFT>::VerDef);
addInt(DT_VERDEFNUM, getVerDefNum());
}
if (HasVerNeed) {
addInSec(DT_VERNEED, In<ELFT>::VerNeed);
addInt(DT_VERNEEDNUM, In<ELFT>::VerNeed->getNeedNum());
addInSec(DT_VERNEED, InX<ELFT>::VerNeed);
addInt(DT_VERNEEDNUM, InX<ELFT>::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<uint32_t *>(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 <class ELFT> 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<FdeData> Fdes = InX::EhFrame->getFdeData();
std::vector<FdeData> 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 <class ELFT>
VersionDefinitionSection<ELFT>::VersionDefinitionSection()
@ -2639,11 +2639,11 @@ static StringRef getFileDefName() {
}
template <class ELFT> void VersionDefinitionSection<ELFT>::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<ELFT>::VersionTableSection()
template <class ELFT> void VersionTableSection<ELFT>::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 <class ELFT> size_t VersionTableSection<ELFT>::getSize() const {
return sizeof(Elf_Versym) * (InX::DynSymTab->getSymbols().size() + 1);
return sizeof(Elf_Versym) * (In.DynSymTab->getSymbols().size() + 1);
}
template <class ELFT> void VersionTableSection<ELFT>::writeTo(uint8_t *Buf) {
auto *OutVersym = reinterpret_cast<Elf_Versym *>(Buf) + 1;
for (const SymbolTableEntry &S : InX::DynSymTab->getSymbols()) {
for (const SymbolTableEntry &S : In.DynSymTab->getSymbols()) {
OutVersym->vs_index = S.Sym->VersionId;
++OutVersym;
}
}
template <class ELFT> bool VersionTableSection<ELFT>::empty() const {
return !In<ELFT>::VerDef && In<ELFT>::VerNeed->empty();
return !InX<ELFT>::VerDef && InX<ELFT>::VerNeed->empty();
}
template <class ELFT>
@ -2736,7 +2736,7 @@ template <class ELFT> void VersionNeedSection<ELFT>::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<ELFT>::NeededVer &NV = File.VerdefMap[Ver];
@ -2744,8 +2744,8 @@ template <class ELFT> void VersionNeedSection<ELFT>::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 <class ELFT> void VersionNeedSection<ELFT>::writeTo(uint8_t *Buf) {
}
template <class ELFT> void VersionNeedSection<ELFT>::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<ELF32LE>();
template GdbIndexSection *GdbIndexSection::create<ELF32BE>();

View File

@ -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 <class ELFT> struct In {
extern InStruct In;
template <class ELFT> struct InX {
static VersionDefinitionSection<ELFT> *VerDef;
static VersionTableSection<ELFT> *VerSym;
static VersionNeedSection<ELFT> *VerNeed;
};
template <class ELFT> VersionDefinitionSection<ELFT> *In<ELFT>::VerDef;
template <class ELFT> VersionTableSection<ELFT> *In<ELFT>::VerSym;
template <class ELFT> VersionNeedSection<ELFT> *In<ELFT>::VerNeed;
template <class ELFT> VersionDefinitionSection<ELFT> *InX<ELFT>::VerDef;
template <class ELFT> VersionTableSection<ELFT> *InX<ELFT>::VerSym;
template <class ELFT> VersionNeedSection<ELFT> *InX<ELFT>::VerNeed;
} // namespace elf
} // namespace lld

View File

@ -156,7 +156,7 @@ template <class ELFT> static void combineEhFrameSections() {
if (!ES || !ES->Live)
continue;
InX::EhFrame->addSection<ELFT>(ES);
In.EhFrame->addSection<ELFT>(ES);
S = nullptr;
}
@ -260,54 +260,52 @@ template <class ELFT> static void createSyntheticSections() {
auto Add = [](InputSectionBase *Sec) { InputSections.push_back(Sec); };
InX::DynStrTab = make<StringTableSection>(".dynstr", true);
InX::Dynamic = make<DynamicSection<ELFT>>();
In.DynStrTab = make<StringTableSection>(".dynstr", true);
In.Dynamic = make<DynamicSection<ELFT>>();
if (Config->AndroidPackDynRelocs) {
InX::RelaDyn = make<AndroidPackedRelocationSection<ELFT>>(
In.RelaDyn = make<AndroidPackedRelocationSection<ELFT>>(
Config->IsRela ? ".rela.dyn" : ".rel.dyn");
} else {
InX::RelaDyn = make<RelocationSection<ELFT>>(
In.RelaDyn = make<RelocationSection<ELFT>>(
Config->IsRela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc);
}
InX::ShStrTab = make<StringTableSection>(".shstrtab", false);
In.ShStrTab = make<StringTableSection>(".shstrtab", false);
Out::ProgramHeaders = make<OutputSection>("", 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<StringTableSection>(".strtab", false);
InX::SymTab = make<SymbolTableSection<ELFT>>(*InX::StrTab);
InX::SymTabShndx = make<SymtabShndxSection>();
In.StrTab = make<StringTableSection>(".strtab", false);
In.SymTab = make<SymbolTableSection<ELFT>>(*In.StrTab);
In.SymTabShndx = make<SymtabShndxSection>();
}
if (Config->BuildId != BuildIdKind::None) {
InX::BuildId = make<BuildIdSection>();
Add(InX::BuildId);
In.BuildId = make<BuildIdSection>();
Add(In.BuildId);
}
InX::Bss = make<BssSection>(".bss", 0, 1);
Add(InX::Bss);
In.Bss = make<BssSection>(".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<BssSection>(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<MipsRldMapSection>();
Add(InX::MipsRldMap);
In.MipsRldMap = make<MipsRldMapSection>();
Add(In.MipsRldMap);
}
if (auto *Sec = MipsAbiFlagsSection<ELFT>::create())
Add(Sec);
@ -318,65 +316,65 @@ template <class ELFT> static void createSyntheticSections() {
}
if (Config->HasDynSymTab) {
InX::DynSymTab = make<SymbolTableSection<ELFT>>(*InX::DynStrTab);
Add(InX::DynSymTab);
In.DynSymTab = make<SymbolTableSection<ELFT>>(*In.DynStrTab);
Add(In.DynSymTab);
In<ELFT>::VerSym = make<VersionTableSection<ELFT>>();
Add(In<ELFT>::VerSym);
InX<ELFT>::VerSym = make<VersionTableSection<ELFT>>();
Add(InX<ELFT>::VerSym);
if (!Config->VersionDefinitions.empty()) {
In<ELFT>::VerDef = make<VersionDefinitionSection<ELFT>>();
Add(In<ELFT>::VerDef);
InX<ELFT>::VerDef = make<VersionDefinitionSection<ELFT>>();
Add(InX<ELFT>::VerDef);
}
In<ELFT>::VerNeed = make<VersionNeedSection<ELFT>>();
Add(In<ELFT>::VerNeed);
InX<ELFT>::VerNeed = make<VersionNeedSection<ELFT>>();
Add(InX<ELFT>::VerNeed);
if (Config->GnuHash) {
InX::GnuHashTab = make<GnuHashTableSection>();
Add(InX::GnuHashTab);
In.GnuHashTab = make<GnuHashTableSection>();
Add(In.GnuHashTab);
}
if (Config->SysvHash) {
InX::HashTab = make<HashTableSection>();
Add(InX::HashTab);
In.HashTab = make<HashTableSection>();
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<RelrSection<ELFT>>();
Add(InX::RelrDyn);
In.RelrDyn = make<RelrSection<ELFT>>();
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<MipsGotSection>();
Add(InX::MipsGot);
In.MipsGot = make<MipsGotSection>();
Add(In.MipsGot);
} else {
InX::Got = make<GotSection>();
Add(InX::Got);
In.Got = make<GotSection>();
Add(In.Got);
}
InX::GotPlt = make<GotPltSection>();
Add(InX::GotPlt);
InX::IgotPlt = make<IgotPltSection>();
Add(InX::IgotPlt);
In.GotPlt = make<GotPltSection>();
Add(In.GotPlt);
In.IgotPlt = make<IgotPltSection>();
Add(In.IgotPlt);
if (Config->GdbIndex) {
InX::GdbIndex = GdbIndexSection::create<ELFT>();
Add(InX::GdbIndex);
In.GdbIndex = GdbIndexSection::create<ELFT>();
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<RelocationSection<ELFT>>(
In.RelaPlt = make<RelocationSection<ELFT>>(
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 <class ELFT> 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<RelocationSection<ELFT>>(
In.RelaIplt = make<RelocationSection<ELFT>>(
(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<PltSection>(false);
Add(InX::Plt);
InX::Iplt = make<PltSection>(true);
Add(InX::Iplt);
In.Plt = make<PltSection>(false);
Add(In.Plt);
In.Iplt = make<PltSection>(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 <class ELFT> static void createSyntheticSections() {
if (!Config->Relocatable) {
if (Config->EhFrameHdr) {
InX::EhFrameHdr = make<EhFrameHeader>();
Add(InX::EhFrameHdr);
In.EhFrameHdr = make<EhFrameHeader>();
Add(In.EhFrameHdr);
}
InX::EhFrame = make<EhFrameSection>();
Add(InX::EhFrame);
In.EhFrame = make<EhFrameSection>();
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 <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
if (!InX::SymTab)
if (!In.SymTab)
return;
for (InputFile *File : ObjectFiles) {
ObjFile<ELFT> *F = cast<ObjFile<ELFT>>(File);
@ -586,7 +584,7 @@ template <class ELFT> void Writer<ELFT>::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 <class ELFT> void Writer<ELFT>::addSectionSymbols() {
auto *Sym =
make<Defined>(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 <class ELFT> void Writer<ELFT>::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 <class ELFT>
@ -900,7 +898,7 @@ void Writer<ELFT>::forEachRelSec(
for (InputSectionBase *IS : InputSections)
if (IS->Live && isa<InputSection>(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 <class ELFT> void Writer<ELFT>::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<InputSection>(InX::MipsGot)
: cast<InputSection>(InX::Got);
GotSection = In.MipsGot ? cast<InputSection>(In.MipsGot)
: cast<InputSection>(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 <class ELFT> void Writer<ELFT>::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 <class ELFT> void Writer<ELFT>::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 <class ELFT> void Writer<ELFT>::finalizeSections() {
if (!Config->Relocatable)
forEachRelSec(scanRelocations<ELFT>);
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<SharedFile<ELFT>>(Sym->File))
if (File->IsNeeded && !Sym->isUndefined())
In<ELFT>::VerNeed->addSymbol(Sym);
InX<ELFT>::VerNeed->addSymbol(Sym);
}
}
@ -1608,8 +1606,8 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
if (errorCount())
return;
if (InX::MipsGot)
InX::MipsGot->build<ELFT>();
if (In.MipsGot)
In.MipsGot->build<ELFT>();
removeUnusedSyntheticSections();
@ -1645,7 +1643,7 @@ template <class ELFT> void Writer<ELFT>::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 <class ELFT> void Writer<ELFT>::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<ELFT>::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<ELFT>::VerSym, In<ELFT>::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<ELFT>::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<ELFT>::VerSym,
InX<ELFT>::VerNeed,
In.Dynamic},
[](SyntheticSection *SS) { SS->finalizeContents(); });
if (!Script->HasSectionsCommand && !Config->Relocatable)
fixSectionAlignments();
@ -1705,16 +1720,16 @@ template <class ELFT> void Writer<ELFT>::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 <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::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 <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::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 <class ELFT> void Writer<ELFT>::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 <class ELFT> void Writer<ELFT>::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 <class ELFT> void Writer<ELFT>::writeSections() {
}
template <class ELFT> void Writer<ELFT>::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<ELF32LE>();