[lld] r280348 - Eliminate LayoutInputSection class
Rafael EspĂndola via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 1 05:31:03 PDT 2016
Thanks!
On 1 September 2016 at 05:55, Eugene Leviant via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: evgeny777
> Date: Thu Sep 1 04:55:57 2016
> New Revision: 280348
>
> URL: http://llvm.org/viewvc/llvm-project?rev=280348&view=rev
> Log:
> Eliminate LayoutInputSection class
>
> Previously we used LayoutInputSection class to correctly assign
> symbols defined in linker script. This patch removes it and uses
> pointer to preceding input section in SymbolAssignment class instead.
>
> Differential revision: https://reviews.llvm.org/D23661
>
> Modified:
> lld/trunk/ELF/InputSection.cpp
> lld/trunk/ELF/InputSection.h
> lld/trunk/ELF/LinkerScript.cpp
> lld/trunk/ELF/LinkerScript.h
> lld/trunk/ELF/OutputSections.cpp
>
> Modified: lld/trunk/ELF/InputSection.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=280348&r1=280347&r2=280348&view=diff
> ==============================================================================
> --- lld/trunk/ELF/InputSection.cpp (original)
> +++ lld/trunk/ELF/InputSection.cpp Thu Sep 1 04:55:57 2016
> @@ -30,14 +30,10 @@ using namespace lld::elf;
>
> template <class ELFT>
> InputSectionBase<ELFT>::InputSectionBase(elf::ObjectFile<ELFT> *File,
> - const Elf_Shdr *Header,
> - Kind SectionKind)
> - : Header(Header), File(File), SectionKind(SectionKind), Repl(this),
> - Compressed(Header->sh_flags & SHF_COMPRESSED) {
> - // The garbage collector sets sections' Live bits.
> - // If GC is disabled, all sections are considered live by default.
> - Live = !Config->GcSections;
> -
> + const Elf_Shdr *Hdr, Kind SectionKind)
> + : InputSectionData(SectionKind, Hdr->sh_flags & SHF_COMPRESSED,
> + !Config->GcSections),
> + Header(Hdr), File(File), Repl(this) {
> // The ELF spec states that a value of 0 means the section has
> // no alignment constraits.
> Alignment = std::max<uintX_t>(Header->sh_addralign, 1);
> @@ -71,7 +67,6 @@ template <class ELFT>
> typename ELFT::uint InputSectionBase<ELFT>::getOffset(uintX_t Offset) const {
> switch (SectionKind) {
> case Regular:
> - case Layout:
> return cast<InputSection<ELFT>>(this)->OutSecOff + Offset;
> case EHFrame:
> // The file crtbeginT.o has relocations pointing to the start of an empty
> @@ -131,7 +126,7 @@ InputSection<ELFT>::InputSection(elf::Ob
>
> template <class ELFT>
> bool InputSection<ELFT>::classof(const InputSectionBase<ELFT> *S) {
> - return S->SectionKind == Base::Regular || S->SectionKind == Base::Layout;
> + return S->SectionKind == Base::Regular;
> }
>
> template <class ELFT>
>
> Modified: lld/trunk/ELF/InputSection.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=280348&r1=280347&r2=280348&view=diff
> ==============================================================================
> --- lld/trunk/ELF/InputSection.h (original)
> +++ lld/trunk/ELF/InputSection.h Thu Sep 1 04:55:57 2016
> @@ -30,8 +30,33 @@ template <class ELFT> class ObjectFile;
> template <class ELFT> class OutputSection;
> template <class ELFT> class OutputSectionBase;
>
> +// We need non-template input section class to store symbol layout
> +// in linker script parser structures, where we do not have ELFT
> +// template parameter. For each scripted output section symbol we
> +// store pointer to preceding InputSectionData object or nullptr,
> +// if symbol should be placed at the very beginning of the output
> +// section
> +class InputSectionData {
> +public:
> + enum Kind { Regular, EHFrame, Merge, MipsReginfo, MipsOptions, MipsAbiFlags };
> +
> + // The garbage collector sets sections' Live bits.
> + // If GC is disabled, all sections are considered live by default.
> + InputSectionData(Kind SectionKind, bool Compressed, bool Live)
> + : SectionKind(SectionKind), Live(Live), Compressed(Compressed) {}
> +
> + Kind SectionKind;
> + uint32_t Alignment;
> + // Used for garbage collection.
> + bool Live;
> +
> + bool Compressed;
> + // If a section is compressed, this vector has uncompressed section data.
> + SmallVector<char, 0> Uncompressed;
> +};
> +
> // This corresponds to a section of an input file.
> -template <class ELFT> class InputSectionBase {
> +template <class ELFT> class InputSectionBase : public InputSectionData {
> protected:
> typedef typename ELFT::Chdr Elf_Chdr;
> typedef typename ELFT::Rel Elf_Rel;
> @@ -44,30 +69,12 @@ protected:
> // The file this section is from.
> ObjectFile<ELFT> *File;
>
> - // If a section is compressed, this vector has uncompressed section data.
> - SmallVector<char, 0> Uncompressed;
> -
> public:
> - enum Kind {
> - Regular,
> - EHFrame,
> - Merge,
> - MipsReginfo,
> - MipsOptions,
> - MipsAbiFlags,
> - Layout
> - };
> - Kind SectionKind;
> -
> - InputSectionBase() : Repl(this) {}
> + InputSectionBase() : InputSectionData(Regular, false, false), Repl(this) {}
>
> InputSectionBase(ObjectFile<ELFT> *File, const Elf_Shdr *Header,
> Kind SectionKind);
> OutputSectionBase<ELFT> *OutSec = nullptr;
> - uint32_t Alignment;
> -
> - // Used for garbage collection.
> - bool Live;
>
> // This pointer points to the "real" instance of this instance.
> // Usually Repl == this. However, if ICF merges two sections,
> @@ -96,8 +103,6 @@ public:
>
> void relocate(uint8_t *Buf, uint8_t *BufEnd);
> std::vector<Relocation<ELFT>> Relocations;
> -
> - bool Compressed;
> };
>
> template <class ELFT> InputSectionBase<ELFT> InputSectionBase<ELFT>::Discarded;
>
> Modified: lld/trunk/ELF/LinkerScript.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=280348&r1=280347&r2=280348&view=diff
> ==============================================================================
> --- lld/trunk/ELF/LinkerScript.cpp (original)
> +++ lld/trunk/ELF/LinkerScript.cpp Thu Sep 1 04:55:57 2016
> @@ -133,54 +133,6 @@ LinkerScript<ELFT>::getInputSections(con
> return Ret;
> }
>
> -// You can define new symbols using linker scripts. For example,
> -// ".text { abc.o(.text); foo = .; def.o(.text); }" defines symbol
> -// foo just after abc.o's text section contents. This class is to
> -// handle such symbol definitions.
> -//
> -// In order to handle scripts like the above one, we want to
> -// keep symbol definitions in output sections. Because output sections
> -// can contain only input sections, we wrap symbol definitions
> -// with dummy input sections. This class serves that purpose.
> -template <class ELFT>
> -class elf::LayoutInputSection : public InputSectionBase<ELFT> {
> -public:
> - explicit LayoutInputSection(SymbolAssignment *Cmd);
> - static bool classof(const InputSectionBase<ELFT> *S);
> - SymbolAssignment *Cmd;
> -
> -private:
> - typename ELFT::Shdr Hdr;
> -};
> -
> -template <class ELFT>
> -static InputSectionBase<ELFT> *
> -getNonLayoutSection(std::vector<InputSectionBase<ELFT> *> &Vec) {
> - for (InputSectionBase<ELFT> *S : Vec)
> - if (!isa<LayoutInputSection<ELFT>>(S))
> - return S;
> - return nullptr;
> -}
> -
> -template <class T> static T *zero(T *Val) {
> - memset(Val, 0, sizeof(*Val));
> - return Val;
> -}
> -
> -template <class ELFT>
> -LayoutInputSection<ELFT>::LayoutInputSection(SymbolAssignment *Cmd)
> - : InputSectionBase<ELFT>(nullptr, zero(&Hdr),
> - InputSectionBase<ELFT>::Layout),
> - Cmd(Cmd) {
> - this->Live = true;
> - Hdr.sh_type = SHT_NOBITS;
> -}
> -
> -template <class ELFT>
> -bool LayoutInputSection<ELFT>::classof(const InputSectionBase<ELFT> *S) {
> - return S->SectionKind == InputSectionBase<ELFT>::Layout;
> -}
> -
> template <class ELFT>
> static bool compareName(InputSectionBase<ELFT> *A, InputSectionBase<ELFT> *B) {
> return A->getSectionName() < B->getSectionName();
> @@ -236,12 +188,13 @@ template <class ELFT>
> std::vector<InputSectionBase<ELFT> *>
> LinkerScript<ELFT>::createInputSectionList(OutputSectionCommand &OutCmd) {
> std::vector<InputSectionBase<ELFT> *> Ret;
> + DenseSet<InputSectionBase<ELFT> *> SectionIndex;
>
> for (const std::unique_ptr<BaseCommand> &Base : OutCmd.Commands) {
> if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base.get())) {
> if (shouldDefine<ELFT>(OutCmd))
> addSynthetic<ELFT>(OutCmd);
> - Ret.push_back(new (LAlloc.Allocate()) LayoutInputSection<ELFT>(OutCmd));
> + OutCmd->GoesAfter = Ret.empty() ? nullptr : Ret.back();
> continue;
> }
>
> @@ -253,7 +206,12 @@ LinkerScript<ELFT>::createInputSectionLi
> std::stable_sort(V.begin(), V.end(), getComparator<ELFT>(Cmd->SortInner));
> if (Cmd->SortOuter)
> std::stable_sort(V.begin(), V.end(), getComparator<ELFT>(Cmd->SortOuter));
> - Ret.insert(Ret.end(), V.begin(), V.end());
> +
> + // Add all input sections corresponding to rule 'Cmd' to
> + // resulting vector. We do not add duplicate input sections.
> + for (InputSectionBase<ELFT> *S : V)
> + if (SectionIndex.insert(S).second)
> + Ret.push_back(S);
> }
> return Ret;
> }
> @@ -284,13 +242,12 @@ void LinkerScript<ELFT>::createSections(
> }
>
> std::vector<InputSectionBase<ELFT> *> V = createInputSectionList(*Cmd);
> - InputSectionBase<ELFT> *Head = getNonLayoutSection<ELFT>(V);
> - if (!Head)
> + if (V.empty())
> continue;
>
> OutputSectionBase<ELFT> *OutSec;
> bool IsNew;
> - std::tie(OutSec, IsNew) = Factory.create(Head, Cmd->Name);
> + std::tie(OutSec, IsNew) = Factory.create(V.front(), Cmd->Name);
> if (IsNew)
> OutputSections->push_back(OutSec);
>
> @@ -298,8 +255,7 @@ void LinkerScript<ELFT>::createSections(
> for (InputSectionBase<ELFT> *Sec : V) {
> if (Subalign)
> Sec->Alignment = Subalign;
> - if (!Sec->OutSec)
> - OutSec->addSection(Sec);
> + OutSec->addSection(Sec);
> }
> }
> }
> @@ -359,31 +315,49 @@ void assignOffsets(OutputSectionCommand
> addStartEndSymbols(Cmd, Sec);
> return;
> }
> -
> typedef typename ELFT::uint uintX_t;
> uintX_t Off = 0;
> + auto ItCmd = Cmd->Commands.begin();
>
> - for (InputSection<ELFT> *I : OutSec->Sections) {
> - if (auto *L = dyn_cast<LayoutInputSection<ELFT>>(I)) {
> - uintX_t Value = L->Cmd->Expression(Sec->getVA() + Off) - Sec->getVA();
> - if (L->Cmd->Name == ".") {
> + // Assigns values to all symbols following the given
> + // input section 'D' in output section 'Sec'. When symbols
> + // are in the beginning of output section the value of 'D'
> + // is nullptr.
> + auto AssignSuccessors = [&](InputSectionData *D) {
> + for (; ItCmd != Cmd->Commands.end(); ++ItCmd) {
> + auto *AssignCmd = dyn_cast<SymbolAssignment>(ItCmd->get());
> + if (!AssignCmd)
> + continue;
> + if (D != AssignCmd->GoesAfter)
> + break;
> +
> + uintX_t Value = AssignCmd->Expression(Sec->getVA() + Off) - Sec->getVA();
> + if (AssignCmd->Name == ".") {
> + // Update to location counter means update to section size.
> Off = Value;
> - } else if (auto *Sym =
> - cast_or_null<DefinedSynthetic<ELFT>>(L->Cmd->Sym)) {
> - // shouldDefine could have returned false, so we need to check Sym,
> - // for non-null value.
> + Sec->setSize(Off);
> + continue;
> + }
> +
> + if (DefinedSynthetic<ELFT> *Sym =
> + cast_or_null<DefinedSynthetic<ELFT>>(AssignCmd->Sym)) {
> Sym->Section = OutSec;
> Sym->Value = Value;
> }
> - } else {
> - Off = alignTo(Off, I->Alignment);
> - I->OutSecOff = Off;
> - Off += I->getSize();
> }
> + };
> +
> + AssignSuccessors(nullptr);
> + for (InputSection<ELFT> *I : OutSec->Sections) {
> + Off = alignTo(Off, I->Alignment);
> + I->OutSecOff = Off;
> + Off += I->getSize();
> // Update section size inside for-loop, so that SIZEOF
> // works correctly in the case below:
> // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) }
> Sec->setSize(Off);
> + // Add symbols following current input section.
> + AssignSuccessors(I);
> }
> }
>
>
> Modified: lld/trunk/ELF/LinkerScript.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=280348&r1=280347&r2=280348&view=diff
> ==============================================================================
> --- lld/trunk/ELF/LinkerScript.h (original)
> +++ lld/trunk/ELF/LinkerScript.h Thu Sep 1 04:55:57 2016
> @@ -26,7 +26,7 @@ class SymbolBody;
> template <class ELFT> class InputSectionBase;
> template <class ELFT> class OutputSectionBase;
> template <class ELFT> class OutputSectionFactory;
> -template <class ELFT> class LayoutInputSection;
> +class InputSectionData;
>
> typedef std::function<uint64_t(uint64_t)> Expr;
>
> @@ -66,6 +66,7 @@ struct SymbolAssignment : BaseCommand {
> // Command attributes for PROVIDE, HIDDEN and PROVIDE_HIDDEN.
> bool Provide = false;
> bool Hidden = false;
> + InputSectionData *GoesAfter = nullptr;
> };
>
> // Linker scripts allow additional constraints to be put on ouput sections.
> @@ -178,8 +179,6 @@ private:
> std::vector<size_t> getPhdrIndices(StringRef SectionName);
> size_t getPhdrIndex(StringRef PhdrName);
>
> - llvm::SpecificBumpPtrAllocator<LayoutInputSection<ELFT>> LAlloc;
> -
> uintX_t Dot;
> };
>
>
> Modified: lld/trunk/ELF/OutputSections.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=280348&r1=280347&r2=280348&view=diff
> ==============================================================================
> --- lld/trunk/ELF/OutputSections.cpp (original)
> +++ lld/trunk/ELF/OutputSections.cpp Thu Sep 1 04:55:57 2016
> @@ -1825,8 +1825,6 @@ OutputSectionFactory<ELFT>::create(Input
> case InputSectionBase<ELFT>::MipsAbiFlags:
> Sec = new MipsAbiFlagsOutputSection<ELFT>();
> break;
> - case InputSectionBase<ELFT>::Layout:
> - llvm_unreachable("Invalid section type");
> }
> Out<ELFT>::Pool.emplace_back(Sec);
> return {Sec, true};
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list