forked from OSchip/llvm-project
Revert r297008: [ELF] - Make Bss and BssRelRo sections to be synthetic (#2).
This reverts commit r297008 because it's reported that that change broke AArch64 bots. llvm-svn: 297297
This commit is contained in:
parent
9f495695bb
commit
007c002cb6
|
@ -31,6 +31,8 @@ using namespace lld;
|
|||
using namespace lld::elf;
|
||||
|
||||
uint8_t Out::First;
|
||||
OutputSection *Out::Bss;
|
||||
OutputSection *Out::BssRelRo;
|
||||
OutputSection *Out::Opd;
|
||||
uint8_t *Out::OpdBuf;
|
||||
PhdrEntry *Out::TlsPhdr;
|
||||
|
|
|
@ -98,6 +98,8 @@ public:
|
|||
// until Writer is initialized.
|
||||
struct Out {
|
||||
static uint8_t First;
|
||||
static OutputSection *Bss;
|
||||
static OutputSection *BssRelRo;
|
||||
static OutputSection *Opd;
|
||||
static uint8_t *OpdBuf;
|
||||
static PhdrEntry *TlsPhdr;
|
||||
|
|
|
@ -479,20 +479,23 @@ template <class ELFT> static void addCopyRelSymbol(SharedSymbol *SS) {
|
|||
// See if this symbol is in a read-only segment. If so, preserve the symbol's
|
||||
// memory protection by reserving space in the .bss.rel.ro section.
|
||||
bool IsReadOnly = isReadOnly<ELFT>(SS);
|
||||
BssRelSection<ELFT> *RelSec = IsReadOnly ? In<ELFT>::BssRelRo : In<ELFT>::Bss;
|
||||
uintX_t Off = RelSec->addCopyRelocation(SS->getAlignment<ELFT>(), SymSize);
|
||||
OutputSection *OSec = IsReadOnly ? Out::BssRelRo : Out::Bss;
|
||||
|
||||
// Create a SyntheticSection in Out to hold the .bss and the Copy Reloc.
|
||||
auto *ISec =
|
||||
make<CopyRelSection<ELFT>>(IsReadOnly, SS->getAlignment<ELFT>(), SymSize);
|
||||
OSec->addSection(ISec);
|
||||
|
||||
// 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
|
||||
// interpose any aliases.
|
||||
for (SharedSymbol *Sym : getSymbolsAt<ELFT>(SS)) {
|
||||
Sym->NeedsCopy = true;
|
||||
Sym->Section = ISec;
|
||||
Sym->symbol()->IsUsedInRegularObj = true;
|
||||
replaceBody<DefinedRegular>(Sym->symbol(), Sym->getName(),
|
||||
/*IsLocal=*/false, Sym->StOther, Sym->Type, Off,
|
||||
Sym->getSize<ELFT>(), RelSec, nullptr);
|
||||
}
|
||||
|
||||
In<ELFT>::RelaDyn->addReloc({Target->CopyRel, RelSec, Off, false, SS, 0});
|
||||
In<ELFT>::RelaDyn->addReloc({Target->CopyRel, ISec, 0, false, SS, 0});
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
|
@ -532,12 +535,14 @@ static RelExpr adjustExpr(const elf::ObjectFile<ELFT> &File, SymbolBody &Body,
|
|||
if (Body.isObject()) {
|
||||
// Produce a copy relocation.
|
||||
auto *B = cast<SharedSymbol>(&Body);
|
||||
if (Config->ZNocopyreloc)
|
||||
error(S.getLocation<ELFT>(RelOff) + ": unresolvable relocation " +
|
||||
toString(Type) + " against symbol '" + toString(*B) +
|
||||
"'; recompile with -fPIC or remove '-z nocopyreloc'");
|
||||
if (!B->NeedsCopy) {
|
||||
if (Config->ZNocopyreloc)
|
||||
error(S.getLocation<ELFT>(RelOff) + ": unresolvable relocation " +
|
||||
toString(Type) + " against symbol '" + toString(*B) +
|
||||
"'; recompile with -fPIC or remove '-z nocopyreloc'");
|
||||
|
||||
addCopyRelSymbol<ELFT>(B);
|
||||
addCopyRelSymbol<ELFT>(B);
|
||||
}
|
||||
return Expr;
|
||||
}
|
||||
if (Body.isFunc()) {
|
||||
|
|
|
@ -112,10 +112,14 @@ static typename ELFT::uint getSymVA(const SymbolBody &Body, int64_t &Addend) {
|
|||
return 0;
|
||||
return In<ELFT>::Common->OutSec->Addr + In<ELFT>::Common->OutSecOff +
|
||||
cast<DefinedCommon>(Body).Offset;
|
||||
case SymbolBody::SharedKind:
|
||||
if (cast<SharedSymbol>(Body).NeedsPltAddr)
|
||||
case SymbolBody::SharedKind: {
|
||||
auto &SS = cast<SharedSymbol>(Body);
|
||||
if (SS.NeedsCopy)
|
||||
return SS.Section->OutSec->Addr + SS.Section->OutSecOff;
|
||||
if (SS.NeedsPltAddr)
|
||||
return Body.getPltVA<ELFT>();
|
||||
return 0;
|
||||
}
|
||||
case SymbolBody::UndefinedKind:
|
||||
return 0;
|
||||
case SymbolBody::LazyArchiveKind:
|
||||
|
@ -128,7 +132,7 @@ static typename ELFT::uint getSymVA(const SymbolBody &Body, int64_t &Addend) {
|
|||
|
||||
SymbolBody::SymbolBody(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther,
|
||||
uint8_t Type)
|
||||
: SymbolKind(K), NeedsPltAddr(false), IsLocal(IsLocal),
|
||||
: SymbolKind(K), NeedsCopy(false), NeedsPltAddr(false), IsLocal(IsLocal),
|
||||
IsInGlobalMipsGot(false), Is32BitMipsGot(false), IsInIplt(false),
|
||||
IsInIgot(false), Type(Type), StOther(StOther), Name(Name) {}
|
||||
|
||||
|
@ -139,9 +143,10 @@ bool SymbolBody::isPreemptible() const {
|
|||
return false;
|
||||
|
||||
// Shared symbols resolve to the definition in the DSO. The exceptions are
|
||||
// symbols that needs plt entries (which resolve to that plt entry).
|
||||
// symbols with copy relocations (which resolve to .bss) or preempt plt
|
||||
// entries (which resolve to that plt entry).
|
||||
if (isShared())
|
||||
return !NeedsPltAddr;
|
||||
return !NeedsCopy && !NeedsPltAddr;
|
||||
|
||||
// That's all that can be preempted in a non-DSO.
|
||||
if (!Config->Shared)
|
||||
|
@ -210,8 +215,11 @@ const OutputSection *SymbolBody::getOutputSection() const {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (isa<SharedSymbol>(this))
|
||||
if (auto *S = dyn_cast<SharedSymbol>(this)) {
|
||||
if (S->NeedsCopy)
|
||||
return S->Section->OutSec;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (isa<DefinedCommon>(this)) {
|
||||
if (Config->DefineCommon)
|
||||
|
|
|
@ -102,6 +102,10 @@ protected:
|
|||
const unsigned SymbolKind : 8;
|
||||
|
||||
public:
|
||||
// True if the linker has to generate a copy relocation.
|
||||
// For SharedSymbol only.
|
||||
unsigned NeedsCopy : 1;
|
||||
|
||||
// True the symbol should point to its PLT entry.
|
||||
// For SharedSymbol only.
|
||||
unsigned NeedsPltAddr : 1;
|
||||
|
@ -266,6 +270,9 @@ public:
|
|||
// This field is a pointer to the symbol's version definition.
|
||||
const void *Verdef;
|
||||
|
||||
// Section is significant only when NeedsCopy is true.
|
||||
InputSection *Section = nullptr;
|
||||
|
||||
private:
|
||||
template <class ELFT> const typename ELFT::Sym &getSym() const {
|
||||
return *(const typename ELFT::Sym *)ElfSym;
|
||||
|
|
|
@ -377,17 +377,10 @@ void BuildIdSection<ELFT>::computeHash(
|
|||
}
|
||||
|
||||
template <class ELFT>
|
||||
BssRelSection<ELFT>::BssRelSection(bool RelRo)
|
||||
: SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, 0,
|
||||
RelRo ? ".bss.rel.ro" : ".bss"),
|
||||
Size(0) {}
|
||||
|
||||
template <class ELFT>
|
||||
size_t BssRelSection<ELFT>::addCopyRelocation(uintX_t AddrAlign, size_t Size) {
|
||||
OutSec->updateAlignment(AddrAlign);
|
||||
this->Size = alignTo(this->Size, AddrAlign) + Size;
|
||||
return this->Size - Size;
|
||||
}
|
||||
CopyRelSection<ELFT>::CopyRelSection(bool ReadOnly, uintX_t AddrAlign, size_t S)
|
||||
: SyntheticSection(SHF_ALLOC, SHT_NOBITS, AddrAlign,
|
||||
ReadOnly ? ".bss.rel.ro" : ".bss"),
|
||||
Size(S) {}
|
||||
|
||||
template <class ELFT>
|
||||
void BuildIdSection<ELFT>::writeBuildId(ArrayRef<uint8_t> Buf) {
|
||||
|
@ -2311,10 +2304,10 @@ template class elf::BuildIdSection<ELF32BE>;
|
|||
template class elf::BuildIdSection<ELF64LE>;
|
||||
template class elf::BuildIdSection<ELF64BE>;
|
||||
|
||||
template class elf::BssRelSection<ELF32LE>;
|
||||
template class elf::BssRelSection<ELF32BE>;
|
||||
template class elf::BssRelSection<ELF64LE>;
|
||||
template class elf::BssRelSection<ELF64BE>;
|
||||
template class elf::CopyRelSection<ELF32LE>;
|
||||
template class elf::CopyRelSection<ELF32BE>;
|
||||
template class elf::CopyRelSection<ELF64LE>;
|
||||
template class elf::CopyRelSection<ELF64BE>;
|
||||
|
||||
template class elf::GotSection<ELF32LE>;
|
||||
template class elf::GotSection<ELF32BE>;
|
||||
|
|
|
@ -152,16 +152,14 @@ private:
|
|||
uint8_t *HashBuf;
|
||||
};
|
||||
|
||||
// Section used for storing copy relocations. We create two sections now,
|
||||
// .bss.rel.ro for RelRo case and .bss for regular case.
|
||||
template <class ELFT> class BssRelSection final : public SyntheticSection {
|
||||
// For each copy relocation, we create an instance of this class to
|
||||
// reserve space in .bss or .bss.rel.ro.
|
||||
template <class ELFT> class CopyRelSection final : public SyntheticSection {
|
||||
typedef typename ELFT::uint uintX_t;
|
||||
|
||||
public:
|
||||
BssRelSection(bool RelRo);
|
||||
CopyRelSection(bool ReadOnly, uintX_t AddrAlign, size_t Size);
|
||||
void writeTo(uint8_t *) override {}
|
||||
bool empty() const override { return getSize() == 0; }
|
||||
size_t addCopyRelocation(uintX_t AddrAlign, size_t Size);
|
||||
size_t getSize() const override { return Size; }
|
||||
size_t Size;
|
||||
};
|
||||
|
@ -764,8 +762,6 @@ SymbolBody *addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value,
|
|||
template <class ELFT> struct In {
|
||||
static InputSection *ARMAttributes;
|
||||
static BuildIdSection<ELFT> *BuildId;
|
||||
static BssRelSection<ELFT> *Bss;
|
||||
static BssRelSection<ELFT> *BssRelRo;
|
||||
static InputSection *Common;
|
||||
static DynamicSection<ELFT> *Dynamic;
|
||||
static StringTableSection<ELFT> *DynStrTab;
|
||||
|
@ -795,8 +791,6 @@ template <class ELFT> struct In {
|
|||
};
|
||||
|
||||
template <class ELFT> InputSection *In<ELFT>::ARMAttributes;
|
||||
template <class ELFT> BssRelSection<ELFT> *In<ELFT>::Bss;
|
||||
template <class ELFT> BssRelSection<ELFT> *In<ELFT>::BssRelRo;
|
||||
template <class ELFT> BuildIdSection<ELFT> *In<ELFT>::BuildId;
|
||||
template <class ELFT> InputSection *In<ELFT>::Common;
|
||||
template <class ELFT> DynamicSection<ELFT> *In<ELFT>::Dynamic;
|
||||
|
|
|
@ -111,8 +111,8 @@ StringRef elf::getOutputSectionName(StringRef Name) {
|
|||
}
|
||||
|
||||
for (StringRef V :
|
||||
{".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.rel.ro.",
|
||||
".bss.", ".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.",
|
||||
{".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.",
|
||||
".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.",
|
||||
".gcc_except_table.", ".tdata.", ".ARM.exidx."}) {
|
||||
StringRef Prefix = V.drop_back();
|
||||
if (Name.startswith(V) || Name == Prefix)
|
||||
|
@ -309,6 +309,10 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() {
|
|||
|
||||
auto Add = [](InputSectionBase *Sec) { InputSections.push_back(Sec); };
|
||||
|
||||
// Create singleton output sections.
|
||||
Out::Bss = make<OutputSection>(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
|
||||
Out::BssRelRo =
|
||||
make<OutputSection>(".bss.rel.ro", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
|
||||
In<ELFT>::DynStrTab = make<StringTableSection<ELFT>>(".dynstr", true);
|
||||
In<ELFT>::Dynamic = make<DynamicSection<ELFT>>();
|
||||
In<ELFT>::RelaDyn = make<RelocationSection<ELFT>>(
|
||||
|
@ -346,11 +350,6 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() {
|
|||
Add(Common);
|
||||
}
|
||||
|
||||
In<ELFT>::Bss = make<BssRelSection<ELFT>>(false /*RelRo*/);
|
||||
Add(In<ELFT>::Bss);
|
||||
In<ELFT>::BssRelRo = make<BssRelSection<ELFT>>(true /*RelRo*/);
|
||||
Add(In<ELFT>::BssRelRo);
|
||||
|
||||
// Add MIPS-specific sections.
|
||||
bool HasDynSymTab =
|
||||
!Symtab<ELFT>::X->getSharedFiles().empty() || Config->pic() ||
|
||||
|
@ -596,7 +595,7 @@ template <class ELFT> bool elf::isRelroSection(const OutputSection *Sec) {
|
|||
return true;
|
||||
if (In<ELFT>::Got && Sec == In<ELFT>::Got->OutSec)
|
||||
return true;
|
||||
if (Sec == In<ELFT>::BssRelRo->OutSec)
|
||||
if (Sec == Out::BssRelRo)
|
||||
return true;
|
||||
|
||||
StringRef S = Sec->Name;
|
||||
|
@ -1150,15 +1149,14 @@ 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<ELFT>(
|
||||
{In<ELFT>::DynSymTab, In<ELFT>::Bss, In<ELFT>::BssRelRo,
|
||||
In<ELFT>::GnuHashTab, In<ELFT>::HashTab, In<ELFT>::SymTab,
|
||||
In<ELFT>::ShStrTab, In<ELFT>::StrTab, In<ELFT>::VerDef,
|
||||
In<ELFT>::DynStrTab, In<ELFT>::GdbIndex, In<ELFT>::Got,
|
||||
In<ELFT>::MipsGot, In<ELFT>::IgotPlt, In<ELFT>::GotPlt,
|
||||
In<ELFT>::RelaDyn, In<ELFT>::RelaIplt, In<ELFT>::RelaPlt,
|
||||
In<ELFT>::Plt, In<ELFT>::Iplt, In<ELFT>::Plt,
|
||||
In<ELFT>::EhFrameHdr, In<ELFT>::VerSym, In<ELFT>::VerNeed,
|
||||
In<ELFT>::Dynamic},
|
||||
{In<ELFT>::DynSymTab, In<ELFT>::GnuHashTab, In<ELFT>::HashTab,
|
||||
In<ELFT>::SymTab, In<ELFT>::ShStrTab, In<ELFT>::StrTab,
|
||||
In<ELFT>::VerDef, In<ELFT>::DynStrTab, In<ELFT>::GdbIndex,
|
||||
In<ELFT>::Got, In<ELFT>::MipsGot, In<ELFT>::IgotPlt,
|
||||
In<ELFT>::GotPlt, In<ELFT>::RelaDyn, In<ELFT>::RelaIplt,
|
||||
In<ELFT>::RelaPlt, In<ELFT>::Plt, In<ELFT>::Iplt,
|
||||
In<ELFT>::Plt, In<ELFT>::EhFrameHdr, In<ELFT>::VerSym,
|
||||
In<ELFT>::VerNeed, In<ELFT>::Dynamic},
|
||||
[](SyntheticSection *SS) { SS->finalizeContents(); });
|
||||
|
||||
// Some architectures use small displacements for jump instructions.
|
||||
|
@ -1187,6 +1185,16 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
|
|||
}
|
||||
|
||||
template <class ELFT> void Writer<ELFT>::addPredefinedSections() {
|
||||
// Add BSS sections.
|
||||
auto Add = [=](OutputSection *Sec) {
|
||||
if (!Sec->Sections.empty()) {
|
||||
Sec->assignOffsets<ELFT>();
|
||||
OutputSections.push_back(Sec);
|
||||
}
|
||||
};
|
||||
Add(Out::Bss);
|
||||
Add(Out::BssRelRo);
|
||||
|
||||
// ARM ABI requires .ARM.exidx to be terminated by some piece of data.
|
||||
// We have the terminater synthetic section class. Add that at the end.
|
||||
auto *OS = dyn_cast_or_null<OutputSection>(findSection(".ARM.exidx"));
|
||||
|
|
Loading…
Reference in New Issue