forked from OSchip/llvm-project
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:
parent
10c11b867a
commit
4e247522ac
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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>();
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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>();
|
||||
|
|
Loading…
Reference in New Issue