[lld] r296127 - Merge OutputSectionBase and OutputSection. NFC.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 24 10:47:30 PST 2017


Awesome! I really like this change. :)

On Fri, Feb 24, 2017 at 7:07 AM, Rafael Espindola via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> Author: rafael
> Date: Fri Feb 24 09:07:30 2017
> New Revision: 296127
>
> URL: http://llvm.org/viewvc/llvm-project?rev=296127&view=rev
> Log:
> Merge OutputSectionBase and OutputSection. NFC.
>
> Now that all special sections are SyntheticSections, we only need one
> OutputSection class.
>
> Modified:
>     lld/trunk/ELF/InputSection.cpp
>     lld/trunk/ELF/InputSection.h
>     lld/trunk/ELF/LinkerScript.cpp
>     lld/trunk/ELF/LinkerScript.h
>     lld/trunk/ELF/MapFile.cpp
>     lld/trunk/ELF/MapFile.h
>     lld/trunk/ELF/OutputSections.cpp
>     lld/trunk/ELF/OutputSections.h
>     lld/trunk/ELF/Relocations.cpp
>     lld/trunk/ELF/Relocations.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/SyntheticSections.h
>     lld/trunk/ELF/Target.cpp
>     lld/trunk/ELF/Thunks.h
>     lld/trunk/ELF/Writer.cpp
>     lld/trunk/ELF/Writer.h
>
> Modified: lld/trunk/ELF/InputSection.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/
> InputSection.cpp?rev=296127&r1=296126&r2=296127&view=diff
> ============================================================
> ==================
> --- lld/trunk/ELF/InputSection.cpp (original)
> +++ lld/trunk/ELF/InputSection.cpp Fri Feb 24 09:07:30 2017
> @@ -118,7 +118,7 @@ uint64_t InputSectionBase::getOffset(uin
>  }
>
>  template <class ELFT>
> -OutputSectionBase *InputSectionBase::getOutputSection() const {
> +OutputSection *InputSectionBase::getOutputSection() const {
>    if (auto *MS = dyn_cast<MergeInputSection<ELFT>>(this))
>      return MS->MergeSec ? MS->MergeSec->OutSec : nullptr;
>    if (auto *EH = dyn_cast<EhInputSection<ELFT>>(this))
> @@ -827,10 +827,10 @@ template InputSectionBase *InputSectionB
>  template InputSectionBase *InputSectionBase::getLinkOrderDep<ELF64LE>()
> const;
>  template InputSectionBase *InputSectionBase::getLinkOrderDep<ELF64BE>()
> const;
>
> -template OutputSectionBase *InputSectionBase::getOutputSection<ELF32LE>()
> const;
> -template OutputSectionBase *InputSectionBase::getOutputSection<ELF32BE>()
> const;
> -template OutputSectionBase *InputSectionBase::getOutputSection<ELF64LE>()
> const;
> -template OutputSectionBase *InputSectionBase::getOutputSection<ELF64BE>()
> const;
> +template OutputSection *InputSectionBase::getOutputSection<ELF32LE>()
> const;
> +template OutputSection *InputSectionBase::getOutputSection<ELF32BE>()
> const;
> +template OutputSection *InputSectionBase::getOutputSection<ELF64LE>()
> const;
> +template OutputSection *InputSectionBase::getOutputSection<ELF64BE>()
> const;
>
>  template InputSectionBase *InputSection::getRelocatedSection<ELF32LE>();
>  template InputSectionBase *InputSection::getRelocatedSection<ELF32BE>();
>
> Modified: lld/trunk/ELF/InputSection.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/
> InputSection.h?rev=296127&r1=296126&r2=296127&view=diff
> ============================================================
> ==================
> --- lld/trunk/ELF/InputSection.h (original)
> +++ lld/trunk/ELF/InputSection.h Fri Feb 24 09:07:30 2017
> @@ -31,8 +31,7 @@ template <class ELFT> class DefinedRegul
>  template <class ELFT> class EhFrameSection;
>  template <class ELFT> class MergeSyntheticSection;
>  template <class ELFT> class ObjectFile;
> -template <class ELFT> class OutputSection;
> -class OutputSectionBase;
> +class OutputSection;
>
>  // This corresponds to a section of an input file.
>  class InputSectionBase {
> @@ -78,7 +77,7 @@ public:
>                     uint64_t Entsize, uint32_t Link, uint32_t Info,
>                     uint64_t Addralign, ArrayRef<uint8_t> Data, StringRef
> Name,
>                     Kind SectionKind);
> -  OutputSectionBase *OutSec = nullptr;
> +  OutputSection *OutSec = nullptr;
>
>    // Relocations that refer to this section.
>    const void *FirstRelocation = nullptr;
> @@ -110,7 +109,7 @@ public:
>    // Returns the size of this section (even if this is a common or BSS.)
>    template <class ELFT> size_t getSize() const;
>
> -  template <class ELFT> OutputSectionBase *getOutputSection() const;
> +  template <class ELFT> OutputSection *getOutputSection() const;
>
>    template <class ELFT> ObjectFile<ELFT> *getFile() const;
>
>
> Modified: lld/trunk/ELF/LinkerScript.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/
> LinkerScript.cpp?rev=296127&r1=296126&r2=296127&view=diff
> ============================================================
> ==================
> --- lld/trunk/ELF/LinkerScript.cpp (original)
> +++ lld/trunk/ELF/LinkerScript.cpp Fri Feb 24 09:07:30 2017
> @@ -72,7 +72,7 @@ template <class ELFT> static SymbolBody
>  template <class ELFT> static SymbolBody *addSynthetic(SymbolAssignment
> *Cmd) {
>    Symbol *Sym;
>    uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
> -  const OutputSectionBase *Sec =
> +  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,
> @@ -397,7 +397,7 @@ void LinkerScript<ELFT>::addOrphanSectio
>        Factory.addInputSec(S, getOutputSectionName(S->Name));
>  }
>
> -template <class ELFT> static bool isTbss(OutputSectionBase *Sec) {
> +template <class ELFT> static bool isTbss(OutputSection *Sec) {
>    return (Sec->Flags & SHF_TLS) && Sec->Type == SHT_NOBITS;
>  }
>
> @@ -438,16 +438,11 @@ template <class ELFT> void LinkerScript<
>  template <class ELFT> void LinkerScript<ELFT>::flush() {
>    if (!CurOutSec || !AlreadyOutputOS.insert(CurOutSec).second)
>      return;
> -  if (auto *OutSec = dyn_cast<OutputSection<ELFT>>(CurOutSec)) {
> -    for (InputSection *I : OutSec->Sections)
> -      output(I);
> -  } else {
> -    Dot += CurOutSec->Size;
> -  }
> +  for (InputSection *I : CurOutSec->Sections)
> +    output(I);
>  }
>
> -template <class ELFT>
> -void LinkerScript<ELFT>::switchTo(OutputSectionBase *Sec) {
> +template <class ELFT> void LinkerScript<ELFT>::switchTo(OutputSection
> *Sec) {
>    if (CurOutSec == Sec)
>      return;
>    if (AlreadyOutputOS.count(Sec))
> @@ -512,12 +507,12 @@ template <class ELFT> void LinkerScript<
>  }
>
>  template <class ELFT>
> -static OutputSectionBase *
> -findSection(StringRef Name, const std::vector<OutputSectionBase *>
> &Sections) {
> +static OutputSection *
> +findSection(StringRef Name, const std::vector<OutputSection *> &Sections)
> {
>    auto End = Sections.end();
> -  auto HasName = [=](OutputSectionBase *Sec) { return Sec->Name == Name;
> };
> +  auto HasName = [=](OutputSection *Sec) { return Sec->Name == Name; };
>    auto I = std::find_if(Sections.begin(), End, HasName);
> -  std::vector<OutputSectionBase *> Ret;
> +  std::vector<OutputSection *> Ret;
>    if (I == End)
>      return nullptr;
>    assert(std::find_if(I + 1, End, HasName) == End);
> @@ -529,7 +524,7 @@ findSection(StringRef Name, const std::v
>  // returned. Otherwise, a nullptr is returned.
>  template <class ELFT>
>  MemoryRegion *LinkerScript<ELFT>::findMemoryRegion(OutputSectionCommand
> *Cmd,
> -                                                   OutputSectionBase
> *Sec) {
> +                                                   OutputSection *Sec) {
>    // If a memory region name was specified in the output section command,
>    // then try to find that region first.
>    if (!Cmd->MemoryRegionName.empty()) {
> @@ -568,7 +563,7 @@ void LinkerScript<ELFT>::assignOffsets(O
>      uintX_t D = Dot;
>      LMAOffset = [=] { return Cmd->LMAExpr(D) - D; };
>    }
> -  OutputSectionBase *Sec = findSection<ELFT>(Cmd->Name, *OutputSections);
> +  OutputSection *Sec = findSection<ELFT>(Cmd->Name, *OutputSections);
>    if (!Sec)
>      return;
>
> @@ -634,8 +629,7 @@ template <class ELFT> void LinkerScript<
>      auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
>      if (!Cmd)
>        continue;
> -    if (OutputSectionBase *Sec =
> -            findSection<ELFT>(Cmd->Name, *OutputSections)) {
> +    if (OutputSection *Sec = findSection<ELFT>(Cmd->Name,
> *OutputSections)) {
>        Flags = Sec->Flags;
>        Type = Sec->Type;
>        continue;
> @@ -644,7 +638,7 @@ template <class ELFT> void LinkerScript<
>      if (isAllSectionDescription(*Cmd))
>        continue;
>
> -    auto *OutSec = make<OutputSection<ELFT>>(Cmd->Name, Type, Flags);
> +    auto *OutSec = make<OutputSection>(Cmd->Name, Type, Flags);
>      OutputSections->push_back(OutSec);
>    }
>  }
> @@ -751,7 +745,7 @@ template <class ELFT> void LinkerScript<
>        ++CmdIndex;
>    }
>
> -  for (OutputSectionBase *Sec : *OutputSections) {
> +  for (OutputSection *Sec : *OutputSections) {
>      StringRef Name = Sec->Name;
>
>      // Find the last spot where we can insert a command and still get the
> @@ -794,7 +788,7 @@ void LinkerScript<ELFT>::assignAddresses
>    // 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<OutputSectionBase>("", 0, SHF_ALLOC);
> +  auto *Aether = make<OutputSection>("", 0, SHF_ALLOC);
>    Aether->SectionIndex = 1;
>    switchTo(Aether);
>
> @@ -814,7 +808,7 @@ void LinkerScript<ELFT>::assignAddresses
>    }
>
>    uintX_t MinVA = std::numeric_limits<uintX_t>::max();
> -  for (OutputSectionBase *Sec : *OutputSections) {
> +  for (OutputSection *Sec : *OutputSections) {
>      if (Sec->Flags & SHF_ALLOC)
>        MinVA = std::min<uint64_t>(MinVA, Sec->Addr);
>      else
> @@ -846,7 +840,7 @@ template <class ELFT> std::vector<PhdrEn
>    }
>
>    // Add output sections to program headers.
> -  for (OutputSectionBase *Sec : *OutputSections) {
> +  for (OutputSection *Sec : *OutputSections) {
>      if (!(Sec->Flags & SHF_ALLOC))
>        break;
>
> @@ -936,11 +930,11 @@ template <class ELFT> bool LinkerScript<
>  }
>
>  template <class ELFT>
> -const OutputSectionBase *LinkerScript<ELFT>::getOutputSection(const
> Twine &Loc,
> -                                                              StringRef
> Name) {
> -  static OutputSectionBase FakeSec("", 0, 0);
> +const OutputSection *LinkerScript<ELFT>::getOutputSection(const Twine
> &Loc,
> +                                                          StringRef Name)
> {
> +  static OutputSection FakeSec("", 0, 0);
>
> -  for (OutputSectionBase *Sec : *OutputSections)
> +  for (OutputSection *Sec : *OutputSections)
>      if (Sec->Name == Name)
>        return Sec;
>
> @@ -956,7 +950,7 @@ const OutputSectionBase *LinkerScript<EL
>  // be empty. That is why this function is different from
> getOutputSection().
>  template <class ELFT>
>  uint64_t LinkerScript<ELFT>::getOutputSectionSize(StringRef Name) {
> -  for (OutputSectionBase *Sec : *OutputSections)
> +  for (OutputSection *Sec : *OutputSections)
>      if (Sec->Name == Name)
>        return Sec->Size;
>    return 0;
> @@ -988,7 +982,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 OutputSectionBase *LinkerScript<ELFT>::getSymbolSection(StringRef
> S) {
> +const OutputSection *LinkerScript<ELFT>::getSymbolSection(StringRef S) {
>    if (SymbolBody *Sym = Symtab<ELFT>::X->find(S))
>      return SymbolTableSection<ELFT>::getOutputSection(Sym);
>    return CurOutSec;
> @@ -1646,7 +1640,7 @@ Expr ScriptParser::readExpr() {
>  static Expr combine(StringRef Op, Expr L, Expr R) {
>    auto IsAbs = [=] { return L.IsAbsolute() && R.IsAbsolute(); };
>    auto GetOutSec = [=] {
> -    const OutputSectionBase *S = L.Section();
> +    const 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=296127&r1=296126&r2=296127&view=diff
> ============================================================
> ==================
> --- lld/trunk/ELF/LinkerScript.h (original)
> +++ lld/trunk/ELF/LinkerScript.h Fri Feb 24 09:07:30 2017
> @@ -33,7 +33,7 @@ class ScriptParser;
>  class SymbolBody;
>  class InputSectionBase;
>  class InputSection;
> -class OutputSectionBase;
> +class OutputSection;
>  template <class ELFT> class OutputSectionFactory;
>  class InputSectionBase;
>
> @@ -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 OutputSectionBase *()> Section;
> +  std::function<const 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 OutputSectionBase *()> Section)
> +       std::function<const OutputSection *()> Section)
>        : Val(Val), IsAbsolute(IsAbsolute), Section(Section) {}
>    template <typename T>
>    Expr(T V) : Expr(V, [] { return true; }, [] { return nullptr; }) {}
> @@ -213,9 +213,9 @@ public:
>    virtual uint64_t getSymbolValue(const Twine &Loc, StringRef S) = 0;
>    virtual bool isDefined(StringRef S) = 0;
>    virtual bool isAbsolute(StringRef S) = 0;
> -  virtual const OutputSectionBase *getSymbolSection(StringRef S) = 0;
> -  virtual const OutputSectionBase *getOutputSection(const Twine &Loc,
> -                                                    StringRef S) = 0;
> +  virtual const OutputSection *getSymbolSection(StringRef S) = 0;
> +  virtual const OutputSection *getOutputSection(const Twine &Loc,
> +                                                StringRef S) = 0;
>    virtual uint64_t getOutputSectionSize(StringRef S) = 0;
>  };
>
> @@ -268,12 +268,11 @@ public:
>    uint64_t getSymbolValue(const Twine &Loc, StringRef S) override;
>    bool isDefined(StringRef S) override;
>    bool isAbsolute(StringRef S) override;
> -  const OutputSectionBase *getSymbolSection(StringRef S) override;
> -  const OutputSectionBase *getOutputSection(const Twine &Loc,
> -                                            StringRef S) override;
> +  const OutputSection *getSymbolSection(StringRef S) override;
> +  const OutputSection *getOutputSection(const Twine &Loc, StringRef S)
> override;
>    uint64_t getOutputSectionSize(StringRef S) override;
>
> -  std::vector<OutputSectionBase *> *OutputSections;
> +  std::vector<OutputSection *> *OutputSections;
>
>    int getSectionIndex(StringRef Name);
>
> @@ -294,19 +293,18 @@ private:
>    std::vector<size_t> getPhdrIndices(StringRef SectionName);
>    size_t getPhdrIndex(const Twine &Loc, StringRef PhdrName);
>
> -  MemoryRegion *findMemoryRegion(OutputSectionCommand *Cmd,
> -                                 OutputSectionBase *Sec);
> +  MemoryRegion *findMemoryRegion(OutputSectionCommand *Cmd,
> OutputSection *Sec);
>
>    uintX_t Dot;
>    std::function<uint64_t()> LMAOffset;
> -  OutputSectionBase *CurOutSec = nullptr;
> +  OutputSection *CurOutSec = nullptr;
>    MemoryRegion *CurMemRegion = nullptr;
>    uintX_t ThreadBssOffset = 0;
> -  void switchTo(OutputSectionBase *Sec);
> +  void switchTo(OutputSection *Sec);
>    void flush();
>    void output(InputSection *Sec);
>    void process(BaseCommand &Base);
> -  llvm::DenseSet<OutputSectionBase *> AlreadyOutputOS;
> +  llvm::DenseSet<OutputSection *> AlreadyOutputOS;
>    llvm::DenseSet<InputSectionBase *> AlreadyOutputIS;
>  };
>
>
> Modified: lld/trunk/ELF/MapFile.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/MapFile.
> cpp?rev=296127&r1=296126&r2=296127&view=diff
> ============================================================
> ==================
> --- lld/trunk/ELF/MapFile.cpp (original)
> +++ lld/trunk/ELF/MapFile.cpp Fri Feb 24 09:07:30 2017
> @@ -95,26 +95,25 @@ static void writeInputSection(raw_fd_ost
>
>  template <class ELFT>
>  static void writeMapFile2(raw_fd_ostream &OS,
> -                          ArrayRef<OutputSectionBase *> OutputSections) {
> +                          ArrayRef<OutputSection *> OutputSections) {
>    int Width = ELFT::Is64Bits ? 16 : 8;
>
>    OS << left_justify("Address", Width) << ' ' << left_justify("Size",
> Width)
>       << " Align Out     In      File    Symbol\n";
>
> -  for (OutputSectionBase *Sec : OutputSections) {
> +  for (OutputSection *Sec : OutputSections) {
>      writeOutSecLine(OS, Width, Sec->Addr, Sec->Size, Sec->Addralign,
> Sec->Name);
>      OS << '\n';
>
>      StringRef PrevName = "";
> -    Sec->forEachInputSection([&](InputSectionBase *S) {
> -      if (const auto *IS = dyn_cast<InputSection>(S))
> -        writeInputSection<ELFT>(OS, IS, PrevName);
> -    });
> +    for (InputSection *IS : Sec->Sections) {
> +      writeInputSection<ELFT>(OS, IS, PrevName);
> +    }
>    }
>  }
>
>  template <class ELFT>
> -void elf::writeMapFile(ArrayRef<OutputSectionBase *> OutputSections) {
> +void elf::writeMapFile(ArrayRef<OutputSection *> OutputSections) {
>    if (Config->MapFile.empty())
>      return;
>
> @@ -126,7 +125,7 @@ void elf::writeMapFile(ArrayRef<OutputSe
>      writeMapFile2<ELFT>(OS, OutputSections);
>  }
>
> -template void elf::writeMapFile<ELF32LE>(ArrayRef<OutputSectionBase *>);
> -template void elf::writeMapFile<ELF32BE>(ArrayRef<OutputSectionBase *>);
> -template void elf::writeMapFile<ELF64LE>(ArrayRef<OutputSectionBase *>);
> -template void elf::writeMapFile<ELF64BE>(ArrayRef<OutputSectionBase *>);
> +template void elf::writeMapFile<ELF32LE>(ArrayRef<OutputSection *>);
> +template void elf::writeMapFile<ELF32BE>(ArrayRef<OutputSection *>);
> +template void elf::writeMapFile<ELF64LE>(ArrayRef<OutputSection *>);
> +template void elf::writeMapFile<ELF64BE>(ArrayRef<OutputSection *>);
>
> Modified: lld/trunk/ELF/MapFile.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/MapFile.
> h?rev=296127&r1=296126&r2=296127&view=diff
> ============================================================
> ==================
> --- lld/trunk/ELF/MapFile.h (original)
> +++ lld/trunk/ELF/MapFile.h Fri Feb 24 09:07:30 2017
> @@ -15,7 +15,7 @@
>  namespace lld {
>  namespace elf {
>  template <class ELFT>
> -void writeMapFile(llvm::ArrayRef<OutputSectionBase *> OutputSections);
> +void writeMapFile(llvm::ArrayRef<OutputSection *> OutputSections);
>  }
>  }
>
>
> Modified: lld/trunk/ELF/OutputSections.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/
> OutputSections.cpp?rev=296127&r1=296126&r2=296127&view=diff
> ============================================================
> ==================
> --- lld/trunk/ELF/OutputSections.cpp (original)
> +++ lld/trunk/ELF/OutputSections.cpp Fri Feb 24 09:07:30 2017
> @@ -30,15 +30,7 @@ using namespace llvm::ELF;
>  using namespace lld;
>  using namespace lld::elf;
>
> -OutputSectionBase::OutputSectionBase(StringRef Name, uint32_t Type,
> -                                     uint64_t Flags)
> -    : Name(Name) {
> -  this->Type = Type;
> -  this->Flags = Flags;
> -  this->Addralign = 1;
> -}
> -
> -uint32_t OutputSectionBase::getPhdrFlags() const {
> +uint32_t OutputSection::getPhdrFlags() const {
>    uint32_t Ret = PF_R;
>    if (Flags & SHF_WRITE)
>      Ret |= PF_W;
> @@ -48,7 +40,7 @@ uint32_t OutputSectionBase::getPhdrFlags
>  }
>
>  template <class ELFT>
> -void OutputSectionBase::writeHeaderTo(typename ELFT::Shdr *Shdr) {
> +void OutputSection::writeHeaderTo(typename ELFT::Shdr *Shdr) {
>    Shdr->sh_entsize = Entsize;
>    Shdr->sh_addralign = Addralign;
>    Shdr->sh_type = Type;
> @@ -78,10 +70,24 @@ template <class ELFT> static uint64_t ge
>    }
>  }
>
> -template <class ELFT>
> -OutputSection<ELFT>::OutputSection(StringRef Name, uint32_t Type,
> uintX_t Flags)
> -    : OutputSectionBase(Name, Type, Flags) {
> -  this->Entsize = getEntsize<ELFT>(Type);
> +OutputSection::OutputSection(StringRef Name, uint32_t Type, uint64_t
> Flags)
> +    : Name(Name), Addralign(1), Flags(Flags), Type(Type) {
> +  switch (Config->EKind) {
> +  case ELFNoneKind:
> +    llvm_unreachable("unknown kind");
> +  case ELF32LEKind:
> +    this->Entsize = getEntsize<ELF32LE>(Type);
> +    break;
> +  case ELF32BEKind:
> +    this->Entsize = getEntsize<ELF32BE>(Type);
> +    break;
> +  case ELF64LEKind:
> +    this->Entsize = getEntsize<ELF64LE>(Type);
> +    break;
> +  case ELF64BEKind:
> +    this->Entsize = getEntsize<ELF64BE>(Type);
> +    break;
> +  }
>  }
>
>  template <typename ELFT>
> @@ -92,18 +98,18 @@ static bool compareByFilePosition(InputS
>      return false;
>    auto *LA = cast<InputSection>(A->template getLinkOrderDep<ELFT>());
>    auto *LB = cast<InputSection>(B->template getLinkOrderDep<ELFT>());
> -  OutputSectionBase *AOut = LA->OutSec;
> -  OutputSectionBase *BOut = LB->OutSec;
> +  OutputSection *AOut = LA->OutSec;
> +  OutputSection *BOut = LB->OutSec;
>    if (AOut != BOut)
>      return AOut->SectionIndex < BOut->SectionIndex;
>    return LA->OutSecOff < LB->OutSecOff;
>  }
>
> -template <class ELFT> void OutputSection<ELFT>::finalize() {
> +template <class ELFT> void OutputSection::finalize() {
>    if ((this->Flags & SHF_LINK_ORDER) && !this->Sections.empty()) {
>      std::sort(Sections.begin(), Sections.end(),
> compareByFilePosition<ELFT>);
>      Size = 0;
> -    assignOffsets();
> +    assignOffsets<ELFT>();
>
>      // We must preserve the link order dependency of sections with the
>      // SHF_LINK_ORDER flag. The dependency is indicated by the sh_link
> field. We
> @@ -128,8 +134,7 @@ template <class ELFT> void OutputSection
>    this->Info = S->OutSec->SectionIndex;
>  }
>
> -template <class ELFT>
> -void OutputSection<ELFT>::addSection(InputSectionBase *C) {
> +void OutputSection::addSection(InputSectionBase *C) {
>    assert(C->Live);
>    auto *S = cast<InputSection>(C);
>    Sections.push_back(S);
> @@ -141,17 +146,10 @@ void OutputSection<ELFT>::addSection(Inp
>      this->Entsize = S->Entsize;
>  }
>
> -template <class ELFT>
> -void OutputSection<ELFT>::forEachInputSection(
> -    std::function<void(InputSectionBase *)> F) {
> -  for (InputSection *S : Sections)
> -    F(S);
> -}
> -
>  // This function is called after we sort input sections
>  // and scan relocations to setup sections' offsets.
> -template <class ELFT> void OutputSection<ELFT>::assignOffsets() {
> -  uintX_t Off = this->Size;
> +template <class ELFT> void OutputSection::assignOffsets() {
> +  uint64_t Off = this->Size;
>    for (InputSection *S : Sections) {
>      Off = alignTo(Off, S->Alignment);
>      S->OutSecOff = Off;
> @@ -160,8 +158,7 @@ template <class ELFT> void OutputSection
>    this->Size = Off;
>  }
>
> -template <class ELFT>
> -void OutputSection<ELFT>::sort(std::function<int(InputSectionBase *S)>
> Order) {
> +void OutputSection::sort(std::function<int(InputSectionBase *S)> Order) {
>    typedef std::pair<unsigned, InputSection *> Pair;
>    auto Comp = [](const Pair &A, const Pair &B) { return A.first <
> B.first; };
>
> @@ -180,7 +177,7 @@ void OutputSection<ELFT>::sort(std::func
>  // because the compiler keeps the original initialization order in a
>  // translation unit and we need to respect that.
>  // For more detail, read the section of the GCC's manual about
> init_priority.
> -template <class ELFT> void OutputSection<ELFT>::sortInitFini() {
> +void OutputSection::sortInitFini() {
>    // Sort sections by priority.
>    sort([](InputSectionBase *S) { return getPriority(S->Name); });
>  }
> @@ -239,7 +236,7 @@ static bool compCtors(const InputSection
>  // Sorts input sections by the special rules for .ctors and .dtors.
>  // Unfortunately, the rules are different from the one for
> .{init,fini}_array.
>  // Read the comment above.
> -template <class ELFT> void OutputSection<ELFT>::sortCtorsDtors() {
> +void OutputSection::sortCtorsDtors() {
>    std::stable_sort(Sections.begin(), Sections.end(), compCtors);
>  }
>
> @@ -254,7 +251,7 @@ void fill(uint8_t *Buf, size_t Size, uin
>    memcpy(Buf + I, V, Size - I);
>  }
>
> -template <class ELFT> void OutputSection<ELFT>::writeTo(uint8_t *Buf) {
> +template <class ELFT> void OutputSection::writeTo(uint8_t *Buf) {
>    Loc = Buf;
>    if (uint32_t Filler = Script<ELFT>::X->getFiller(this->Name))
>      fill(Buf, this->Size, Filler);
> @@ -331,7 +328,7 @@ static SectionKey createKey(InputSection
>
>  template <class ELFT>
>  OutputSectionFactory<ELFT>::OutputSectionFactory(
> -    std::vector<OutputSectionBase *> &OutputSections)
> +    std::vector<OutputSection *> &OutputSections)
>      : OutputSections(OutputSections) {}
>
>  static uint64_t getIncompatibleFlags(uint64_t Flags) {
> @@ -367,7 +364,7 @@ void OutputSectionFactory<ELFT>::addInpu
>
>    SectionKey Key = createKey<ELFT>(IS, OutsecName);
>    uintX_t Flags = getOutFlags<ELFT>(IS);
> -  OutputSectionBase *&Sec = Map[Key];
> +  OutputSection *&Sec = Map[Key];
>    if (Sec) {
>      if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(IS->
> Flags))
>        error("Section has flags incompatible with others with the same
> name " +
> @@ -386,7 +383,7 @@ void OutputSectionFactory<ELFT>::addInpu
>        In<ELFT>::EhFrame->addSection(IS);
>        return;
>      }
> -    Sec = make<OutputSection<ELFT>>(Key.Name, Type, Flags);
> +    Sec = make<OutputSection>(Key.Name, Type, Flags);
>      OutputSections.push_back(Sec);
>    }
>
> @@ -416,15 +413,25 @@ bool DenseMapInfo<SectionKey>::isEqual(c
>  namespace lld {
>  namespace elf {
>
> -template void OutputSectionBase::writeHeaderTo<ELF32LE>(ELF32LE::Shdr
> *Shdr);
> -template void OutputSectionBase::writeHeaderTo<ELF32BE>(ELF32BE::Shdr
> *Shdr);
> -template void OutputSectionBase::writeHeaderTo<ELF64LE>(ELF64LE::Shdr
> *Shdr);
> -template void OutputSectionBase::writeHeaderTo<ELF64BE>(ELF64BE::Shdr
> *Shdr);
> -
> -template class OutputSection<ELF32LE>;
> -template class OutputSection<ELF32BE>;
> -template class OutputSection<ELF64LE>;
> -template class OutputSection<ELF64BE>;
> +template void OutputSection::writeHeaderTo<ELF32LE>(ELF32LE::Shdr *Shdr);
> +template void OutputSection::writeHeaderTo<ELF32BE>(ELF32BE::Shdr *Shdr);
> +template void OutputSection::writeHeaderTo<ELF64LE>(ELF64LE::Shdr *Shdr);
> +template void OutputSection::writeHeaderTo<ELF64BE>(ELF64BE::Shdr *Shdr);
> +
> +template void OutputSection::assignOffsets<ELF32LE>();
> +template void OutputSection::assignOffsets<ELF32BE>();
> +template void OutputSection::assignOffsets<ELF64LE>();
> +template void OutputSection::assignOffsets<ELF64BE>();
> +
> +template void OutputSection::finalize<ELF32LE>();
> +template void OutputSection::finalize<ELF32BE>();
> +template void OutputSection::finalize<ELF64LE>();
> +template void OutputSection::finalize<ELF64BE>();
> +
> +template void OutputSection::writeTo<ELF32LE>(uint8_t *Buf);
> +template void OutputSection::writeTo<ELF32BE>(uint8_t *Buf);
> +template void OutputSection::writeTo<ELF64LE>(uint8_t *Buf);
> +template void OutputSection::writeTo<ELF64BE>(uint8_t *Buf);
>
>  template class OutputSectionFactory<ELF32LE>;
>  template class OutputSectionFactory<ELF32BE>;
>
> Modified: lld/trunk/ELF/OutputSections.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/
> OutputSections.h?rev=296127&r1=296126&r2=296127&view=diff
> ============================================================
> ==================
> --- lld/trunk/ELF/OutputSections.h (original)
> +++ lld/trunk/ELF/OutputSections.h Fri Feb 24 09:07:30 2017
> @@ -27,34 +27,23 @@ template <class ELFT> class EhInputSecti
>  class InputSection;
>  class InputSectionBase;
>  template <class ELFT> class MergeInputSection;
> -template <class ELFT> class OutputSection;
> +class OutputSection;
>  template <class ELFT> class ObjectFile;
>  template <class ELFT> class SharedFile;
>  template <class ELFT> class SharedSymbol;
>  template <class ELFT> class DefinedRegular;
>
>  // This represents a section in an output file.
> -// Different sub classes represent different types of sections. Some
> contain
> -// input sections, others are created by the linker.
> +// It is composed of multiple InputSections.
>  // The writer creates multiple OutputSections and assign them unique,
>  // non-overlapping file offsets and VAs.
> -class OutputSectionBase {
> +class OutputSection final {
>  public:
> -  enum Kind {
> -    Base,
> -    Regular,
> -  };
> +  OutputSection(StringRef Name, uint32_t Type, uint64_t Flags);
>
> -  OutputSectionBase(StringRef Name, uint32_t Type, uint64_t Flags);
>    uint64_t getLMA() const { return Addr + LMAOffset; }
>    template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *SHdr);
>
> -  virtual void addSection(InputSectionBase *C) {}
> -  virtual Kind getKind() const { return Base; }
> -  static bool classof(const OutputSectionBase *B) {
> -    return B->getKind() == Base;
> -  }
> -
>    unsigned SectionIndex;
>
>    uint32_t getPhdrFlags() const;
> @@ -74,13 +63,7 @@ public:
>    // between their file offsets should be equal to difference between
> their
>    // virtual addresses. To compute some section offset we use the
> following
>    // formula: Off = Off_first + VA - VA_first.
> -  OutputSectionBase *FirstInPtLoad = nullptr;
> -
> -  virtual void finalize() {}
> -  virtual void forEachInputSection(std::function<void(InputSectionBase
> *)> F) {}
> -  virtual void assignOffsets() {}
> -  virtual void writeTo(uint8_t *Buf) {}
> -  virtual ~OutputSectionBase() = default;
> +  OutputSection *FirstInPtLoad = nullptr;
>
>    StringRef Name;
>
> @@ -96,29 +79,14 @@ public:
>    uint32_t Type = 0;
>    uint32_t Info = 0;
>    uint32_t Link = 0;
> -};
> -
> -template <class ELFT> class OutputSection final : public
> OutputSectionBase {
>
> -public:
> -  typedef typename ELFT::Shdr Elf_Shdr;
> -  typedef typename ELFT::Sym Elf_Sym;
> -  typedef typename ELFT::Rel Elf_Rel;
> -  typedef typename ELFT::Rela Elf_Rela;
> -  typedef typename ELFT::uint uintX_t;
> -  OutputSection(StringRef Name, uint32_t Type, uintX_t Flags);
> -  void addSection(InputSectionBase *C) override;
> +  void addSection(InputSectionBase *C);
>    void sort(std::function<int(InputSectionBase *S)> Order);
>    void sortInitFini();
>    void sortCtorsDtors();
> -  void writeTo(uint8_t *Buf) override;
> -  void finalize() override;
> -  void forEachInputSection(std::function<void(InputSectionBase *)> F)
> override;
> -  void assignOffsets() override;
> -  Kind getKind() const override { return Regular; }
> -  static bool classof(const OutputSectionBase *B) {
> -    return B->getKind() == Regular;
> -  }
> +  template <class ELFT> void writeTo(uint8_t *Buf);
> +  template <class ELFT> void finalize();
> +  template <class ELFT> void assignOffsets();
>    std::vector<InputSection *> Sections;
>
>    // Location in the output buffer.
> @@ -133,17 +101,17 @@ template <class ELFT> struct Out {
>    typedef typename ELFT::Phdr Elf_Phdr;
>
>    static uint8_t First;
> -  static OutputSection<ELFT> *Bss;
> -  static OutputSection<ELFT> *BssRelRo;
> -  static OutputSectionBase *Opd;
> +  static OutputSection *Bss;
> +  static OutputSection *BssRelRo;
> +  static OutputSection *Opd;
>    static uint8_t *OpdBuf;
>    static PhdrEntry *TlsPhdr;
> -  static OutputSectionBase *DebugInfo;
> -  static OutputSectionBase *ElfHeader;
> -  static OutputSectionBase *ProgramHeaders;
> -  static OutputSectionBase *PreinitArray;
> -  static OutputSectionBase *InitArray;
> -  static OutputSectionBase *FiniArray;
> +  static OutputSection *DebugInfo;
> +  static OutputSection *ElfHeader;
> +  static OutputSection *ProgramHeaders;
> +  static OutputSection *PreinitArray;
> +  static OutputSection *InitArray;
> +  static OutputSection *FiniArray;
>  };
>
>  struct SectionKey {
> @@ -174,13 +142,13 @@ template <class ELFT> class OutputSectio
>    typedef typename ELFT::uint uintX_t;
>
>  public:
> -  OutputSectionFactory(std::vector<OutputSectionBase *> &OutputSections);
> +  OutputSectionFactory(std::vector<OutputSection *> &OutputSections);
>    ~OutputSectionFactory();
>    void addInputSec(InputSectionBase *IS, StringRef OutsecName);
>
>  private:
> -  llvm::SmallDenseMap<SectionKey, OutputSectionBase *> Map;
> -  std::vector<OutputSectionBase *> &OutputSections;
> +  llvm::SmallDenseMap<SectionKey, OutputSection *> Map;
> +  std::vector<OutputSection *> &OutputSections;
>  };
>
>  template <class ELFT> uint64_t getHeaderSize() {
> @@ -190,17 +158,17 @@ template <class ELFT> uint64_t getHeader
>  }
>
>  template <class ELFT> uint8_t Out<ELFT>::First;
> -template <class ELFT> OutputSection<ELFT> *Out<ELFT>::Bss;
> -template <class ELFT> OutputSection<ELFT> *Out<ELFT>::BssRelRo;
> -template <class ELFT> OutputSectionBase *Out<ELFT>::Opd;
> +template <class ELFT> OutputSection *Out<ELFT>::Bss;
> +template <class ELFT> OutputSection *Out<ELFT>::BssRelRo;
> +template <class ELFT> OutputSection *Out<ELFT>::Opd;
>  template <class ELFT> uint8_t *Out<ELFT>::OpdBuf;
>  template <class ELFT> PhdrEntry *Out<ELFT>::TlsPhdr;
> -template <class ELFT> OutputSectionBase *Out<ELFT>::DebugInfo;
> -template <class ELFT> OutputSectionBase *Out<ELFT>::ElfHeader;
> -template <class ELFT> OutputSectionBase *Out<ELFT>::ProgramHeaders;
> -template <class ELFT> OutputSectionBase *Out<ELFT>::PreinitArray;
> -template <class ELFT> OutputSectionBase *Out<ELFT>::InitArray;
> -template <class ELFT> OutputSectionBase *Out<ELFT>::FiniArray;
> +template <class ELFT> OutputSection *Out<ELFT>::DebugInfo;
> +template <class ELFT> OutputSection *Out<ELFT>::ElfHeader;
> +template <class ELFT> OutputSection *Out<ELFT>::ProgramHeaders;
> +template <class ELFT> OutputSection *Out<ELFT>::PreinitArray;
> +template <class ELFT> OutputSection *Out<ELFT>::InitArray;
> +template <class ELFT> OutputSection *Out<ELFT>::FiniArray;
>  } // namespace elf
>  } // namespace lld
>
>
> Modified: lld/trunk/ELF/Relocations.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/
> Relocations.cpp?rev=296127&r1=296126&r2=296127&view=diff
> ============================================================
> ==================
> --- lld/trunk/ELF/Relocations.cpp (original)
> +++ lld/trunk/ELF/Relocations.cpp Fri Feb 24 09:07:30 2017
> @@ -485,7 +485,7 @@ template <class ELFT> static void addCop
>    // 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(SS);
> -  OutputSection<ELFT> *OSec = IsReadOnly ? Out<ELFT>::BssRelRo :
> Out<ELFT>::Bss;
> +  OutputSection *OSec = IsReadOnly ? Out<ELFT>::BssRelRo : Out<ELFT>::Bss;
>
>    // Create a SyntheticSection in Out to hold the .bss and the Copy Reloc.
>    auto *ISec =
> @@ -866,7 +866,7 @@ template <class ELFT> void scanRelocatio
>  // offsets.
>  // This may invalidate any output section offsets stored outside of
> InputSection
>  template <class ELFT>
> -static void mergeThunks(OutputSection<ELFT> *OS,
> +static void mergeThunks(OutputSection *OS,
>                          std::vector<ThunkSection<ELFT> *> &Thunks) {
>    // Order Thunks in ascending OutSecOff
>    auto ThunkCmp = [](const ThunkSection<ELFT> *A, const
> ThunkSection<ELFT> *B) {
> @@ -893,7 +893,7 @@ static void mergeThunks(OutputSection<EL
>               Thunks.end(), std::back_inserter(Tmp), MergeCmp);
>    OS->Sections = std::move(Tmp);
>    OS->Size = 0;
> -  OS->assignOffsets();
> +  OS->assignOffsets<ELFT>();
>  }
>
>  // Process all relocations from the InputSections that have been assigned
> @@ -907,14 +907,13 @@ static void mergeThunks(OutputSection<EL
>  // FIXME: All Thunks are assumed to be in range of the relocation. Range
>  // extension Thunks are not yet supported.
>  template <class ELFT>
> -void createThunks(ArrayRef<OutputSectionBase *> OutputSections) {
> +void createThunks(ArrayRef<OutputSection *> OutputSections) {
>    // Track Symbols that already have a Thunk
>    DenseMap<SymbolBody *, Thunk<ELFT> *> ThunkedSymbols;
>    // Track InputSections that have a ThunkSection placed in front
>    DenseMap<InputSection *, ThunkSection<ELFT> *> ThunkedSections;
>    // Track the ThunksSections that need to be inserted into an
> OutputSection
> -  std::map<OutputSection<ELFT> *, std::vector<ThunkSection<ELFT> *>>
> -      ThunkSections;
> +  std::map<OutputSection *, std::vector<ThunkSection<ELFT> *>>
> ThunkSections;
>
>    // Find or create a Thunk for Body for relocation Type
>    auto GetThunk = [&](SymbolBody &Body, uint32_t Type) {
> @@ -925,11 +924,11 @@ void createThunks(ArrayRef<OutputSection
>    };
>
>    // Find or create a ThunkSection to be placed immediately before IS
> -  auto GetISThunkSec = [&](InputSection *IS, OutputSection<ELFT> *OS) {
> +  auto GetISThunkSec = [&](InputSection *IS, OutputSection *OS) {
>      ThunkSection<ELFT> *TS = ThunkedSections.lookup(IS);
>      if (TS)
>        return TS;
> -    auto *TOS = cast<OutputSection<ELFT>>(IS->OutSec);
> +    auto *TOS = cast<OutputSection>(IS->OutSec);
>      TS = make<ThunkSection<ELFT>>(TOS, IS->OutSecOff);
>      ThunkSections[OS].push_back(TS);
>      ThunkedSections[IS] = TS;
> @@ -937,7 +936,7 @@ void createThunks(ArrayRef<OutputSection
>    };
>    // Find or create a ThunkSection to be placed as last executable
> section in
>    // OS.
> -  auto GetOSThunkSec = [&](ThunkSection<ELFT> *&TS, OutputSection<ELFT>
> *OS) {
> +  auto GetOSThunkSec = [&](ThunkSection<ELFT> *&TS, OutputSection *OS) {
>      if (TS == nullptr) {
>        uint32_t Off = 0;
>        for (auto *IS : OS->Sections) {
> @@ -956,8 +955,8 @@ void createThunks(ArrayRef<OutputSection
>    // We separate the creation of ThunkSections from the insertion of the
>    // ThunkSections back into the OutputSection as ThunkSections are not
> always
>    // inserted into the same OutputSection as the caller.
> -  for (OutputSectionBase *Base : OutputSections) {
> -    auto *OS = dyn_cast<OutputSection<ELFT>>(Base);
> +  for (OutputSection *Base : OutputSections) {
> +    auto *OS = dyn_cast<OutputSection>(Base);
>      if (OS == nullptr)
>        continue;
>
> @@ -997,9 +996,9 @@ template void scanRelocations<ELF32BE>(I
>  template void scanRelocations<ELF64LE>(InputSectionBase &);
>  template void scanRelocations<ELF64BE>(InputSectionBase &);
>
> -template void createThunks<ELF32LE>(ArrayRef<OutputSectionBase *>);
> -template void createThunks<ELF32BE>(ArrayRef<OutputSectionBase *>);
> -template void createThunks<ELF64LE>(ArrayRef<OutputSectionBase *>);
> -template void createThunks<ELF64BE>(ArrayRef<OutputSectionBase *>);
> +template void createThunks<ELF32LE>(ArrayRef<OutputSection *>);
> +template void createThunks<ELF32BE>(ArrayRef<OutputSection *>);
> +template void createThunks<ELF64LE>(ArrayRef<OutputSection *>);
> +template void createThunks<ELF64BE>(ArrayRef<OutputSection *>);
>  }
>  }
>
> Modified: lld/trunk/ELF/Relocations.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/
> Relocations.h?rev=296127&r1=296126&r2=296127&view=diff
> ============================================================
> ==================
> --- lld/trunk/ELF/Relocations.h (original)
> +++ lld/trunk/ELF/Relocations.h Fri Feb 24 09:07:30 2017
> @@ -17,7 +17,7 @@ namespace elf {
>  class SymbolBody;
>  class InputSection;
>  class InputSectionBase;
> -class OutputSectionBase;
> +class OutputSection;
>
>  // List of target-independent relocation types. Relocations read
>  // from files are converted to these types so that the main code
> @@ -112,7 +112,7 @@ struct Relocation {
>  template <class ELFT> void scanRelocations(InputSectionBase &);
>
>  template <class ELFT>
> -void createThunks(ArrayRef<OutputSectionBase *> OutputSections);
> +void createThunks(ArrayRef<OutputSection *> OutputSections);
>
>  // Return a int64_t to make sure we get the sign extension out of the way
> as
>  // early as possible.
>
> Modified: lld/trunk/ELF/SymbolTable.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/
> SymbolTable.cpp?rev=296127&r1=296126&r2=296127&view=diff
> ============================================================
> ==================
> --- lld/trunk/ELF/SymbolTable.cpp (original)
> +++ lld/trunk/ELF/SymbolTable.cpp Fri Feb 24 09:07:30 2017
> @@ -397,7 +397,7 @@ SymbolTable<ELFT>::addRegular(StringRef
>
>  template <typename ELFT>
>  Symbol *SymbolTable<ELFT>::addSynthetic(StringRef N,
> -                                        const OutputSectionBase *Section,
> +                                        const OutputSection *Section,
>                                          uintX_t Value, uint8_t StOther) {
>    Symbol *S;
>    bool WasInserted;
>
> Modified: lld/trunk/ELF/SymbolTable.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/
> SymbolTable.h?rev=296127&r1=296126&r2=296127&view=diff
> ============================================================
> ==================
> --- lld/trunk/ELF/SymbolTable.h (original)
> +++ lld/trunk/ELF/SymbolTable.h Fri Feb 24 09:07:30 2017
> @@ -19,7 +19,6 @@
>  namespace lld {
>  namespace elf {
>  class Lazy;
> -class OutputSectionBase;
>  struct Symbol;
>
>  // SymbolTable is a bucket of all known symbols, including defined,
> @@ -62,8 +61,8 @@ public:
>                       uintX_t Value, uintX_t Size, uint8_t Binding,
>                       InputSectionBase *Section, InputFile *File);
>
> -  Symbol *addSynthetic(StringRef N, const OutputSectionBase *Section,
> -                       uintX_t Value, uint8_t StOther);
> +  Symbol *addSynthetic(StringRef N, const OutputSection *Section, uintX_t
> Value,
> +                       uint8_t StOther);
>
>    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=296127&r1=296126&r2=296127&view=diff
> ============================================================
> ==================
> --- lld/trunk/ELF/Symbols.cpp (original)
> +++ lld/trunk/ELF/Symbols.cpp Fri Feb 24 09:07:30 2017
> @@ -35,7 +35,7 @@ static typename ELFT::uint getSymVA(cons
>    switch (Body.kind()) {
>    case SymbolBody::DefinedSyntheticKind: {
>      auto &D = cast<DefinedSynthetic>(Body);
> -    const OutputSectionBase *Sec = D.Section;
> +    const OutputSection *Sec = D.Section;
>      if (!Sec)
>        return D.Value;
>      if (D.Value == uintX_t(-1))
> @@ -62,7 +62,7 @@ static typename ELFT::uint getSymVA(cons
>        Offset += Addend;
>        Addend = 0;
>      }
> -    const OutputSectionBase *OutSec = IS->getOutputSection<ELFT>();
> +    const OutputSection *OutSec = IS->getOutputSection<ELFT>();
>      uintX_t VA = (OutSec ? OutSec->Addr : 0) +
> IS->getOffset<ELFT>(Offset);
>      if (D.isTls() && !Config->Relocatable) {
>        if (!Out<ELFT>::TlsPhdr)
>
> Modified: lld/trunk/ELF/Symbols.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.
> h?rev=296127&r1=296126&r2=296127&view=diff
> ============================================================
> ==================
> --- lld/trunk/ELF/Symbols.h (original)
> +++ lld/trunk/ELF/Symbols.h Fri Feb 24 09:07:30 2017
> @@ -30,8 +30,7 @@ class BitcodeFile;
>  class InputFile;
>  class LazyObjectFile;
>  template <class ELFT> class ObjectFile;
> -template <class ELFT> class OutputSection;
> -class OutputSectionBase;
> +class OutputSection;
>  template <class ELFT> class SharedFile;
>
>  struct Symbol;
> @@ -219,8 +218,7 @@ template <class ELFT> InputSectionBase *
>  // If Section is null, this symbol is relative to the image base.
>  class DefinedSynthetic : public Defined {
>  public:
> -  DefinedSynthetic(StringRef Name, uint64_t Value,
> -                   const OutputSectionBase *Section)
> +  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) {}
> @@ -230,7 +228,7 @@ public:
>    }
>
>    uint64_t Value;
> -  const OutputSectionBase *Section;
> +  const OutputSection *Section;
>  };
>
>  class Undefined : public SymbolBody {
>
> Modified: lld/trunk/ELF/SyntheticSections.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/
> SyntheticSections.cpp?rev=296127&r1=296126&r2=296127&view=diff
> ============================================================
> ==================
> --- lld/trunk/ELF/SyntheticSections.cpp (original)
> +++ lld/trunk/ELF/SyntheticSections.cpp Fri Feb 24 09:07:30 2017
> @@ -769,7 +769,7 @@ template <class ELFT>
>  typename MipsGotSection<ELFT>::uintX_t
>  MipsGotSection<ELFT>::getPageEntryOffset(const SymbolBody &B,
>                                           int64_t Addend) const {
> -  const OutputSectionBase *OutSec =
> +  const OutputSection *OutSec =
>        cast<DefinedRegular<ELFT>>(&B)
>            ->Section->template getOutputSection<ELFT>();
>    uintX_t SecAddr = getMipsPageAddr(OutSec->Addr);
> @@ -827,7 +827,7 @@ unsigned MipsGotSection<ELFT>::getLocalE
>
>  template <class ELFT> void MipsGotSection<ELFT>::finalize() {
>    PageEntriesNum = 0;
> -  for (std::pair<const OutputSectionBase *, size_t> &P : PageIndexMap) {
> +  for (std::pair<const OutputSection *, size_t> &P : PageIndexMap) {
>      // For each output section referenced by GOT page relocations
> calculate
>      // and save into PageIndexMap an upper bound of MIPS GOT entries
> required
>      // to store page addresses of local symbols. We assume the worst case
> -
> @@ -877,7 +877,7 @@ template <class ELFT> void MipsGotSectio
>    P[1] = uintX_t(1) << (ELFT::Is64Bits ? 63 : 31);
>    Buf += HeaderEntriesNum * sizeof(uintX_t);
>    // Write 'page address' entries to the local part of the GOT.
> -  for (std::pair<const OutputSectionBase *, size_t> &L : PageIndexMap) {
> +  for (std::pair<const OutputSection *, size_t> &L : PageIndexMap) {
>      size_t PageCount = getMipsPageCount(L.first->Size);
>      uintX_t FirstPageAddr = getMipsPageAddr(L.first->Addr);
>      for (size_t PI = 0; PI < PageCount; ++PI) {
> @@ -1381,7 +1381,7 @@ void SymbolTableSection<ELFT>::writeLoca
>        ESym->st_shndx = SHN_ABS;
>        ESym->st_value = Body.Value;
>      } else {
> -      const OutputSectionBase *OutSec = Section->getOutputSection<
> ELFT>();
> +      const OutputSection *OutSec = Section->getOutputSection<ELFT>();
>        ESym->st_shndx = OutSec->SectionIndex;
>        ESym->st_value = OutSec->Addr + Section->getOffset(Body);
>      }
> @@ -1412,7 +1412,7 @@ void SymbolTableSection<ELFT>::writeGlob
>      ESym->setVisibility(Body->symbol()->Visibility);
>      ESym->st_value = Body->getVA<ELFT>();
>
> -    if (const OutputSectionBase *OutSec = getOutputSection(Body)) {
> +    if (const OutputSection *OutSec = getOutputSection(Body)) {
>        ESym->st_shndx = OutSec->SectionIndex;
>      } else if (isa<DefinedRegular<ELFT>>(Body)) {
>        ESym->st_shndx = SHN_ABS;
> @@ -1439,7 +1439,7 @@ void SymbolTableSection<ELFT>::writeGlob
>  }
>
>  template <class ELFT>
> -const OutputSectionBase *
> +const OutputSection *
>  SymbolTableSection<ELFT>::getOutputSection(SymbolBody *Sym) {
>    switch (Sym->kind()) {
>    case SymbolBody::DefinedSyntheticKind:
> @@ -2173,7 +2173,7 @@ ARMExidxSentinelSection<ELFT>::ARMExidxS
>  template <class ELFT>
>  void ARMExidxSentinelSection<ELFT>::writeTo(uint8_t *Buf) {
>    // Get the InputSection before us, we are by definition last
> -  auto RI = cast<OutputSection<ELFT>>(this->OutSec)->Sections.rbegin();
> +  auto RI = cast<OutputSection>(this->OutSec)->Sections.rbegin();
>    InputSection *LE = *(++RI);
>    InputSection *LC = cast<InputSection>(LE->template
> getLinkOrderDep<ELFT>());
>    uint64_t S = LC->OutSec->Addr +
> @@ -2184,7 +2184,7 @@ void ARMExidxSentinelSection<ELFT>::writ
>  }
>
>  template <class ELFT>
> -ThunkSection<ELFT>::ThunkSection(OutputSectionBase *OS, uint64_t Off)
> +ThunkSection<ELFT>::ThunkSection(OutputSection *OS, uint64_t Off)
>      : SyntheticSection<ELFT>(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS,
>                               sizeof(typename ELFT::uint), ".text.thunk") {
>    this->OutSec = OS;
>
> Modified: lld/trunk/ELF/SyntheticSections.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/
> SyntheticSections.h?rev=296127&r1=296126&r2=296127&view=diff
> ============================================================
> ==================
> --- lld/trunk/ELF/SyntheticSections.h (original)
> +++ lld/trunk/ELF/SyntheticSections.h Fri Feb 24 09:07:30 2017
> @@ -249,7 +249,7 @@ private:
>    uint32_t PageEntriesNum = 0;
>    // Map output sections referenced by MIPS GOT relocations
>    // to the first index of "Page" entries allocated for this section.
> -  llvm::SmallMapVector<const OutputSectionBase *, size_t, 16>
> PageIndexMap;
> +  llvm::SmallMapVector<const OutputSection *, size_t, 16> PageIndexMap;
>
>    typedef std::pair<const SymbolBody *, uintX_t> GotEntry;
>    typedef std::vector<GotEntry> GotEntries;
> @@ -364,13 +364,13 @@ class DynamicSection final : public Synt
>    struct Entry {
>      int32_t Tag;
>      union {
> -      OutputSectionBase *OutSec;
> +      OutputSection *OutSec;
>        InputSection *InSec;
>        uint64_t Val;
>        const SymbolBody *Sym;
>      };
>      enum KindT { SecAddr, SecSize, SymAddr, PlainInt, InSecAddr } Kind;
> -    Entry(int32_t Tag, OutputSectionBase *OutSec, KindT Kind = SecAddr)
> +    Entry(int32_t Tag, OutputSection *OutSec, KindT Kind = SecAddr)
>          : Tag(Tag), OutSec(OutSec), Kind(Kind) {}
>      Entry(int32_t Tag, InputSection *Sec)
>          : Tag(Tag), InSec(Sec), Kind(InSecAddr) {}
> @@ -443,7 +443,7 @@ public:
>
>    ArrayRef<SymbolTableEntry> getSymbols() const { return Symbols; }
>
> -  static const OutputSectionBase *getOutputSection(SymbolBody *Sym);
> +  static const OutputSection *getOutputSection(SymbolBody *Sym);
>
>  private:
>    void writeLocalSymbols(uint8_t *&Buf);
> @@ -777,7 +777,7 @@ public:
>  template <class ELFT> class ThunkSection : public SyntheticSection<ELFT> {
>  public:
>    // ThunkSection in OS, with desired OutSecOff of Off
> -  ThunkSection(OutputSectionBase *OS, uint64_t Off);
> +  ThunkSection(OutputSection *OS, uint64_t Off);
>
>    // Add a newly created Thunk to this container:
>    // Thunk is given offset from start of this InputSection
>
> Modified: lld/trunk/ELF/Target.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.
> cpp?rev=296127&r1=296126&r2=296127&view=diff
> ============================================================
> ==================
> --- lld/trunk/ELF/Target.cpp (original)
> +++ lld/trunk/ELF/Target.cpp Fri Feb 24 09:07:30 2017
> @@ -65,7 +65,7 @@ template <class ELFT> static std::string
>      if (!IS || !IS->OutSec)
>        continue;
>
> -    uint8_t *ISLoc = cast<OutputSection<ELFT>>(IS->OutSec)->Loc +
> IS->OutSecOff;
> +    uint8_t *ISLoc = cast<OutputSection>(IS->OutSec)->Loc +
> IS->OutSecOff;
>      if (ISLoc <= Loc && Loc < ISLoc + IS->template getSize<ELFT>())
>        return IS->template getLocation<ELFT>(Loc - ISLoc) + ": ";
>    }
>
> Modified: lld/trunk/ELF/Thunks.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Thunks.
> h?rev=296127&r1=296126&r2=296127&view=diff
> ============================================================
> ==================
> --- lld/trunk/ELF/Thunks.h (original)
> +++ lld/trunk/ELF/Thunks.h Fri Feb 24 09:07:30 2017
> @@ -16,7 +16,6 @@ namespace lld {
>  namespace elf {
>  class SymbolBody;
>  template <class ELFT> class ThunkSection;
> -class OutputSectionBase;
>  // Class to describe an instance of a Thunk.
>  // A Thunk is a code-sequence inserted by the linker in between a caller
> and
>  // the callee. The relocation to the callee is redirected to the Thunk,
> which
>
> Modified: lld/trunk/ELF/Writer.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.
> cpp?rev=296127&r1=296126&r2=296127&view=diff
> ============================================================
> ==================
> --- lld/trunk/ELF/Writer.cpp (original)
> +++ lld/trunk/ELF/Writer.cpp Fri Feb 24 09:07:30 2017
> @@ -77,14 +77,14 @@ private:
>
>    std::unique_ptr<FileOutputBuffer> Buffer;
>
> -  std::vector<OutputSectionBase *> OutputSections;
> +  std::vector<OutputSection *> OutputSections;
>    OutputSectionFactory<ELFT> Factory{OutputSections};
>
>    void addRelIpltSymbols();
>    void addStartEndSymbols();
> -  void addStartStopSymbols(OutputSectionBase *Sec);
> +  void addStartStopSymbols(OutputSection *Sec);
>    uintX_t getEntryAddr();
> -  OutputSectionBase *findSection(StringRef Name);
> +  OutputSection *findSection(StringRef Name);
>
>    std::vector<PhdrEntry> Phdrs;
>
> @@ -313,18 +313,18 @@ template <class ELFT> void Writer<ELFT>:
>
>    // Create singleton output sections.
>    Out<ELFT>::Bss =
> -      make<OutputSection<ELFT>>(".bss", SHT_NOBITS, SHF_ALLOC |
> SHF_WRITE);
> -  Out<ELFT>::BssRelRo = make<OutputSection<ELFT>>(".bss.rel.ro",
> SHT_NOBITS,
> -                                                  SHF_ALLOC | SHF_WRITE);
> +      make<OutputSection>(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
> +  Out<ELFT>::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>>(
>        Config->Rela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc);
>    In<ELFT>::ShStrTab = make<StringTableSection<ELFT>>(".shstrtab",
> false);
>
> -  Out<ELFT>::ElfHeader = make<OutputSectionBase>("", 0, SHF_ALLOC);
> +  Out<ELFT>::ElfHeader = make<OutputSection>("", 0, SHF_ALLOC);
>    Out<ELFT>::ElfHeader->Size = sizeof(Elf_Ehdr);
> -  Out<ELFT>::ProgramHeaders = make<OutputSectionBase>("", 0, SHF_ALLOC);
> +  Out<ELFT>::ProgramHeaders = make<OutputSection>("", 0, SHF_ALLOC);
>    Out<ELFT>::ProgramHeaders->updateAlignment(sizeof(uintX_t));
>
>    if (needsInterpSection<ELFT>()) {
> @@ -529,13 +529,10 @@ template <class ELFT> void Writer<ELFT>:
>  template <class ELFT> void Writer<ELFT>::addSectionSymbols() {
>    // Create one STT_SECTION symbol for each output section we might
>    // have a relocation with.
> -  for (OutputSectionBase *Sec : OutputSections) {
> -    InputSectionBase *First = nullptr;
> -    Sec->forEachInputSection([&](InputSectionBase *D) {
> -      if (!First)
> -        First = D;
> -    });
> -    auto *IS = dyn_cast_or_null<InputSection>(First);
> +  for (OutputSection *Sec : OutputSections) {
> +    InputSection *IS = nullptr;
> +    if (!Sec->Sections.empty())
> +      IS = Sec->Sections[0];
>      if (!IS || isa<SyntheticSection<ELFT>>(IS) || IS->Type == SHT_REL ||
>          IS->Type == SHT_RELA)
>        continue;
> @@ -565,7 +562,7 @@ static int getPPC64SectionRank(StringRef
>
>  // All sections with SHF_MIPS_GPREL flag should be grouped together
>  // because data in these sections is addressable with a gp relative
> address.
> -static int getMipsSectionRank(const OutputSectionBase *S) {
> +static int getMipsSectionRank(const OutputSection *S) {
>    if ((S->Flags & SHF_MIPS_GPREL) == 0)
>      return 0;
>    if (S->Name == ".got")
> @@ -579,7 +576,7 @@ static int getMipsSectionRank(const Outp
>  //
>  // This function returns true if a section needs to be put into a
>  // PT_GNU_RELRO segment.
> -template <class ELFT> bool elf::isRelroSection(const OutputSectionBase
> *Sec) {
> +template <class ELFT> bool elf::isRelroSection(const OutputSection *Sec) {
>    if (!Config->ZRelro)
>      return false;
>
> @@ -609,8 +606,8 @@ template <class ELFT> bool elf::isRelroS
>  }
>
>  template <class ELFT>
> -static bool compareSectionsNonScript(const OutputSectionBase *A,
> -                                     const OutputSectionBase *B) {
> +static bool compareSectionsNonScript(const OutputSection *A,
> +                                     const OutputSection *B) {
>    // Put .interp first because some loaders want to see that section
>    // on the first page of the executable file when loaded into memory.
>    bool AIsInterp = A->Name == ".interp";
> @@ -707,8 +704,7 @@ static bool compareSectionsNonScript(con
>
>  // Output section ordering is determined by this function.
>  template <class ELFT>
> -static bool compareSections(const OutputSectionBase *A,
> -                            const OutputSectionBase *B) {
> +static bool compareSections(const OutputSection *A, const OutputSection
> *B) {
>    // For now, put sections mentioned in a linker script first.
>    int AIndex = Script<ELFT>::X->getSectionIndex(A->Name);
>    int BIndex = Script<ELFT>::X->getSectionIndex(B->Name);
> @@ -729,7 +725,7 @@ PhdrEntry::PhdrEntry(unsigned Type, unsi
>    p_flags = Flags;
>  }
>
> -void PhdrEntry::add(OutputSectionBase *Sec) {
> +void PhdrEntry::add(OutputSection *Sec) {
>    Last = Sec;
>    if (!First)
>      First = Sec;
> @@ -740,7 +736,7 @@ void PhdrEntry::add(OutputSectionBase *S
>
>  template <class ELFT>
>  static DefinedSynthetic *
> -addOptionalSynthetic(StringRef Name, OutputSectionBase *Sec,
> +addOptionalSynthetic(StringRef Name, OutputSection *Sec,
>                       typename ELFT::uint Val, uint8_t StOther =
> STV_HIDDEN) {
>    if (SymbolBody *S = Symtab<ELFT>::X->find(Name))
>      if (!S->isInCurrentDSO())
> @@ -862,20 +858,20 @@ template <class ELFT> void Writer<ELFT>:
>
>  // Sort input sections by section name suffixes for
>  // __attribute__((init_priority(N))).
> -template <class ELFT> static void sortInitFini(OutputSectionBase *S) {
> +template <class ELFT> static void sortInitFini(OutputSection *S) {
>    if (S)
> -    reinterpret_cast<OutputSection<ELFT> *>(S)->sortInitFini();
> +    reinterpret_cast<OutputSection *>(S)->sortInitFini();
>  }
>
>  // Sort input sections by the special rule for .ctors and .dtors.
> -template <class ELFT> static void sortCtorsDtors(OutputSectionBase *S) {
> +template <class ELFT> static void sortCtorsDtors(OutputSection *S) {
>    if (S)
> -    reinterpret_cast<OutputSection<ELFT> *>(S)->sortCtorsDtors();
> +    reinterpret_cast<OutputSection *>(S)->sortCtorsDtors();
>  }
>
>  // Sort input sections using the list provided by --symbol-ordering-file.
>  template <class ELFT>
> -static void sortBySymbolsOrder(ArrayRef<OutputSectionBase *>
> OutputSections) {
> +static void sortBySymbolsOrder(ArrayRef<OutputSection *> OutputSections)
> {
>    if (Config->SymbolOrderingFile.empty())
>      return;
>
> @@ -900,8 +896,8 @@ static void sortBySymbolsOrder(ArrayRef<
>    }
>
>    // Sort sections by priority.
> -  for (OutputSectionBase *Base : OutputSections)
> -    if (auto *Sec = dyn_cast<OutputSection<ELFT>>(Base))
> +  for (OutputSection *Base : OutputSections)
> +    if (auto *Sec = dyn_cast<OutputSection>(Base))
>        Sec->sort([&](InputSectionBase *S) { return SectionOrder.lookup(S);
> });
>  }
>
> @@ -933,13 +929,12 @@ template <class ELFT> void Writer<ELFT>:
>    sortCtorsDtors<ELFT>(findSection(".ctors"));
>    sortCtorsDtors<ELFT>(findSection(".dtors"));
>
> -  for (OutputSectionBase *Sec : OutputSections)
> -    Sec->assignOffsets();
> +  for (OutputSection *Sec : OutputSections)
> +    Sec->assignOffsets<ELFT>();
>  }
>
>  template <class ELFT>
> -static bool canSharePtLoad(const OutputSectionBase &S1,
> -                           const OutputSectionBase &S2) {
> +static bool canSharePtLoad(const OutputSection &S1, const OutputSection
> &S2) {
>    if (!(S1.Flags & SHF_ALLOC) || !(S2.Flags & SHF_ALLOC))
>      return false;
>
> @@ -995,12 +990,12 @@ template <class ELFT> void Writer<ELFT>:
>    auto I = OutputSections.begin();
>    auto E = OutputSections.end();
>    auto NonScriptI =
> -      std::find_if(OutputSections.begin(), E, [](OutputSectionBase *S) {
> +      std::find_if(OutputSections.begin(), E, [](OutputSection *S) {
>          return Script<ELFT>::X->getSectionIndex(S->Name) == INT_MAX;
>        });
>    while (NonScriptI != E) {
>      auto BestPos = std::max_element(
> -        I, NonScriptI, [&](OutputSectionBase *&A, OutputSectionBase *&B) {
> +        I, NonScriptI, [&](OutputSection *&A, OutputSection *&B) {
>            bool ACanSharePtLoad = canSharePtLoad<ELFT>(**NonScriptI, *A);
>            bool BCanSharePtLoad = canSharePtLoad<ELFT>(**NonScriptI, *B);
>            if (ACanSharePtLoad != BCanSharePtLoad)
> @@ -1036,7 +1031,7 @@ finalizeSynthetic(const std::vector<Synt
>      if (SS && SS->OutSec && !SS->empty()) {
>        SS->finalize();
>        SS->OutSec->Size = 0;
> -      SS->OutSec->assignOffsets();
> +      SS->OutSec->template assignOffsets<ELFT>();
>      }
>  }
>
> @@ -1045,7 +1040,7 @@ finalizeSynthetic(const std::vector<Synt
>  // required to be in output. For example we don't need dynamic section
> content
>  // sometimes. This function filters out such unused sections from output.
>  template <class ELFT>
> -static void removeUnusedSyntheticSections(std::vector<OutputSectionBase
> *> &V) {
> +static void removeUnusedSyntheticSections(std::vector<OutputSection *>
> &V) {
>    // All input synthetic sections that can be empty are placed after
>    // all regular ones. We iterate over them all and exit at first
>    // non-synthetic.
> @@ -1056,7 +1051,7 @@ static void removeUnusedSyntheticSection
>      if (!SS->empty() || !SS->OutSec)
>        continue;
>
> -    OutputSection<ELFT> *OutSec = cast<OutputSection<ELFT>>(SS->OutSec);
> +    OutputSection *OutSec = cast<OutputSection>(SS->OutSec);
>      OutSec->Sections.erase(
>          std::find(OutSec->Sections.begin(), OutSec->Sections.end(), SS));
>      // If there is no other sections in output section, remove it from
> output.
> @@ -1077,7 +1072,7 @@ template <class ELFT> void Writer<ELFT>:
>    // addresses of each section by section name. Add such symbols.
>    if (!Config->Relocatable) {
>      addStartEndSymbols();
> -    for (OutputSectionBase *Sec : OutputSections)
> +    for (OutputSection *Sec : OutputSections)
>        addStartStopSymbols(Sec);
>    }
>
> @@ -1140,7 +1135,7 @@ template <class ELFT> void Writer<ELFT>:
>    Out<ELFT>::ElfHeader->SectionIndex = 1;
>
>    unsigned I = 1;
> -  for (OutputSectionBase *Sec : OutputSections) {
> +  for (OutputSection *Sec : OutputSections) {
>      Sec->SectionIndex = I++;
>      Sec->ShName = In<ELFT>::ShStrTab->addString(Sec->Name);
>    }
> @@ -1164,8 +1159,8 @@ template <class ELFT> void Writer<ELFT>:
>    // Fill other section headers. The dynamic table is finalized
>    // at the end because some tags like RELSZ depend on result
>    // of finalizing other sections.
> -  for (OutputSectionBase *Sec : OutputSections)
> -    Sec->finalize();
> +  for (OutputSection *Sec : OutputSections)
> +    Sec->finalize<ELFT>();
>
>    // Dynamic section must be the last one in this list and dynamic
>    // symbol table section (DynSymTab) must be the first one.
> @@ -1182,9 +1177,9 @@ template <class ELFT> void Writer<ELFT>:
>
>  template <class ELFT> void Writer<ELFT>::addPredefinedSections() {
>    // Add BSS sections.
> -  auto Add = [=](OutputSection<ELFT> *Sec) {
> +  auto Add = [=](OutputSection *Sec) {
>      if (!Sec->Sections.empty()) {
> -      Sec->assignOffsets();
> +      Sec->assignOffsets<ELFT>();
>        OutputSections.push_back(Sec);
>      }
>    };
> @@ -1193,7 +1188,7 @@ template <class ELFT> void Writer<ELFT>:
>
>    // 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<ELFT>>(
> findSection(".ARM.exidx"));
> +  auto *OS = dyn_cast_or_null<OutputSection>(findSection(".ARM.exidx"));
>    if (OS && !OS->Sections.empty() && !Config->Relocatable)
>      OS->addSection(make<ARMExidxSentinelSection<ELFT>>());
>  }
> @@ -1201,7 +1196,7 @@ template <class ELFT> void Writer<ELFT>:
>  // The linker is expected to define SECNAME_start and SECNAME_end
>  // symbols for a few sections. This function defines them.
>  template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
> -  auto Define = [&](StringRef Start, StringRef End, OutputSectionBase
> *OS) {
> +  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);
> @@ -1213,7 +1208,7 @@ template <class ELFT> void Writer<ELFT>:
>    Define("__init_array_start", "__init_array_end", Out<ELFT>::InitArray);
>    Define("__fini_array_start", "__fini_array_end", Out<ELFT>::FiniArray);
>
> -  if (OutputSectionBase *Sec = findSection(".ARM.exidx"))
> +  if (OutputSection *Sec = findSection(".ARM.exidx"))
>      Define("__exidx_start", "__exidx_end", Sec);
>  }
>
> @@ -1223,7 +1218,7 @@ template <class ELFT> void Writer<ELFT>:
>  // respectively. This is not requested by the ELF standard, but GNU ld and
>  // gold provide the feature, and used by many programs.
>  template <class ELFT>
> -void Writer<ELFT>::addStartStopSymbols(OutputSectionBase *Sec) {
> +void Writer<ELFT>::addStartStopSymbols(OutputSection *Sec) {
>    StringRef S = Sec->Name;
>    if (!isValidCIdentifier(S))
>      return;
> @@ -1231,15 +1226,14 @@ void Writer<ELFT>::addStartStopSymbols(O
>    addOptionalSynthetic<ELFT>(Saver.save("__stop_" + S), Sec, -1,
> STV_DEFAULT);
>  }
>
> -template <class ELFT>
> -OutputSectionBase *Writer<ELFT>::findSection(StringRef Name) {
> -  for (OutputSectionBase *Sec : OutputSections)
> +template <class ELFT> OutputSection *Writer<ELFT>::findSection(StringRef
> Name) {
> +  for (OutputSection *Sec : OutputSections)
>      if (Sec->Name == Name)
>        return Sec;
>    return nullptr;
>  }
>
> -template <class ELFT> static bool needsPtLoad(OutputSectionBase *Sec) {
> +template <class ELFT> static bool needsPtLoad(OutputSection *Sec) {
>    if (!(Sec->Flags & SHF_ALLOC))
>      return false;
>
> @@ -1277,13 +1271,13 @@ template <class ELFT> std::vector<PhdrEn
>    AddHdr(PT_PHDR, PF_R)->add(Out<ELFT>::ProgramHeaders);
>
>    // PT_INTERP must be the second entry if exists.
> -  if (OutputSectionBase *Sec = findSection(".interp"))
> +  if (OutputSection *Sec = findSection(".interp"))
>      AddHdr(PT_INTERP, Sec->getPhdrFlags())->add(Sec);
>
>    // Add the first PT_LOAD segment for regular output sections.
>    uintX_t Flags = computeFlags<ELFT>(PF_R);
>    PhdrEntry *Load = AddHdr(PT_LOAD, Flags);
> -  for (OutputSectionBase *Sec : OutputSections) {
> +  for (OutputSection *Sec : OutputSections) {
>      if (!(Sec->Flags & SHF_ALLOC))
>        break;
>      if (!needsPtLoad<ELFT>(Sec))
> @@ -1305,7 +1299,7 @@ template <class ELFT> std::vector<PhdrEn
>
>    // Add a TLS segment if any.
>    PhdrEntry TlsHdr(PT_TLS, PF_R);
> -  for (OutputSectionBase *Sec : OutputSections)
> +  for (OutputSection *Sec : OutputSections)
>      if (Sec->Flags & SHF_TLS)
>        TlsHdr.add(Sec);
>    if (TlsHdr.First)
> @@ -1319,7 +1313,7 @@ template <class ELFT> std::vector<PhdrEn
>    // PT_GNU_RELRO includes all sections that should be marked as
>    // read-only by dynamic linker after proccessing relocations.
>    PhdrEntry RelRo(PT_GNU_RELRO, PF_R);
> -  for (OutputSectionBase *Sec : OutputSections)
> +  for (OutputSection *Sec : OutputSections)
>      if (needsPtLoad<ELFT>(Sec) && isRelroSection<ELFT>(Sec))
>        RelRo.add(Sec);
>    if (RelRo.First)
> @@ -1333,7 +1327,7 @@ template <class ELFT> std::vector<PhdrEn
>    // PT_OPENBSD_RANDOMIZE specifies the location and size of a part of the
>    // memory image of the program that must be filled with random data
> before any
>    // code in the object is executed.
> -  if (OutputSectionBase *Sec = findSection(".openbsd.randomdata"))
> +  if (OutputSection *Sec = findSection(".openbsd.randomdata"))
>      AddHdr(PT_OPENBSD_RANDOMIZE, Sec->getPhdrFlags())->add(Sec);
>
>    // PT_GNU_STACK is a special section to tell the loader to make the
> @@ -1356,7 +1350,7 @@ template <class ELFT> std::vector<PhdrEn
>
>    // Create one PT_NOTE per a group of contiguous .note sections.
>    PhdrEntry *Note = nullptr;
> -  for (OutputSectionBase *Sec : OutputSections) {
> +  for (OutputSection *Sec : OutputSections) {
>      if (Sec->Type == SHT_NOTE) {
>        if (!Note || Script<ELFT>::X->hasLMA(Sec->Name))
>          Note = AddHdr(PT_NOTE, PF_R);
> @@ -1374,7 +1368,7 @@ void Writer<ELFT>::addPtArmExid(std::vec
>      return;
>    auto I = std::find_if(
>        OutputSections.begin(), OutputSections.end(),
> -      [](OutputSectionBase *Sec) { return Sec->Type == SHT_ARM_EXIDX; });
> +      [](OutputSection *Sec) { return Sec->Type == SHT_ARM_EXIDX; });
>    if (I == OutputSections.end())
>      return;
>
> @@ -1403,7 +1397,7 @@ template <class ELFT> void Writer<ELFT>:
>      auto I = std::find(OutputSections.begin(), End, P.Last);
>      if (I == End || (I + 1) == End)
>        continue;
> -    OutputSectionBase *Sec = *(I + 1);
> +    OutputSection *Sec = *(I + 1);
>      if (needsPtLoad<ELFT>(Sec))
>        Sec->PageAlign = true;
>    }
> @@ -1411,7 +1405,7 @@ template <class ELFT> void Writer<ELFT>:
>
>  template <class ELFT>
>  bool elf::allocateHeaders(std::vector<PhdrEntry> &Phdrs,
> -                          ArrayRef<OutputSectionBase *> OutputSections,
> +                          ArrayRef<OutputSection *> OutputSections,
>                            uint64_t Min) {
>    auto FirstPTLoad =
>        std::find_if(Phdrs.begin(), Phdrs.end(),
> @@ -1440,7 +1434,7 @@ bool elf::allocateHeaders(std::vector<Ph
>      return true;
>
>    if (FirstPTLoad->First)
> -    for (OutputSectionBase *Sec : OutputSections)
> +    for (OutputSection *Sec : OutputSections)
>        if (Sec->FirstInPtLoad == FirstPTLoad->First)
>          Sec->FirstInPtLoad = Out<ELFT>::ElfHeader;
>    FirstPTLoad->First = Out<ELFT>::ElfHeader;
> @@ -1474,7 +1468,7 @@ template <class ELFT> void Writer<ELFT>:
>    if (AllocateHeader)
>      VA += getHeaderSize<ELFT>();
>    uintX_t ThreadBssOffset = 0;
> -  for (OutputSectionBase *Sec : OutputSections) {
> +  for (OutputSection *Sec : OutputSections) {
>      uintX_t Alignment = Sec->Addralign;
>      if (Sec->PageAlign)
>        Alignment = std::max<uintX_t>(Alignment, Config->MaxPageSize);
> @@ -1502,8 +1496,8 @@ template <class ELFT> void Writer<ELFT>:
>  // virtual address (modulo the page size) so that the loader can load
>  // executables without any address adjustment.
>  template <class ELFT, class uintX_t>
> -static uintX_t getFileAlignment(uintX_t Off, OutputSectionBase *Sec) {
> -  OutputSectionBase *First = Sec->FirstInPtLoad;
> +static uintX_t getFileAlignment(uintX_t Off, OutputSection *Sec) {
> +  OutputSection *First = Sec->FirstInPtLoad;
>    // If the section is not in a PT_LOAD, we just have to align it.
>    if (!First)
>      return alignTo(Off, Sec->Addralign);
> @@ -1519,7 +1513,7 @@ static uintX_t getFileAlignment(uintX_t
>  }
>
>  template <class ELFT, class uintX_t>
> -static uintX_t setOffset(OutputSectionBase *Sec, uintX_t Off) {
> +static uintX_t setOffset(OutputSection *Sec, uintX_t Off) {
>    if (Sec->Type == SHT_NOBITS) {
>      Sec->Offset = Off;
>      return Off;
> @@ -1532,7 +1526,7 @@ static uintX_t setOffset(OutputSectionBa
>
>  template <class ELFT> void Writer<ELFT>::assignFileOffsetsBinary() {
>    uintX_t Off = 0;
> -  for (OutputSectionBase *Sec : OutputSections)
> +  for (OutputSection *Sec : OutputSections)
>      if (Sec->Flags & SHF_ALLOC)
>        Off = setOffset<ELFT>(Sec, Off);
>    FileSize = alignTo(Off, sizeof(uintX_t));
> @@ -1544,7 +1538,7 @@ template <class ELFT> void Writer<ELFT>:
>    Off = setOffset<ELFT>(Out<ELFT>::ElfHeader, Off);
>    Off = setOffset<ELFT>(Out<ELFT>::ProgramHeaders, Off);
>
> -  for (OutputSectionBase *Sec : OutputSections)
> +  for (OutputSection *Sec : OutputSections)
>      Off = setOffset<ELFT>(Sec, Off);
>
>    SectionHeaderOff = alignTo(Off, sizeof(uintX_t));
> @@ -1555,8 +1549,8 @@ template <class ELFT> void Writer<ELFT>:
>  // file offsets and VAs to all sections.
>  template <class ELFT> void Writer<ELFT>::setPhdrs() {
>    for (PhdrEntry &P : Phdrs) {
> -    OutputSectionBase *First = P.First;
> -    OutputSectionBase *Last = P.Last;
> +    OutputSection *First = P.First;
> +    OutputSection *Last = P.Last;
>      if (First) {
>        P.p_filesz = Last->Offset - First->Offset;
>        if (Last->Type != SHT_NOBITS)
> @@ -1604,7 +1598,7 @@ template <class ELFT> typename ELFT::uin
>      return Addr;
>
>    // Case 4
> -  if (OutputSectionBase *Sec = findSection(".text")) {
> +  if (OutputSection *Sec = findSection(".text")) {
>      if (Config->WarnMissingEntry)
>        warn("cannot find entry symbol " + Config->Entry + "; defaulting to
> 0x" +
>             utohexstr(Sec->Addr));
> @@ -1636,8 +1630,8 @@ 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,
> -                OutputSectionBase *Sec, uint64_t Value) {
> +  auto Set = [](DefinedSynthetic *S1, DefinedSynthetic *S2, OutputSection
> *Sec,
> +                uint64_t Value) {
>      if (S1) {
>        S1->Section = Sec;
>        S1->Value = Value;
> @@ -1679,7 +1673,7 @@ template <class ELFT> void Writer<ELFT>:
>        // Find GP-relative section with the lowest address
>        // and use this address to calculate default _gp value.
>        uintX_t Gp = -1;
> -      for (const OutputSectionBase * OS : OutputSections)
> +      for (const OutputSection *OS : OutputSections)
>          if ((OS->Flags & SHF_MIPS_GPREL) && OS->Addr < Gp)
>            Gp = OS->Addr;
>        if (Gp != (uintX_t)-1)
> @@ -1742,7 +1736,7 @@ template <class ELFT> void Writer<ELFT>:
>
>    // Write the section header table. Note that the first table entry is
> null.
>    auto *SHdrs = reinterpret_cast<Elf_Shdr *>(Buf + EHdr->e_shoff);
> -  for (OutputSectionBase *Sec : OutputSections)
> +  for (OutputSection *Sec : OutputSections)
>      Sec->writeHeaderTo<ELFT>(++SHdrs);
>  }
>
> @@ -1796,9 +1790,9 @@ template <class ELFT> void Writer<ELFT>:
>
>  template <class ELFT> void Writer<ELFT>::writeSectionsBinary() {
>    uint8_t *Buf = Buffer->getBufferStart();
> -  for (OutputSectionBase *Sec : OutputSections)
> +  for (OutputSection *Sec : OutputSections)
>      if (Sec->Flags & SHF_ALLOC)
> -      Sec->writeTo(Buf + Sec->Offset);
> +      Sec->writeTo<ELFT>(Buf + Sec->Offset);
>  }
>
>  // Write section contents to a mmap'ed file.
> @@ -1810,28 +1804,28 @@ template <class ELFT> void Writer<ELFT>:
>    Out<ELFT>::Opd = findSection(".opd");
>    if (Out<ELFT>::Opd) {
>      Out<ELFT>::OpdBuf = Buf + Out<ELFT>::Opd->Offset;
> -    Out<ELFT>::Opd->writeTo(Buf + Out<ELFT>::Opd->Offset);
> +    Out<ELFT>::Opd->template writeTo<ELFT>(Buf + Out<ELFT>::Opd->Offset);
>    }
>
> -  OutputSectionBase *EhFrameHdr =
> +  OutputSection *EhFrameHdr =
>        In<ELFT>::EhFrameHdr ? In<ELFT>::EhFrameHdr->OutSec : nullptr;
>
>    // 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
>    // section while doing it.
> -  for (OutputSectionBase *Sec : OutputSections)
> +  for (OutputSection *Sec : OutputSections)
>      if (Sec->Type == SHT_REL || Sec->Type == SHT_RELA)
> -      Sec->writeTo(Buf + Sec->Offset);
> +      Sec->writeTo<ELFT>(Buf + Sec->Offset);
>
> -  for (OutputSectionBase *Sec : OutputSections)
> +  for (OutputSection *Sec : OutputSections)
>      if (Sec != Out<ELFT>::Opd && Sec != EhFrameHdr && Sec->Type !=
> SHT_REL &&
>          Sec->Type != SHT_RELA)
> -      Sec->writeTo(Buf + Sec->Offset);
> +      Sec->writeTo<ELFT>(Buf + Sec->Offset);
>
>    // The .eh_frame_hdr depends on .eh_frame section contents, therefore
>    // it should be written after .eh_frame is written.
>    if (EhFrameHdr)
> -    EhFrameHdr->writeTo(Buf + EhFrameHdr->Offset);
> +    EhFrameHdr->writeTo<ELFT>(Buf + EhFrameHdr->Offset);
>  }
>
>  template <class ELFT> void Writer<ELFT>::writeBuildId() {
> @@ -1850,19 +1844,19 @@ template void elf::writeResult<ELF64LE>(
>  template void elf::writeResult<ELF64BE>();
>
>  template bool elf::allocateHeaders<ELF32LE>(std::vector<PhdrEntry> &,
> -                                            ArrayRef<OutputSectionBase *>,
> +                                            ArrayRef<OutputSection *>,
>                                              uint64_t);
>  template bool elf::allocateHeaders<ELF32BE>(std::vector<PhdrEntry> &,
> -                                            ArrayRef<OutputSectionBase *>,
> +                                            ArrayRef<OutputSection *>,
>                                              uint64_t);
>  template bool elf::allocateHeaders<ELF64LE>(std::vector<PhdrEntry> &,
> -                                            ArrayRef<OutputSectionBase *>,
> +                                            ArrayRef<OutputSection *>,
>                                              uint64_t);
>  template bool elf::allocateHeaders<ELF64BE>(std::vector<PhdrEntry> &,
> -                                            ArrayRef<OutputSectionBase *>,
> +                                            ArrayRef<OutputSection *>,
>                                              uint64_t);
>
> -template bool elf::isRelroSection<ELF32LE>(const OutputSectionBase *);
> -template bool elf::isRelroSection<ELF32BE>(const OutputSectionBase *);
> -template bool elf::isRelroSection<ELF64LE>(const OutputSectionBase *);
> -template bool elf::isRelroSection<ELF64BE>(const OutputSectionBase *);
> +template bool elf::isRelroSection<ELF32LE>(const OutputSection *);
> +template bool elf::isRelroSection<ELF32BE>(const OutputSection *);
> +template bool elf::isRelroSection<ELF64LE>(const OutputSection *);
> +template bool elf::isRelroSection<ELF64BE>(const OutputSection *);
>
> Modified: lld/trunk/ELF/Writer.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.
> h?rev=296127&r1=296126&r2=296127&view=diff
> ============================================================
> ==================
> --- lld/trunk/ELF/Writer.h (original)
> +++ lld/trunk/ELF/Writer.h Fri Feb 24 09:07:30 2017
> @@ -18,20 +18,20 @@
>  namespace lld {
>  namespace elf {
>  class InputFile;
> -class OutputSectionBase;
> +class OutputSection;
>  class InputSectionBase;
>  template <class ELFT> class ObjectFile;
>  template <class ELFT> class SymbolTable;
>  template <class ELFT> void writeResult();
>  template <class ELFT> void markLive();
> -template <class ELFT> bool isRelroSection(const OutputSectionBase *Sec);
> +template <class ELFT> bool isRelroSection(const OutputSection *Sec);
>
>  // This describes a program header entry.
>  // Each contains type, access flags and range of output sections that
> will be
>  // placed in it.
>  struct PhdrEntry {
>    PhdrEntry(unsigned Type, unsigned Flags);
> -  void add(OutputSectionBase *Sec);
> +  void add(OutputSection *Sec);
>
>    uint64_t p_paddr = 0;
>    uint64_t p_vaddr = 0;
> @@ -42,16 +42,16 @@ struct PhdrEntry {
>    uint32_t p_type = 0;
>    uint32_t p_flags = 0;
>
> -  OutputSectionBase *First = nullptr;
> -  OutputSectionBase *Last = nullptr;
> +  OutputSection *First = nullptr;
> +  OutputSection *Last = nullptr;
>    bool HasLMA = false;
>  };
>
>  llvm::StringRef getOutputSectionName(llvm::StringRef Name);
>
>  template <class ELFT>
> -bool allocateHeaders(std::vector<PhdrEntry> &,
> -                     llvm::ArrayRef<OutputSectionBase *>, uint64_t Min);
> +bool allocateHeaders(std::vector<PhdrEntry> &,
> llvm::ArrayRef<OutputSection *>,
> +                     uint64_t Min);
>
>  template <class ELFT> uint32_t getMipsEFlags();
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170224/44d041f8/attachment-0001.html>


More information about the llvm-commits mailing list