[lld] r297313 - Remove DefinedSynthetic.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 8 14:36:29 PST 2017
Author: rafael
Date: Wed Mar 8 16:36:28 2017
New Revision: 297313
URL: http://llvm.org/viewvc/llvm-project?rev=297313&view=rev
Log:
Remove DefinedSynthetic.
With this we have a single section hierarchy. It is a bit less code,
but the main advantage will be in a future patch being able to handle
foo = symbol_in_obj;
in a linker script. Currently that fails since we try to find the
output section of symbol_in_obj. With this we should be able to just
return an InputSection from the expression.
Modified:
lld/trunk/ELF/InputSection.cpp
lld/trunk/ELF/InputSection.h
lld/trunk/ELF/LinkerScript.cpp
lld/trunk/ELF/LinkerScript.h
lld/trunk/ELF/MarkLive.cpp
lld/trunk/ELF/OutputSections.cpp
lld/trunk/ELF/OutputSections.h
lld/trunk/ELF/SymbolTable.cpp
lld/trunk/ELF/SymbolTable.h
lld/trunk/ELF/Symbols.cpp
lld/trunk/ELF/Symbols.h
lld/trunk/ELF/SyntheticSections.cpp
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=297313&r1=297312&r2=297313&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Wed Mar 8 16:36:28 2017
@@ -55,10 +55,11 @@ InputSectionBase::InputSectionBase(Input
uint32_t Link, uint32_t Info,
uint32_t Alignment, ArrayRef<uint8_t> Data,
StringRef Name, Kind SectionKind)
- : File(File), Data(Data), Name(Name), SectionKind(SectionKind),
- Live(!Config->GcSections || !(Flags & SHF_ALLOC)), Assigned(false),
- Flags(Flags), Entsize(Entsize), Type(Type), Link(Link), Info(Info),
- Repl(this) {
+ : SectionBase(SectionKind, Name, Flags, Entsize, Alignment, Type, Info,
+ Link),
+ File(File), Data(Data), Repl(this) {
+ Live = !Config->GcSections || !(Flags & SHF_ALLOC);
+ Assigned = false;
NumRelocations = 0;
AreRelocsRela = false;
@@ -98,15 +99,20 @@ uint64_t InputSectionBase::getOffsetInFi
return SecStart - FileStart;
}
-uint64_t InputSectionBase::getOffset(uint64_t Offset) const {
+uint64_t SectionBase::getOffset(uint64_t Offset) const {
switch (kind()) {
+ case Output: {
+ auto *OS = cast<OutputSection>(this);
+ // For output sections we treat offset -1 as the end of the section.
+ return Offset == uint64_t(-1) ? OS->Size : Offset;
+ }
case Regular:
return cast<InputSection>(this)->OutSecOff + Offset;
- case Synthetic:
+ case Synthetic: {
+ auto *IS = cast<InputSection>(this);
// For synthetic sections we treat offset -1 as the end of the section.
- // The same approach is used for synthetic symbols (DefinedSynthetic).
- return cast<InputSection>(this)->OutSecOff +
- (Offset == uint64_t(-1) ? getSize() : Offset);
+ return IS->OutSecOff + (Offset == uint64_t(-1) ? IS->getSize() : Offset);
+ }
case EHFrame:
// The file crtbeginT.o has relocations pointing to the start of an empty
// .eh_frame that is known to be the first in the link. It does that to
@@ -121,12 +127,14 @@ uint64_t InputSectionBase::getOffset(uin
llvm_unreachable("invalid section kind");
}
-OutputSection *InputSectionBase::getOutputSection() const {
+OutputSection *SectionBase::getOutputSection() {
+ if (auto *IS = dyn_cast<InputSection>(this))
+ return IS->OutSec;
if (auto *MS = dyn_cast<MergeInputSection>(this))
return MS->MergeSec ? MS->MergeSec->OutSec : nullptr;
if (auto *EH = dyn_cast<EhInputSection>(this))
return EH->EHSec->OutSec;
- return OutSec;
+ return cast<OutputSection>(this);
}
// Uncompress section contents. Note that this function is called
@@ -150,7 +158,7 @@ template <class ELFT> void InputSectionB
Data = ArrayRef<uint8_t>((uint8_t *)OutputBuf, Size);
}
-uint64_t InputSectionBase::getOffset(const DefinedRegular &Sym) const {
+uint64_t SectionBase::getOffset(const DefinedRegular &Sym) const {
return getOffset(Sym.Value);
}
@@ -199,9 +207,13 @@ InputSection::InputSection(elf::ObjectFi
const typename ELFT::Shdr *Header, StringRef Name)
: InputSectionBase(F, Header, Name, InputSectionBase::Regular) {}
-bool InputSection::classof(const InputSectionBase *S) {
- return S->kind() == InputSectionBase::Regular ||
- S->kind() == InputSectionBase::Synthetic;
+bool InputSection::classof(const SectionBase *S) {
+ return S->kind() == SectionBase::Regular ||
+ S->kind() == SectionBase::Synthetic;
+}
+
+bool InputSectionBase::classof(const SectionBase *S) {
+ return S->kind() != Output;
}
template <class ELFT> InputSectionBase *InputSection::getRelocatedSection() {
@@ -248,14 +260,14 @@ void InputSection::copyRelocations(uint8
// avoid having to parse and recreate .eh_frame, we just replace any
// relocation in it pointing to discarded sections with R_*_NONE, which
// hopefully creates a frame that is ignored at runtime.
- InputSectionBase *Section = cast<DefinedRegular>(Body).Section;
+ SectionBase *Section = cast<DefinedRegular>(Body).Section;
if (Section == &InputSection::Discarded) {
P->setSymbolAndType(0, 0, false);
continue;
}
if (Config->isRela()) {
- P->r_addend += Body.getVA<ELFT>() - Section->OutSec->Addr;
+ P->r_addend += Body.getVA<ELFT>() - Section->getOutputSection()->Addr;
} else if (Config->Relocatable) {
const uint8_t *BufLoc = RelocatedSection->Data.begin() + Rel.r_offset;
RelocatedSection->Relocations.push_back(
@@ -587,7 +599,7 @@ EhInputSection::EhInputSection(elf::Obje
this->Live = true;
}
-bool EhInputSection::classof(const InputSectionBase *S) {
+bool EhInputSection::classof(const SectionBase *S) {
return S->kind() == InputSectionBase::EHFrame;
}
@@ -710,7 +722,7 @@ void MergeInputSection::splitIntoPieces(
this->getSectionPiece(Off)->Live = true;
}
-bool MergeInputSection::classof(const InputSectionBase *S) {
+bool MergeInputSection::classof(const SectionBase *S) {
return S->kind() == InputSectionBase::Merge;
}
Modified: lld/trunk/ELF/InputSection.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=297313&r1=297312&r2=297313&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.h (original)
+++ lld/trunk/ELF/InputSection.h Wed Mar 8 16:36:28 2017
@@ -34,21 +34,23 @@ class MergeSyntheticSection;
template <class ELFT> class ObjectFile;
class OutputSection;
-// This corresponds to a section of an input file.
-class InputSectionBase {
+// This is the base class of all sections that lld handles. Some are sections in
+// input files, some are sections in the produced output file and some exist
+// just as a convenience for implementing special ways of combining some
+// sections.
+class SectionBase {
public:
- enum Kind { Regular, EHFrame, Merge, Synthetic, };
+ enum Kind { Regular, EHFrame, Merge, Synthetic, Output };
Kind kind() const { return (Kind)SectionKind; }
- // The file this section is from.
- InputFile *File;
-
- ArrayRef<uint8_t> Data;
StringRef Name;
unsigned SectionKind : 3;
+ // The next two bit fields are only used by InputSectionBase, but we
+ // put them here so the struct packs better.
+
// The garbage collector sets sections' Live bits.
// If GC is disabled, all sections are considered live by default.
unsigned Live : 1; // for garbage collection
@@ -63,12 +65,48 @@ public:
uint32_t Link;
uint32_t Info;
+ OutputSection *getOutputSection();
+ const OutputSection *getOutputSection() const {
+ return const_cast<SectionBase *>(this)->getOutputSection();
+ }
+
+ // Translate an offset in the input section to an offset in the output
+ // section.
+ uint64_t getOffset(uint64_t Offset) const;
+
+ uint64_t getOffset(const DefinedRegular &Sym) const;
+
+protected:
+ SectionBase(Kind SectionKind, StringRef Name, uint64_t Flags,
+ uint64_t Entsize, uint64_t Alignment, uint32_t Type,
+ uint32_t Info, uint32_t Link)
+ : Name(Name), SectionKind(SectionKind), Alignment(Alignment),
+ Flags(Flags), Entsize(Entsize), Type(Type), Link(Link), Info(Info) {
+ Live = false;
+ Assigned = false;
+ }
+};
+
+// This corresponds to a section of an input file.
+class InputSectionBase : public SectionBase {
+public:
+ static bool classof(const SectionBase *S);
+
+ // The file this section is from.
+ InputFile *File;
+
+ ArrayRef<uint8_t> Data;
uint64_t getOffsetInFile() const;
static InputSectionBase Discarded;
InputSectionBase()
- : SectionKind(Regular), Live(false), Assigned(false), Repl(this) {
+ : SectionBase(Regular, "", /*Flags*/ 0, /*Entsize*/ 0, /*Alignment*/ 0,
+ /*Type*/ 0,
+ /*Info*/ 0, /*Link*/ 0),
+ Repl(this) {
+ Live = false;
+ Assigned = false;
NumRelocations = 0;
AreRelocsRela = false;
}
@@ -113,20 +151,13 @@ public:
// Returns the size of this section (even if this is a common or BSS.)
size_t getSize() const;
- OutputSection *getOutputSection() const;
-
template <class ELFT> ObjectFile<ELFT> *getFile() const;
template <class ELFT> llvm::object::ELFFile<ELFT> getObj() const {
return getFile<ELFT>()->getObj();
}
- uint64_t getOffset(const DefinedRegular &Sym) const;
-
template <class ELFT> InputSectionBase *getLinkOrderDep() const;
- // Translate an offset in the input section to an offset in the output
- // section.
- uint64_t getOffset(uint64_t Offset) const;
template <class ELFT> void uncompress();
@@ -165,7 +196,7 @@ public:
template <class ELFT>
MergeInputSection(ObjectFile<ELFT> *F, const typename ELFT::Shdr *Header,
StringRef Name);
- static bool classof(const InputSectionBase *S);
+ static bool classof(const SectionBase *S);
void splitIntoPieces();
// Mark the piece at a given offset live. Used by GC.
@@ -237,7 +268,7 @@ public:
template <class ELFT>
EhInputSection(ObjectFile<ELFT> *F, const typename ELFT::Shdr *Header,
StringRef Name);
- static bool classof(const InputSectionBase *S);
+ static bool classof(const SectionBase *S);
template <class ELFT> void split();
template <class ELFT, class RelTy> void split(ArrayRef<RelTy> Rels);
@@ -267,7 +298,7 @@ public:
// to. The writer sets a value.
uint64_t OutSecOff = 0;
- static bool classof(const InputSectionBase *S);
+ static bool classof(const SectionBase *S);
template <class ELFT> InputSectionBase *getRelocatedSection();
Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=297313&r1=297312&r2=297313&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Wed Mar 8 16:36:28 2017
@@ -63,21 +63,10 @@ template <class ELFT> static SymbolBody
Cmd->Name, /*Type*/ 0, Visibility, /*CanOmitFromDynSym*/ false,
/*File*/ nullptr);
Sym->Binding = STB_GLOBAL;
+ OutputSection *Sec =
+ Cmd->Expression.IsAbsolute() ? nullptr : Cmd->Expression.Section();
replaceBody<DefinedRegular>(Sym, Cmd->Name, /*IsLocal=*/false, Visibility,
- STT_NOTYPE, 0, 0, nullptr, nullptr);
- return Sym->body();
-}
-
-template <class ELFT> static SymbolBody *addSynthetic(SymbolAssignment *Cmd) {
- Symbol *Sym;
- uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
- const OutputSection *Sec =
- ScriptConfig->HasSections ? nullptr : Cmd->Expression.Section();
- std::tie(Sym, std::ignore) = Symtab<ELFT>::X->insert(
- Cmd->Name, /*Type*/ 0, Visibility, /*CanOmitFromDynSym*/ false,
- /*File*/ nullptr);
- Sym->Binding = STB_GLOBAL;
- replaceBody<DefinedSynthetic>(Sym, Cmd->Name, 0, Sec);
+ STT_NOTYPE, 0, 0, Sec, nullptr);
return Sym->body();
}
@@ -119,18 +108,14 @@ void LinkerScript<ELFT>::assignSymbol(Sy
if (!Cmd->Sym)
return;
- if (auto *Body = dyn_cast<DefinedSynthetic>(Cmd->Sym)) {
- Body->Section = Cmd->Expression.Section();
- if (Body->Section) {
- uint64_t VA = 0;
- if (Body->Section->Flags & SHF_ALLOC)
- VA = Body->Section->Addr;
- Body->Value = Cmd->Expression(Dot) - VA;
- }
- return;
+ auto *Sym = cast<DefinedRegular>(Cmd->Sym);
+ Sym->Value = Cmd->Expression(Dot);
+ if (!Cmd->Expression.IsAbsolute()) {
+ Sym->Section = Cmd->Expression.Section();
+ if (auto *Sec = dyn_cast_or_null<OutputSection>(Sym->Section))
+ if (Sec->Flags & SHF_ALLOC)
+ Sym->Value -= Sec->Addr;
}
-
- cast<DefinedRegular>(Cmd->Sym)->Value = Cmd->Expression(Dot);
}
template <class ELFT>
@@ -144,12 +129,7 @@ void LinkerScript<ELFT>::addSymbol(Symbo
if (Cmd->Provide && (!B || B->isDefined()))
return;
- // Otherwise, create a new symbol if one does not exist or an
- // undefined one does exist.
- if (Cmd->Expression.IsAbsolute())
- Cmd->Sym = addRegular<ELFT>(Cmd);
- else
- Cmd->Sym = addSynthetic<ELFT>(Cmd);
+ Cmd->Sym = addRegular<ELFT>(Cmd);
// If there are sections, then let the value be assigned later in
// `assignAddresses`.
@@ -321,6 +301,19 @@ LinkerScript<ELFT>::createInputSectionLi
template <class ELFT>
void LinkerScript<ELFT>::processCommands(OutputSectionFactory &Factory) {
+ // A symbol can be assigned before any section is mentioned in the linker
+ // script. In an DSO, the symbol values are addresses, so the only important
+ // section values are:
+ // * SHN_UNDEF
+ // * SHN_ABS
+ // * Any value meaning a regular section.
+ // To handle that, create a dummy aether section that fills the void before
+ // the linker scripts switches to another section. It has an index of one
+ // which will map to whatever the first actual section is.
+ Aether = make<OutputSection>("", 0, SHF_ALLOC);
+ Aether->SectionIndex = 1;
+ CurOutSec = Aether;
+
for (unsigned I = 0; I < Opt.Commands.size(); ++I) {
auto Iter = Opt.Commands.begin() + I;
const std::unique_ptr<BaseCommand> &Base1 = *Iter;
@@ -385,6 +378,7 @@ void LinkerScript<ELFT>::processCommands
Factory.addInputSec<ELFT>(S, Cmd->Name);
}
}
+ CurOutSec = nullptr;
}
// Add sections that didn't match any sections command.
@@ -772,18 +766,6 @@ template <class ELFT>
void LinkerScript<ELFT>::assignAddresses(std::vector<PhdrEntry> &Phdrs) {
// Assign addresses as instructed by linker script SECTIONS sub-commands.
Dot = 0;
-
- // A symbol can be assigned before any section is mentioned in the linker
- // script. In an DSO, the symbol values are addresses, so the only important
- // section values are:
- // * SHN_UNDEF
- // * SHN_ABS
- // * Any value meaning a regular section.
- // To handle that, create a dummy aether section that fills the void before
- // the linker scripts switches to another section. It has an index of one
- // which will map to whatever the first actual section is.
- auto *Aether = make<OutputSection>("", 0, SHF_ALLOC);
- Aether->SectionIndex = 1;
switchTo(Aether);
for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
@@ -924,8 +906,8 @@ template <class ELFT> bool LinkerScript<
}
template <class ELFT>
-const OutputSection *LinkerScript<ELFT>::getOutputSection(const Twine &Loc,
- StringRef Name) {
+OutputSection *LinkerScript<ELFT>::getOutputSection(const Twine &Loc,
+ StringRef Name) {
static OutputSection FakeSec("", 0, 0);
for (OutputSection *Sec : *OutputSections)
@@ -976,7 +958,7 @@ template <class ELFT> bool LinkerScript<
// specific section but isn't absolute at the same time, so we try
// to find suitable section for it as well.
template <class ELFT>
-const OutputSection *LinkerScript<ELFT>::getSymbolSection(StringRef S) {
+OutputSection *LinkerScript<ELFT>::getSymbolSection(StringRef S) {
if (SymbolBody *Sym = Symtab<ELFT>::X->find(S))
return Sym->getOutputSection<ELFT>();
return CurOutSec;
@@ -1634,7 +1616,7 @@ Expr ScriptParser::readExpr() {
static Expr combine(StringRef Op, Expr L, Expr R) {
auto IsAbs = [=] { return L.IsAbsolute() && R.IsAbsolute(); };
auto GetOutSec = [=] {
- const OutputSection *S = L.Section();
+ OutputSection *S = L.Section();
return S ? S : R.Section();
};
Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=297313&r1=297312&r2=297313&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Wed Mar 8 16:36:28 2017
@@ -47,13 +47,13 @@ struct Expr {
// If expression is section-relative the function below is used
// to get the output section pointer.
- std::function<const OutputSection *()> Section;
+ std::function<OutputSection *()> Section;
uint64_t operator()(uint64_t Dot) const { return Val(Dot); }
operator bool() const { return (bool)Val; }
Expr(std::function<uint64_t(uint64_t)> Val, std::function<bool()> IsAbsolute,
- std::function<const OutputSection *()> Section)
+ std::function<OutputSection *()> Section)
: Val(Val), IsAbsolute(IsAbsolute), Section(Section) {}
template <typename T>
Expr(T V) : Expr(V, [] { return true; }, [] { return nullptr; }) {}
@@ -207,15 +207,15 @@ struct MemoryRegion {
class LinkerScriptBase {
protected:
~LinkerScriptBase() = default;
+ OutputSection *Aether;
public:
virtual uint64_t getHeaderSize() = 0;
virtual uint64_t getSymbolValue(const Twine &Loc, StringRef S) = 0;
virtual bool isDefined(StringRef S) = 0;
virtual bool isAbsolute(StringRef S) = 0;
- virtual const OutputSection *getSymbolSection(StringRef S) = 0;
- virtual const OutputSection *getOutputSection(const Twine &Loc,
- StringRef S) = 0;
+ virtual OutputSection *getSymbolSection(StringRef S) = 0;
+ virtual OutputSection *getOutputSection(const Twine &Loc, StringRef S) = 0;
virtual uint64_t getOutputSectionSize(StringRef S) = 0;
};
@@ -268,8 +268,8 @@ public:
uint64_t getSymbolValue(const Twine &Loc, StringRef S) override;
bool isDefined(StringRef S) override;
bool isAbsolute(StringRef S) override;
- const OutputSection *getSymbolSection(StringRef S) override;
- const OutputSection *getOutputSection(const Twine &Loc, StringRef S) override;
+ OutputSection *getSymbolSection(StringRef S) override;
+ OutputSection *getOutputSection(const Twine &Loc, StringRef S) override;
uint64_t getOutputSectionSize(StringRef S) override;
std::vector<OutputSection *> *OutputSections;
Modified: lld/trunk/ELF/MarkLive.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/MarkLive.cpp?rev=297313&r1=297312&r2=297313&view=diff
==============================================================================
--- lld/trunk/ELF/MarkLive.cpp (original)
+++ lld/trunk/ELF/MarkLive.cpp Wed Mar 8 16:36:28 2017
@@ -78,7 +78,7 @@ static void resolveReloc(InputSectionBas
typename ELFT::uint Offset = D->Value;
if (D->isSection())
Offset += getAddend<ELFT>(Sec, Rel);
- Fn({D->Section->Repl, Offset});
+ Fn({cast<InputSectionBase>(D->Section)->Repl, Offset});
} else if (auto *U = dyn_cast<Undefined>(&B)) {
for (InputSectionBase *Sec : CNamedSections.lookup(U->getName()))
Fn({Sec, 0});
@@ -223,7 +223,7 @@ template <class ELFT> void elf::markLive
auto MarkSymbol = [&](const SymbolBody *Sym) {
if (auto *D = dyn_cast_or_null<DefinedRegular>(Sym))
- Enqueue({D->Section, D->Value});
+ Enqueue({cast<InputSectionBase>(D->Section), D->Value});
};
// Add GC root symbols.
Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=297313&r1=297312&r2=297313&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Wed Mar 8 16:36:28 2017
@@ -67,7 +67,9 @@ void OutputSection::writeHeaderTo(typena
}
OutputSection::OutputSection(StringRef Name, uint32_t Type, uint64_t Flags)
- : Name(Name), Flags(Flags), Alignment(1), Type(Type) {}
+ : SectionBase(Output, Name, Flags, /*Entsize*/ 0, /*Alignment*/ 1, Type,
+ /*Info*/ 0,
+ /*Link*/ 0) {}
template <typename ELFT>
static bool compareByFilePosition(InputSection *A, InputSection *B) {
Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=297313&r1=297312&r2=297313&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Wed Mar 8 16:36:28 2017
@@ -11,6 +11,7 @@
#define LLD_ELF_OUTPUT_SECTIONS_H
#include "Config.h"
+#include "InputSection.h"
#include "Relocations.h"
#include "lld/Core/LLVM.h"
@@ -37,10 +38,14 @@ class DefinedRegular;
// It is composed of multiple InputSections.
// The writer creates multiple OutputSections and assign them unique,
// non-overlapping file offsets and VAs.
-class OutputSection final {
+class OutputSection final : public SectionBase {
public:
OutputSection(StringRef Name, uint32_t Type, uint64_t Flags);
+ static bool classof(const SectionBase *S) {
+ return S->kind() == SectionBase::Output;
+ }
+
uint64_t getLMA() const { return Addr + LMAOffset; }
template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *SHdr);
@@ -65,20 +70,12 @@ public:
// formula: Off = Off_first + VA - VA_first.
OutputSection *FirstInPtLoad = nullptr;
- StringRef Name;
-
// The following fields correspond to Elf_Shdr members.
uint64_t Size = 0;
- uint64_t Entsize = 0;
uint64_t Offset = 0;
- uint64_t Flags = 0;
uint64_t LMAOffset = 0;
uint64_t Addr = 0;
- uint32_t Alignment = 0;
uint32_t ShName = 0;
- uint32_t Type = 0;
- uint32_t Info = 0;
- uint32_t Link = 0;
void addSection(InputSectionBase *C);
void sort(std::function<int(InputSectionBase *S)> Order);
Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=297313&r1=297312&r2=297313&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Wed Mar 8 16:36:28 2017
@@ -369,7 +369,8 @@ static void reportDuplicate(SymbolBody *
return;
}
- std::string OldLoc = D->Section->template getLocation<ELFT>(D->Value);
+ std::string OldLoc =
+ cast<InputSectionBase>(D->Section)->template getLocation<ELFT>(D->Value);
std::string NewLoc = ErrSec->getLocation<ELFT>(ErrOffset);
print(NewLoc + ": duplicate symbol '" + toString(*Existing) + "'");
@@ -377,10 +378,10 @@ static void reportDuplicate(SymbolBody *
}
template <typename ELFT>
-Symbol *
-SymbolTable<ELFT>::addRegular(StringRef Name, uint8_t StOther, uint8_t Type,
- uint64_t Value, uint64_t Size, uint8_t Binding,
- InputSectionBase *Section, InputFile *File) {
+Symbol *SymbolTable<ELFT>::addRegular(StringRef Name, uint8_t StOther,
+ uint8_t Type, uint64_t Value,
+ uint64_t Size, uint8_t Binding,
+ SectionBase *Section, InputFile *File) {
Symbol *S;
bool WasInserted;
std::tie(S, WasInserted) = insert(Name, Type, getVisibility(StOther),
@@ -391,24 +392,8 @@ SymbolTable<ELFT>::addRegular(StringRef
replaceBody<DefinedRegular>(S, Name, /*IsLocal=*/false, StOther, Type,
Value, Size, Section, File);
else if (Cmp == 0)
- reportDuplicate<ELFT>(S->body(), Section, Value);
- return S;
-}
-
-template <typename ELFT>
-Symbol *SymbolTable<ELFT>::addSynthetic(StringRef N,
- const OutputSection *Section,
- uint64_t Value, uint8_t StOther) {
- Symbol *S;
- bool WasInserted;
- std::tie(S, WasInserted) = insert(N, STT_NOTYPE, getVisibility(StOther),
- /*CanOmitFromDynSym*/ false, nullptr);
- int Cmp = compareDefinedNonCommon<ELFT>(S, WasInserted, STB_GLOBAL,
- /*IsAbsolute*/ false, /*Value*/ 0);
- if (Cmp > 0)
- replaceBody<DefinedSynthetic>(S, N, Value, Section);
- else if (Cmp == 0)
- reportDuplicate(S->body(), nullptr);
+ reportDuplicate<ELFT>(S->body(),
+ dyn_cast_or_null<InputSectionBase>(Section), Value);
return S;
}
Modified: lld/trunk/ELF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=297313&r1=297312&r2=297313&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Wed Mar 8 16:36:28 2017
@@ -58,10 +58,7 @@ public:
Symbol *addRegular(StringRef Name, uint8_t StOther, uint8_t Type,
uint64_t Value, uint64_t Size, uint8_t Binding,
- InputSectionBase *Section, InputFile *File);
-
- Symbol *addSynthetic(StringRef N, const OutputSection *Section,
- uint64_t Value, uint8_t StOther);
+ SectionBase *Section, InputFile *File);
void addShared(SharedFile<ELFT> *F, StringRef Name, const Elf_Sym &Sym,
const typename ELFT::Verdef *Verdef);
Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=297313&r1=297312&r2=297313&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Wed Mar 8 16:36:28 2017
@@ -28,14 +28,12 @@ using namespace llvm::ELF;
using namespace lld;
using namespace lld::elf;
-InputSectionBase *DefinedRegular::NullInputSection;
-
-DefinedSynthetic *ElfSym::Etext;
-DefinedSynthetic *ElfSym::Etext2;
-DefinedSynthetic *ElfSym::Edata;
-DefinedSynthetic *ElfSym::Edata2;
-DefinedSynthetic *ElfSym::End;
-DefinedSynthetic *ElfSym::End2;
+DefinedRegular *ElfSym::Etext;
+DefinedRegular *ElfSym::Etext2;
+DefinedRegular *ElfSym::Edata;
+DefinedRegular *ElfSym::Edata2;
+DefinedRegular *ElfSym::End;
+DefinedRegular *ElfSym::End2;
DefinedRegular *ElfSym::MipsGpDisp;
DefinedRegular *ElfSym::MipsLocalGp;
DefinedRegular *ElfSym::MipsGp;
@@ -43,18 +41,11 @@ DefinedRegular *ElfSym::MipsGp;
template <class ELFT>
static typename ELFT::uint getSymVA(const SymbolBody &Body, int64_t &Addend) {
switch (Body.kind()) {
- case SymbolBody::DefinedSyntheticKind: {
- auto &D = cast<DefinedSynthetic>(Body);
- const OutputSection *Sec = D.Section;
- if (!Sec)
- return D.Value;
- if (D.Value == uint64_t(-1))
- return Sec->Addr + Sec->Size;
- return Sec->Addr + D.Value;
- }
case SymbolBody::DefinedRegularKind: {
auto &D = cast<DefinedRegular>(Body);
- InputSectionBase *IS = D.Section;
+ SectionBase *IS = D.Section;
+ if (auto *ISB = dyn_cast_or_null<InputSectionBase>(IS))
+ IS = ISB->Repl;
// According to the ELF spec reference to a local symbol from outside
// the group are not allowed. Unfortunately .eh_frame breaks that rule
@@ -207,8 +198,7 @@ template <class ELFT> typename ELFT::uin
return 0;
}
-template <class ELFT>
-const OutputSection *SymbolBody::getOutputSection() const {
+template <class ELFT> OutputSection *SymbolBody::getOutputSection() const {
if (auto *S = dyn_cast<DefinedRegular>(this)) {
if (S->Section)
return S->Section->getOutputSection();
@@ -227,8 +217,6 @@ const OutputSection *SymbolBody::getOutp
return nullptr;
}
- if (auto *S = dyn_cast<DefinedSynthetic>(this))
- return S->Section;
return nullptr;
}
@@ -279,7 +267,11 @@ template <class ELFT> bool DefinedRegula
if (!Section || !isFunc())
return false;
return (this->StOther & STO_MIPS_MIPS16) == STO_MIPS_PIC ||
- (Section->getFile<ELFT>()->getObj().getHeader()->e_flags &
+ (cast<InputSectionBase>(Section)
+ ->template getFile<ELFT>()
+ ->getObj()
+ .getHeader()
+ ->e_flags &
EF_MIPS_PIC);
}
@@ -419,14 +411,10 @@ template uint32_t SymbolBody::template g
template uint64_t SymbolBody::template getSize<ELF64LE>() const;
template uint64_t SymbolBody::template getSize<ELF64BE>() const;
-template const OutputSection *
- SymbolBody::template getOutputSection<ELF32LE>() const;
-template const OutputSection *
- SymbolBody::template getOutputSection<ELF32BE>() const;
-template const OutputSection *
- SymbolBody::template getOutputSection<ELF64LE>() const;
-template const OutputSection *
- SymbolBody::template getOutputSection<ELF64BE>() const;
+template OutputSection *SymbolBody::template getOutputSection<ELF32LE>() const;
+template OutputSection *SymbolBody::template getOutputSection<ELF32BE>() const;
+template OutputSection *SymbolBody::template getOutputSection<ELF64LE>() const;
+template OutputSection *SymbolBody::template getOutputSection<ELF64BE>() const;
template bool DefinedRegular::template isMipsPIC<ELF32LE>() const;
template bool DefinedRegular::template isMipsPIC<ELF32BE>() const;
Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=297313&r1=297312&r2=297313&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Wed Mar 8 16:36:28 2017
@@ -43,8 +43,7 @@ public:
DefinedRegularKind = DefinedFirst,
SharedKind,
DefinedCommonKind,
- DefinedSyntheticKind,
- DefinedLast = DefinedSyntheticKind,
+ DefinedLast = DefinedCommonKind,
UndefinedKind,
LazyArchiveKind,
LazyObjectKind,
@@ -84,7 +83,7 @@ public:
template <class ELFT> typename ELFT::uint getGotPltVA() const;
template <class ELFT> typename ELFT::uint getPltVA() const;
template <class ELFT> typename ELFT::uint getSize() const;
- template <class ELFT> const OutputSection *getOutputSection() const;
+ template <class ELFT> OutputSection *getOutputSection() const;
// The file from which this symbol was created.
InputFile *File = nullptr;
@@ -177,11 +176,10 @@ public:
class DefinedRegular : public Defined {
public:
DefinedRegular(StringRefZ Name, bool IsLocal, uint8_t StOther, uint8_t Type,
- uint64_t Value, uint64_t Size, InputSectionBase *Section,
+ uint64_t Value, uint64_t Size, SectionBase *Section,
InputFile *File)
: Defined(SymbolBody::DefinedRegularKind, Name, IsLocal, StOther, Type),
- Value(Value), Size(Size),
- Section(Section ? Section->Repl : NullInputSection) {
+ Value(Value), Size(Size), Section(Section) {
this->File = File;
}
@@ -194,37 +192,7 @@ public:
uint64_t Value;
uint64_t Size;
-
- // The input section this symbol belongs to. Notice that this is
- // a reference to a pointer. We are using two levels of indirections
- // because of ICF. If ICF decides two sections need to be merged, it
- // manipulates this Section pointers so that they point to the same
- // section. This is a bit tricky, so be careful to not be confused.
- // If this is null, the symbol is an absolute symbol.
- InputSectionBase *&Section;
-
-private:
- static InputSectionBase *NullInputSection;
-};
-
-// DefinedSynthetic is a class to represent linker-generated ELF symbols.
-// The difference from the regular symbol is that DefinedSynthetic symbols
-// don't belong to any input files or sections. Thus, its constructor
-// takes an output section to calculate output VA, etc.
-// If Section is null, this symbol is relative to the image base.
-class DefinedSynthetic : public Defined {
-public:
- DefinedSynthetic(StringRef Name, uint64_t Value, const OutputSection *Section)
- : Defined(SymbolBody::DefinedSyntheticKind, Name, /*IsLocal=*/false,
- llvm::ELF::STV_HIDDEN, 0 /* Type */),
- Value(Value), Section(Section) {}
-
- static bool classof(const SymbolBody *S) {
- return S->kind() == SymbolBody::DefinedSyntheticKind;
- }
-
- uint64_t Value;
- const OutputSection *Section;
+ SectionBase *Section;
};
class Undefined : public SymbolBody {
@@ -334,16 +302,16 @@ public:
// DefinedRegular symbols.
struct ElfSym {
// The content for _etext and etext symbols.
- static DefinedSynthetic *Etext;
- static DefinedSynthetic *Etext2;
+ static DefinedRegular *Etext;
+ static DefinedRegular *Etext2;
// The content for _edata and edata symbols.
- static DefinedSynthetic *Edata;
- static DefinedSynthetic *Edata2;
+ static DefinedRegular *Edata;
+ static DefinedRegular *Edata2;
// The content for _end and end symbols.
- static DefinedSynthetic *End;
- static DefinedSynthetic *End2;
+ static DefinedRegular *End;
+ static DefinedRegular *End2;
// The content for _gp_disp/__gnu_local_gp symbols for MIPS target.
static DefinedRegular *MipsGpDisp;
@@ -395,8 +363,8 @@ struct Symbol {
// This field is used to store the Symbol's SymbolBody. This instantiation of
// AlignedCharArrayUnion gives us a struct with a char array field that is
// large and aligned enough to store any derived class of SymbolBody.
- llvm::AlignedCharArrayUnion<DefinedCommon, DefinedRegular, DefinedSynthetic,
- Undefined, SharedSymbol, LazyArchive, LazyObject>
+ llvm::AlignedCharArrayUnion<DefinedCommon, DefinedRegular, Undefined,
+ SharedSymbol, LazyArchive, LazyObject>
Body;
SymbolBody *body() { return reinterpret_cast<SymbolBody *>(Body.buffer); }
Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=297313&r1=297312&r2=297313&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Wed Mar 8 16:36:28 2017
@@ -460,7 +460,8 @@ bool EhFrameSection<ELFT>::isFdeLive(EhS
auto *D = dyn_cast<DefinedRegular>(&B);
if (!D || !D->Section)
return false;
- InputSectionBase *Target = D->Section->Repl;
+ auto *Target =
+ cast<InputSectionBase>(cast<InputSectionBase>(D->Section)->Repl);
return Target && Target->Live;
}
@@ -1357,8 +1358,8 @@ size_t SymbolTableSection<ELFT>::getSymb
// This is used for -r, so we have to handle multiple section
// symbols being combined.
if (Body->Type == STT_SECTION && E.Symbol->Type == STT_SECTION)
- return cast<DefinedRegular>(Body)->Section->OutSec ==
- cast<DefinedRegular>(E.Symbol)->Section->OutSec;
+ return cast<DefinedRegular>(Body)->Section->getOutputSection() ==
+ cast<DefinedRegular>(E.Symbol)->Section->getOutputSection();
return false;
});
if (I == Symbols.end())
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=297313&r1=297312&r2=297313&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Mar 8 16:36:28 2017
@@ -453,7 +453,7 @@ template <class ELFT> void Writer<ELFT>:
}
template <class ELFT>
-static bool shouldKeepInSymtab(InputSectionBase *Sec, StringRef SymName,
+static bool shouldKeepInSymtab(SectionBase *Sec, StringRef SymName,
const SymbolBody &B) {
if (B.isFile() || B.isSection())
return false;
@@ -485,12 +485,17 @@ template <class ELFT> static bool includ
if (auto *D = dyn_cast<DefinedRegular>(&B)) {
// Always include absolute symbols.
- if (!D->Section)
+ SectionBase *Sec = D->Section;
+ if (!Sec)
return true;
- // Exclude symbols pointing to garbage-collected sections.
- if (!D->Section->Live)
- return false;
- if (auto *S = dyn_cast<MergeInputSection>(D->Section))
+ if (auto *IS = dyn_cast<InputSectionBase>(Sec)) {
+ Sec = IS->Repl;
+ IS = cast<InputSectionBase>(Sec);
+ // Exclude symbols pointing to garbage-collected sections.
+ if (!IS->Live)
+ return false;
+ }
+ if (auto *S = dyn_cast<MergeInputSection>(Sec))
if (!S->getSectionPiece(D->Value)->Live)
return false;
}
@@ -515,7 +520,7 @@ template <class ELFT> void Writer<ELFT>:
if (!includeInSymtab<ELFT>(*B))
continue;
- InputSectionBase *Sec = DR->Section;
+ SectionBase *Sec = DR->Section;
if (!shouldKeepInSymtab<ELFT>(Sec, B->getName(), *B))
continue;
In<ELFT>::SymTab->addSymbol(B);
@@ -733,35 +738,27 @@ void PhdrEntry::add(OutputSection *Sec)
}
template <class ELFT>
-static DefinedSynthetic *addOptionalSynthetic(StringRef Name,
- OutputSection *Sec, uint64_t Val,
- uint8_t StOther = STV_HIDDEN) {
- if (SymbolBody *S = Symtab<ELFT>::X->find(Name))
- if (!S->isInCurrentDSO())
- return cast<DefinedSynthetic>(
- Symtab<ELFT>::X->addSynthetic(Name, Sec, Val, StOther)->body());
- return nullptr;
-}
-
-template <class ELFT>
-static Symbol *addRegular(StringRef Name, InputSectionBase *Sec,
- uint64_t Value) {
+static Symbol *addRegular(StringRef Name, SectionBase *Sec, uint64_t Value,
+ uint8_t StOther = STV_HIDDEN,
+ uint8_t Binding = STB_WEAK) {
// The linker generated symbols are added as STB_WEAK to allow user defined
// ones to override them.
- return Symtab<ELFT>::X->addRegular(Name, STV_HIDDEN, STT_NOTYPE, Value,
- /*Size=*/0, STB_WEAK, Sec,
+ return Symtab<ELFT>::X->addRegular(Name, StOther, STT_NOTYPE, Value,
+ /*Size=*/0, Binding, Sec,
/*File=*/nullptr);
}
template <class ELFT>
-static Symbol *addOptionalRegular(StringRef Name, InputSectionBase *IS,
- uint64_t Value) {
+static DefinedRegular *
+addOptionalRegular(StringRef Name, SectionBase *Sec, uint64_t Val,
+ uint8_t StOther = STV_HIDDEN, uint8_t Binding = STB_GLOBAL) {
SymbolBody *S = Symtab<ELFT>::X->find(Name);
if (!S)
return nullptr;
if (S->isInCurrentDSO())
- return S->symbol();
- return addRegular<ELFT>(Name, IS, Value);
+ return nullptr;
+ return cast<DefinedRegular>(
+ addRegular<ELFT>(Name, Sec, Val, StOther, Binding)->body());
}
// The beginning and the ending of .rel[a].plt section are marked
@@ -774,10 +771,10 @@ template <class ELFT> void Writer<ELFT>:
if (In<ELFT>::DynSymTab)
return;
StringRef S = Config->isRela() ? "__rela_iplt_start" : "__rel_iplt_start";
- addOptionalRegular<ELFT>(S, In<ELFT>::RelaIplt, 0);
+ addOptionalRegular<ELFT>(S, In<ELFT>::RelaIplt, 0, STV_HIDDEN, STB_WEAK);
S = Config->isRela() ? "__rela_iplt_end" : "__rel_iplt_end";
- addOptionalRegular<ELFT>(S, In<ELFT>::RelaIplt, -1);
+ addOptionalRegular<ELFT>(S, In<ELFT>::RelaIplt, -1, STV_HIDDEN, STB_WEAK);
}
// The linker is expected to define some symbols depending on
@@ -837,14 +834,13 @@ template <class ELFT> void Writer<ELFT>:
return;
// __ehdr_start is the location of ELF file headers.
- addOptionalSynthetic<ELFT>("__ehdr_start", Out::ElfHeader, 0);
+ addOptionalRegular<ELFT>("__ehdr_start", Out::ElfHeader, 0, STV_HIDDEN);
- auto Define = [](StringRef S, DefinedSynthetic *&Sym1,
- DefinedSynthetic *&Sym2) {
- Sym1 = addOptionalSynthetic<ELFT>(S, nullptr, 0, STV_DEFAULT);
+ auto Define = [](StringRef S, DefinedRegular *&Sym1, DefinedRegular *&Sym2) {
+ Sym1 = addOptionalRegular<ELFT>(S, Out::ElfHeader, 0, STV_DEFAULT);
assert(S.startswith("_"));
S = S.substr(1);
- Sym2 = addOptionalSynthetic<ELFT>(S, nullptr, 0, STV_DEFAULT);
+ Sym2 = addOptionalRegular<ELFT>(S, Out::ElfHeader, 0, STV_DEFAULT);
};
Define("_end", ElfSym::End, ElfSym::End2);
@@ -880,7 +876,7 @@ static void sortBySymbolsOrder(ArrayRef<
SymbolOrder.insert({S, Priority++});
// Build a map from sections to their priorities.
- DenseMap<InputSectionBase *, int> SectionOrder;
+ DenseMap<SectionBase *, int> SectionOrder;
for (elf::ObjectFile<ELFT> *File : Symtab<ELFT>::X->getObjectFiles()) {
for (SymbolBody *Body : File->getSymbols()) {
auto *D = dyn_cast<DefinedRegular>(Body);
@@ -1208,8 +1204,10 @@ template <class ELFT> void Writer<ELFT>:
auto Define = [&](StringRef Start, StringRef End, OutputSection *OS) {
// These symbols resolve to the image base if the section does not exist.
// A special value -1 indicates end of the section.
- addOptionalSynthetic<ELFT>(Start, OS, 0);
- addOptionalSynthetic<ELFT>(End, OS, OS ? -1 : 0);
+ if (!OS && Config->pic())
+ OS = Out::ElfHeader;
+ addOptionalRegular<ELFT>(Start, OS, 0);
+ addOptionalRegular<ELFT>(End, OS, OS ? -1 : 0);
};
Define("__preinit_array_start", "__preinit_array_end", Out::PreinitArray);
@@ -1230,8 +1228,8 @@ void Writer<ELFT>::addStartStopSymbols(O
StringRef S = Sec->Name;
if (!isValidCIdentifier(S))
return;
- addOptionalSynthetic<ELFT>(Saver.save("__start_" + S), Sec, 0, STV_DEFAULT);
- addOptionalSynthetic<ELFT>(Saver.save("__stop_" + S), Sec, -1, STV_DEFAULT);
+ addOptionalRegular<ELFT>(Saver.save("__start_" + S), Sec, 0, STV_DEFAULT);
+ addOptionalRegular<ELFT>(Saver.save("__stop_" + S), Sec, -1, STV_DEFAULT);
}
template <class ELFT> OutputSection *Writer<ELFT>::findSection(StringRef Name) {
@@ -1638,7 +1636,7 @@ static uint16_t getELFType() {
// to each section. This function fixes some predefined
// symbol values that depend on section address and size.
template <class ELFT> void Writer<ELFT>::fixPredefinedSymbols() {
- auto Set = [](DefinedSynthetic *S1, DefinedSynthetic *S2, OutputSection *Sec,
+ auto Set = [](DefinedRegular *S1, DefinedRegular *S2, OutputSection *Sec,
uint64_t Value) {
if (S1) {
S1->Section = Sec;
More information about the llvm-commits
mailing list