[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