[lld] r286414 - Make OutputSectionBase a class instead of class template.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Sat Nov 12 20:10:04 PST 2016


On Sat, Nov 12, 2016 at 3:52 PM, Sean Silva <chisophugis at gmail.com> wrote:

>
>
> On Thu, Nov 10, 2016 at 3:47 PM, Rui Ueyama via llvm-commits <
> llvm-commits at lists.llvm.org> wrote:
>
>> It seems we could do the same thing for InputSectionBase, and it would
>> have the same advantage as this patch aims for. What do you think?
>>
>
> That would have a cost for the sizeof of input sections for 32-bit target
> links, but I'm not sure how much we care about that.
>

I believe in this case we should prefer simpler code than the small runtime
cost to link 32-bit executables. 32-bit output is small, so it is fast
anyways. I become increasingly convinced that we should use uint64_t
instead of uintX_t in many more places to reduce ELFT-template classes.


> -- Sean Silva
>
>
>>
>> On Wed, Nov 9, 2016 at 3:23 PM, Rafael Espindola via llvm-commits <
>> llvm-commits at lists.llvm.org> wrote:
>>
>>> Author: rafael
>>> Date: Wed Nov  9 17:23:45 2016
>>> New Revision: 286414
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=286414&view=rev
>>> Log:
>>> Make OutputSectionBase a class instead of class template.
>>>
>>> The disadvantage is that we use uint64_t instad of uint32_t for some
>>> value in 32 bit files. The advantage is a substantially simpler code,
>>> faster builds and less code duplication.
>>>
>>> Modified:
>>>     lld/trunk/ELF/InputSection.h
>>>     lld/trunk/ELF/LinkerScript.cpp
>>>     lld/trunk/ELF/LinkerScript.h
>>>     lld/trunk/ELF/OutputSections.cpp
>>>     lld/trunk/ELF/OutputSections.h
>>>     lld/trunk/ELF/SymbolTable.cpp
>>>     lld/trunk/ELF/SymbolTable.h
>>>     lld/trunk/ELF/Symbols.cpp
>>>     lld/trunk/ELF/Symbols.h
>>>     lld/trunk/ELF/Writer.cpp
>>>     lld/trunk/ELF/Writer.h
>>>
>>> Modified: lld/trunk/ELF/InputSection.h
>>> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSecti
>>> on.h?rev=286414&r1=286413&r2=286414&view=diff
>>> ============================================================
>>> ==================
>>> --- lld/trunk/ELF/InputSection.h (original)
>>> +++ lld/trunk/ELF/InputSection.h Wed Nov  9 17:23:45 2016
>>> @@ -29,7 +29,7 @@ template <class ELFT> class ICF;
>>>  template <class ELFT> class DefinedRegular;
>>>  template <class ELFT> class ObjectFile;
>>>  template <class ELFT> class OutputSection;
>>> -template <class ELFT> class OutputSectionBase;
>>> +class OutputSectionBase;
>>>
>>>  // We need non-template input section class to store symbol layout
>>>  // in linker script parser structures, where we do not have ELFT
>>> @@ -104,7 +104,7 @@ public:
>>>                     uintX_t Entsize, uint32_t Link, uint32_t Info,
>>>                     uintX_t Addralign, ArrayRef<uint8_t> Data, StringRef
>>> Name,
>>>                     Kind SectionKind);
>>> -  OutputSectionBase<ELFT> *OutSec = nullptr;
>>> +  OutputSectionBase *OutSec = nullptr;
>>>
>>>    // This pointer points to the "real" instance of this instance.
>>>    // Usually Repl == this. However, if ICF merges two sections,
>>>
>>> Modified: lld/trunk/ELF/LinkerScript.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScri
>>> pt.cpp?rev=286414&r1=286413&r2=286414&view=diff
>>> ============================================================
>>> ==================
>>> --- lld/trunk/ELF/LinkerScript.cpp (original)
>>> +++ lld/trunk/ELF/LinkerScript.cpp Wed Nov  9 17:23:45 2016
>>> @@ -229,7 +229,7 @@ void LinkerScript<ELFT>::computeInputSec
>>>    // section for now.
>>>    for (InputSectionData *S : I->Sections) {
>>>      auto *S2 = static_cast<InputSectionBase<ELFT> *>(S);
>>> -    S2->OutSec = (OutputSectionBase<ELFT> *)-1;
>>> +    S2->OutSec = (OutputSectionBase *)-1;
>>>    }
>>>  }
>>>
>>> @@ -298,7 +298,7 @@ template <class ELFT>
>>>  void LinkerScript<ELFT>::addSection(OutputSectionFactory<ELFT>
>>> &Factory,
>>>                                      InputSectionBase<ELFT> *Sec,
>>>                                      StringRef Name) {
>>> -  OutputSectionBase<ELFT> *OutSec;
>>> +  OutputSectionBase *OutSec;
>>>    bool IsNew;
>>>    std::tie(OutSec, IsNew) = Factory.create(createKey(Sec, Name), Sec);
>>>    if (IsNew)
>>> @@ -373,8 +373,7 @@ void LinkerScript<ELFT>::createSections(
>>>  // is an offset from beginning of section and regular
>>>  // symbols whose value is absolute.
>>>  template <class ELFT>
>>> -static void assignSectionSymbol(SymbolAssignment *Cmd,
>>> -                                OutputSectionBase<ELFT> *Sec,
>>> +static void assignSectionSymbol(SymbolAssignment *Cmd,
>>> OutputSectionBase *Sec,
>>>                                  typename ELFT::uint Value) {
>>>    if (!Cmd->Sym)
>>>      return;
>>> @@ -388,14 +387,14 @@ static void assignSectionSymbol(SymbolAs
>>>    Body->Value = Cmd->Expression(Value);
>>>  }
>>>
>>> -template <class ELFT> static bool isTbss(OutputSectionBase<ELFT> *Sec) {
>>> +template <class ELFT> static bool isTbss(OutputSectionBase *Sec) {
>>>    return (Sec->Flags & SHF_TLS) && Sec->Type == SHT_NOBITS;
>>>  }
>>>
>>>  template <class ELFT> void LinkerScript<ELFT>::output(InputSection<ELFT>
>>> *S) {
>>>    if (!AlreadyOutputIS.insert(S).second)
>>>      return;
>>> -  bool IsTbss = isTbss(CurOutSec);
>>> +  bool IsTbss = isTbss<ELFT>(CurOutSec);
>>>
>>>    uintX_t Pos = IsTbss ? Dot + ThreadBssOffset : Dot;
>>>    Pos = alignTo(Pos, S->Alignment);
>>> @@ -425,7 +424,7 @@ template <class ELFT> void LinkerScript<
>>>  }
>>>
>>>  template <class ELFT>
>>> -void LinkerScript<ELFT>::switchTo(OutputSectionBase<ELFT> *Sec) {
>>> +void LinkerScript<ELFT>::switchTo(OutputSectionBase *Sec) {
>>>    if (CurOutSec == Sec)
>>>      return;
>>>    if (AlreadyOutputOS.count(Sec))
>>> @@ -435,7 +434,7 @@ void LinkerScript<ELFT>::switchTo(Output
>>>    CurOutSec = Sec;
>>>
>>>    Dot = alignTo(Dot, CurOutSec->Addralign);
>>> -  CurOutSec->Addr = isTbss(CurOutSec) ? Dot + ThreadBssOffset : Dot;
>>> +  CurOutSec->Addr = isTbss<ELFT>(CurOutSec) ? Dot + ThreadBssOffset :
>>> Dot;
>>>
>>>    // If neither AT nor AT> is specified for an allocatable section, the
>>> linker
>>>    // will set the LMA such that the difference between VMA and LMA for
>>> the
>>> @@ -480,11 +479,10 @@ template <class ELFT> void LinkerScript<
>>>  }
>>>
>>>  template <class ELFT>
>>> -static std::vector<OutputSectionBase<ELFT> *>
>>> -findSections(StringRef Name,
>>> -             const std::vector<OutputSectionBase<ELFT> *> &Sections) {
>>> -  std::vector<OutputSectionBase<ELFT> *> Ret;
>>> -  for (OutputSectionBase<ELFT> *Sec : Sections)
>>> +static std::vector<OutputSectionBase *>
>>> +findSections(StringRef Name, const std::vector<OutputSectionBase *>
>>> &Sections) {
>>> +  std::vector<OutputSectionBase *> Ret;
>>> +  for (OutputSectionBase *Sec : Sections)
>>>      if (Sec->getName() == Name)
>>>        Ret.push_back(Sec);
>>>    return Ret;
>>> @@ -494,8 +492,8 @@ template <class ELFT>
>>>  void LinkerScript<ELFT>::assignOffsets(OutputSectionCommand *Cmd) {
>>>    if (Cmd->LMAExpr)
>>>      LMAOffset = Cmd->LMAExpr(Dot) - Dot;
>>> -  std::vector<OutputSectionBase<ELFT> *> Sections =
>>> -      findSections(Cmd->Name, *OutputSections);
>>> +  std::vector<OutputSectionBase *> Sections =
>>> +      findSections<ELFT>(Cmd->Name, *OutputSections);
>>>    if (Sections.empty())
>>>      return;
>>>    switchTo(Sections[0]);
>>> @@ -508,7 +506,7 @@ void LinkerScript<ELFT>::assignOffsets(O
>>>                 .base();
>>>    for (auto I = Cmd->Commands.begin(); I != E; ++I)
>>>      process(**I);
>>> -  for (OutputSectionBase<ELFT> *Base : Sections)
>>> +  for (OutputSectionBase *Base : Sections)
>>>      switchTo(Base);
>>>    flush();
>>>    std::for_each(E, Cmd->Commands.end(),
>>> @@ -528,8 +526,8 @@ template <class ELFT> void LinkerScript<
>>>          auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
>>>          if (!Cmd)
>>>            return false;
>>> -        std::vector<OutputSectionBase<ELFT> *> Secs =
>>> -            findSections(Cmd->Name, *OutputSections);
>>> +        std::vector<OutputSectionBase *> Secs =
>>> +            findSections<ELFT>(Cmd->Name, *OutputSections);
>>>          if (!Secs.empty())
>>>            return false;
>>>          for (const std::unique_ptr<BaseCommand> &I : Cmd->Commands)
>>> @@ -549,8 +547,8 @@ template <class ELFT> void LinkerScript<
>>>      auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
>>>      if (!Cmd)
>>>        continue;
>>> -    std::vector<OutputSectionBase<ELFT> *> Secs =
>>> -        findSections(Cmd->Name, *OutputSections);
>>> +    std::vector<OutputSectionBase *> Secs =
>>> +        findSections<ELFT>(Cmd->Name, *OutputSections);
>>>      if (!Secs.empty()) {
>>>        Flags = Secs[0]->Flags;
>>>        Type = Secs[0]->Type;
>>> @@ -597,7 +595,7 @@ void LinkerScript<ELFT>::assignAddresses
>>>    // This loops creates or moves commands as needed so that they are in
>>> the
>>>    // correct order.
>>>    int CmdIndex = 0;
>>> -  for (OutputSectionBase<ELFT> *Sec : *OutputSections) {
>>> +  for (OutputSectionBase *Sec : *OutputSections) {
>>>      StringRef Name = Sec->getName();
>>>
>>>      // Find the last spot where we can insert a command and still get
>>> the
>>> @@ -633,8 +631,8 @@ void LinkerScript<ELFT>::assignAddresses
>>>        if (Cmd->Name == ".") {
>>>          Dot = Cmd->Expression(Dot);
>>>        } else if (Cmd->Sym) {
>>> -        assignSectionSymbol(Cmd, CurOutSec ? CurOutSec :
>>> (*OutputSections)[0],
>>> -                            Dot);
>>> +        assignSectionSymbol<ELFT>(
>>> +            Cmd, CurOutSec ? CurOutSec : (*OutputSections)[0], Dot);
>>>        }
>>>        continue;
>>>      }
>>> @@ -653,9 +651,9 @@ void LinkerScript<ELFT>::assignAddresses
>>>    }
>>>
>>>    uintX_t MinVA = std::numeric_limits<uintX_t>::max();
>>> -  for (OutputSectionBase<ELFT> *Sec : *OutputSections) {
>>> +  for (OutputSectionBase *Sec : *OutputSections) {
>>>      if (Sec->Flags & SHF_ALLOC)
>>> -      MinVA = std::min(MinVA, Sec->Addr);
>>> +      MinVA = std::min<uint64_t>(MinVA, Sec->Addr);
>>>      else
>>>        Sec->Addr = 0;
>>>    }
>>> @@ -730,7 +728,7 @@ std::vector<PhdrEntry<ELFT>> LinkerScrip
>>>    }
>>>
>>>    // Add output sections to program headers.
>>> -  for (OutputSectionBase<ELFT> *Sec : *OutputSections) {
>>> +  for (OutputSectionBase *Sec : *OutputSections) {
>>>      if (!(Sec->Flags & SHF_ALLOC))
>>>        break;
>>>
>>> @@ -831,7 +829,7 @@ template <class ELFT> bool LinkerScript<
>>>
>>>  template <class ELFT>
>>>  uint64_t LinkerScript<ELFT>::getOutputSectionAddress(StringRef Name) {
>>> -  for (OutputSectionBase<ELFT> *Sec : *OutputSections)
>>> +  for (OutputSectionBase *Sec : *OutputSections)
>>>      if (Sec->getName() == Name)
>>>        return Sec->Addr;
>>>    error("undefined section " + Name);
>>> @@ -840,7 +838,7 @@ uint64_t LinkerScript<ELFT>::getOutputSe
>>>
>>>  template <class ELFT>
>>>  uint64_t LinkerScript<ELFT>::getOutputSectionLMA(StringRef Name) {
>>> -  for (OutputSectionBase<ELFT> *Sec : *OutputSections)
>>> +  for (OutputSectionBase *Sec : *OutputSections)
>>>      if (Sec->getName() == Name)
>>>        return Sec->getLMA();
>>>    error("undefined section " + Name);
>>> @@ -849,7 +847,7 @@ uint64_t LinkerScript<ELFT>::getOutputSe
>>>
>>>  template <class ELFT>
>>>  uint64_t LinkerScript<ELFT>::getOutputSectionSize(StringRef Name) {
>>> -  for (OutputSectionBase<ELFT> *Sec : *OutputSections)
>>> +  for (OutputSectionBase *Sec : *OutputSections)
>>>      if (Sec->getName() == Name)
>>>        return Sec->Size;
>>>    error("undefined section " + Name);
>>> @@ -858,7 +856,7 @@ uint64_t LinkerScript<ELFT>::getOutputSe
>>>
>>>  template <class ELFT>
>>>  uint64_t LinkerScript<ELFT>::getOutputSectionAlign(StringRef Name) {
>>> -  for (OutputSectionBase<ELFT> *Sec : *OutputSections)
>>> +  for (OutputSectionBase *Sec : *OutputSections)
>>>      if (Sec->getName() == Name)
>>>        return Sec->Addralign;
>>>    error("undefined section " + Name);
>>>
>>> Modified: lld/trunk/ELF/LinkerScript.h
>>> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScri
>>> pt.h?rev=286414&r1=286413&r2=286414&view=diff
>>> ============================================================
>>> ==================
>>> --- lld/trunk/ELF/LinkerScript.h (original)
>>> +++ lld/trunk/ELF/LinkerScript.h Wed Nov  9 17:23:45 2016
>>> @@ -32,7 +32,7 @@ class ScriptParser;
>>>  class SymbolBody;
>>>  template <class ELFT> class InputSectionBase;
>>>  template <class ELFT> class InputSection;
>>> -template <class ELFT> class OutputSectionBase;
>>> +class OutputSectionBase;
>>>  template <class ELFT> class OutputSectionFactory;
>>>  class InputSectionData;
>>>
>>> @@ -240,7 +240,7 @@ public:
>>>    bool isDefined(StringRef S) override;
>>>    bool isAbsolute(StringRef S) override;
>>>
>>> -  std::vector<OutputSectionBase<ELFT> *> *OutputSections;
>>> +  std::vector<OutputSectionBase *> *OutputSections;
>>>
>>>    int getSectionIndex(StringRef Name);
>>>
>>> @@ -262,13 +262,13 @@ private:
>>>
>>>    uintX_t Dot;
>>>    uintX_t LMAOffset = 0;
>>> -  OutputSectionBase<ELFT> *CurOutSec = nullptr;
>>> +  OutputSectionBase *CurOutSec = nullptr;
>>>    uintX_t ThreadBssOffset = 0;
>>> -  void switchTo(OutputSectionBase<ELFT> *Sec);
>>> +  void switchTo(OutputSectionBase *Sec);
>>>    void flush();
>>>    void output(InputSection<ELFT> *Sec);
>>>    void process(BaseCommand &Base);
>>> -  llvm::DenseSet<OutputSectionBase<ELFT> *> AlreadyOutputOS;
>>> +  llvm::DenseSet<OutputSectionBase *> AlreadyOutputOS;
>>>    llvm::DenseSet<InputSectionData *> AlreadyOutputIS;
>>>  };
>>>
>>>
>>> Modified: lld/trunk/ELF/OutputSections.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSect
>>> ions.cpp?rev=286414&r1=286413&r2=286414&view=diff
>>> ============================================================
>>> ==================
>>> --- lld/trunk/ELF/OutputSections.cpp (original)
>>> +++ lld/trunk/ELF/OutputSections.cpp Wed Nov  9 17:23:45 2016
>>> @@ -32,16 +32,15 @@ using namespace llvm::ELF;
>>>  using namespace lld;
>>>  using namespace lld::elf;
>>>
>>> -template <class ELFT>
>>> -OutputSectionBase<ELFT>::OutputSectionBase(StringRef Name, uint32_t
>>> Type,
>>> -                                           uintX_t Flags)
>>> +OutputSectionBase::OutputSectionBase(StringRef Name, uint32_t Type,
>>> +                                     uint64_t Flags)
>>>      : Name(Name) {
>>>    this->Type = Type;
>>>    this->Flags = Flags;
>>>    this->Addralign = 1;
>>>  }
>>>
>>> -template <class ELFT> uint32_t OutputSectionBase<ELFT>::getPhdrFlags()
>>> const {
>>> +uint32_t OutputSectionBase::getPhdrFlags() const {
>>>    uint32_t Ret = PF_R;
>>>    if (Flags & SHF_WRITE)
>>>      Ret |= PF_W;
>>> @@ -51,7 +50,7 @@ template <class ELFT> uint32_t OutputSec
>>>  }
>>>
>>>  template <class ELFT>
>>> -void OutputSectionBase<ELFT>::writeHeaderTo(Elf_Shdr *Shdr) {
>>> +void OutputSectionBase::writeHeaderTo(typename ELFT::Shdr *Shdr) {
>>>    Shdr->sh_entsize = Entsize;
>>>    Shdr->sh_addralign = Addralign;
>>>    Shdr->sh_type = Type;
>>> @@ -66,7 +65,7 @@ void OutputSectionBase<ELFT>::writeHeade
>>>
>>>  template <class ELFT>
>>>  GdbIndexSection<ELFT>::GdbIndexSection()
>>> -    : OutputSectionBase<ELFT>(".gdb_index", SHT_PROGBITS, 0) {}
>>> +    : OutputSectionBase(".gdb_index", SHT_PROGBITS, 0) {}
>>>
>>>  template <class ELFT> void GdbIndexSection<ELFT>::parseDebugSections()
>>> {
>>>    std::vector<InputSection<ELFT> *> &IS =
>>> @@ -110,7 +109,7 @@ template <class ELFT> void GdbIndexSecti
>>>
>>>  template <class ELFT>
>>>  GotPltSection<ELFT>::GotPltSection()
>>> -    : OutputSectionBase<ELFT>(".got.plt", SHT_PROGBITS, SHF_ALLOC |
>>> SHF_WRITE) {
>>> +    : OutputSectionBase(".got.plt", SHT_PROGBITS, SHF_ALLOC |
>>> SHF_WRITE) {
>>>    this->Addralign = Target->GotPltEntrySize;
>>>  }
>>>
>>> @@ -139,7 +138,7 @@ template <class ELFT> void GotPltSection
>>>
>>>  template <class ELFT>
>>>  GotSection<ELFT>::GotSection()
>>> -    : OutputSectionBase<ELFT>(".got", SHT_PROGBITS, SHF_ALLOC |
>>> SHF_WRITE) {
>>> +    : OutputSectionBase(".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE) {
>>>    if (Config->EMachine == EM_MIPS)
>>>      this->Flags |= SHF_MIPS_GPREL;
>>>    this->Addralign = Target->GotEntrySize;
>>> @@ -313,7 +312,7 @@ template <class ELFT> void GotSection<EL
>>>      // Take into account MIPS GOT header.
>>>      // See comment in the GotSection::writeTo.
>>>      MipsPageEntries += 2;
>>> -    for (const OutputSectionBase<ELFT> *OutSec : MipsOutSections) {
>>> +    for (const OutputSectionBase *OutSec : MipsOutSections) {
>>>        // Calculate an upper bound of MIPS GOT entries required to store
>>> page
>>>        // addresses of local symbols. We assume the worst case - each
>>> 64kb
>>>        // page of the output section has at least one GOT relocation
>>> against it.
>>> @@ -408,7 +407,7 @@ template <class ELFT> void GotSection<EL
>>>
>>>  template <class ELFT>
>>>  PltSection<ELFT>::PltSection()
>>> -    : OutputSectionBase<ELFT>(".plt", SHT_PROGBITS, SHF_ALLOC |
>>> SHF_EXECINSTR) {
>>> +    : OutputSectionBase(".plt", SHT_PROGBITS, SHF_ALLOC |
>>> SHF_EXECINSTR) {
>>>    this->Addralign = 16;
>>>  }
>>>
>>> @@ -440,8 +439,7 @@ template <class ELFT> void PltSection<EL
>>>
>>>  template <class ELFT>
>>>  RelocationSection<ELFT>::RelocationSection(StringRef Name, bool Sort)
>>> -    : OutputSectionBase<ELFT>(Name, Config->Rela ? SHT_RELA : SHT_REL,
>>> -                              SHF_ALLOC),
>>> +    : OutputSectionBase(Name, Config->Rela ? SHT_RELA : SHT_REL,
>>> SHF_ALLOC),
>>>        Sort(Sort) {
>>>    this->Entsize = Config->Rela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
>>>    this->Addralign = sizeof(uintX_t);
>>> @@ -504,7 +502,7 @@ template <class ELFT> void RelocationSec
>>>
>>>  template <class ELFT>
>>>  HashTableSection<ELFT>::HashTableSection()
>>> -    : OutputSectionBase<ELFT>(".hash", SHT_HASH, SHF_ALLOC) {
>>> +    : OutputSectionBase(".hash", SHT_HASH, SHF_ALLOC) {
>>>    this->Entsize = sizeof(Elf_Word);
>>>    this->Addralign = sizeof(Elf_Word);
>>>  }
>>> @@ -550,7 +548,7 @@ static uint32_t hashGnu(StringRef Name)
>>>
>>>  template <class ELFT>
>>>  GnuHashTableSection<ELFT>::GnuHashTableSection()
>>> -    : OutputSectionBase<ELFT>(".gnu.hash", SHT_GNU_HASH, SHF_ALLOC) {
>>> +    : OutputSectionBase(".gnu.hash", SHT_GNU_HASH, SHF_ALLOC) {
>>>    this->Entsize = ELFT::Is64Bits ? 0 : 4;
>>>    this->Addralign = sizeof(uintX_t);
>>>  }
>>> @@ -695,7 +693,7 @@ static unsigned getVerDefNum() { return
>>>
>>>  template <class ELFT>
>>>  DynamicSection<ELFT>::DynamicSection()
>>> -    : OutputSectionBase<ELFT>(".dynamic", SHT_DYNAMIC, SHF_ALLOC |
>>> SHF_WRITE) {
>>> +    : OutputSectionBase(".dynamic", SHT_DYNAMIC, SHF_ALLOC | SHF_WRITE)
>>> {
>>>    this->Addralign = sizeof(uintX_t);
>>>    this->Entsize = ELFT::Is64Bits ? 16 : 8;
>>>
>>> @@ -863,7 +861,7 @@ template <class ELFT> void DynamicSectio
>>>
>>>  template <class ELFT>
>>>  EhFrameHeader<ELFT>::EhFrameHeader()
>>> -    : OutputSectionBase<ELFT>(".eh_frame_hdr", SHT_PROGBITS,
>>> SHF_ALLOC) {}
>>> +    : OutputSectionBase(".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC) {}
>>>
>>>  // .eh_frame_hdr contains a binary search table of pointers to FDEs.
>>>  // Each entry of the search table consists of two values,
>>> @@ -925,7 +923,7 @@ template <class ELFT> static uint64_t ge
>>>
>>>  template <class ELFT>
>>>  OutputSection<ELFT>::OutputSection(StringRef Name, uint32_t Type,
>>> uintX_t Flags)
>>> -    : OutputSectionBase<ELFT>(Name, Type, Flags) {
>>> +    : OutputSectionBase(Name, Type, Flags) {
>>>    this->Entsize = getEntsize<ELFT>(Type);
>>>  }
>>>
>>> @@ -956,7 +954,7 @@ template <class ELFT> void OutputSection
>>>  }
>>>
>>>  template <class ELFT>
>>> -void OutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
>>> +void OutputSection<ELFT>::addSection(InputSectionData *C) {
>>>    assert(C->Live);
>>>    auto *S = cast<InputSection<ELFT>>(C);
>>>    Sections.push_back(S);
>>> @@ -1085,7 +1083,7 @@ template <class ELFT> void OutputSection
>>>
>>>  template <class ELFT>
>>>  EhOutputSection<ELFT>::EhOutputSection()
>>> -    : OutputSectionBase<ELFT>(".eh_frame", SHT_PROGBITS, SHF_ALLOC) {}
>>> +    : OutputSectionBase(".eh_frame", SHT_PROGBITS, SHF_ALLOC) {}
>>>
>>>  // Search for an existing CIE record or create a new one.
>>>  // CIE records from input object files are uniquified by their contents
>>> @@ -1170,7 +1168,7 @@ void EhOutputSection<ELFT>::addSectionAu
>>>  }
>>>
>>>  template <class ELFT>
>>> -void EhOutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
>>> +void EhOutputSection<ELFT>::addSection(InputSectionData *C) {
>>>    auto *Sec = cast<EhInputSection<ELFT>>(C);
>>>    Sec->OutSec = this;
>>>    this->updateAlignment(Sec->Alignment);
>>> @@ -1290,7 +1288,7 @@ template <class ELFT> void EhOutputSecti
>>>  template <class ELFT>
>>>  MergeOutputSection<ELFT>::MergeOutputSection(StringRef Name, uint32_t
>>> Type,
>>>                                               uintX_t Flags, uintX_t
>>> Alignment)
>>> -    : OutputSectionBase<ELFT>(Name, Type, Flags),
>>> +    : OutputSectionBase(Name, Type, Flags),
>>>        Builder(StringTableBuilder::RAW, Alignment) {}
>>>
>>>  template <class ELFT> void MergeOutputSection<ELFT>::writeTo(uint8_t
>>> *Buf) {
>>> @@ -1298,7 +1296,7 @@ template <class ELFT> void MergeOutputSe
>>>  }
>>>
>>>  template <class ELFT>
>>> -void MergeOutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
>>> +void MergeOutputSection<ELFT>::addSection(InputSectionData *C) {
>>>    auto *Sec = cast<MergeInputSection<ELFT>>(C);
>>>    Sec->OutSec = this;
>>>    this->updateAlignment(Sec->Alignment);
>>> @@ -1344,8 +1342,7 @@ template <class ELFT> void MergeOutputSe
>>>
>>>  template <class ELFT>
>>>  StringTableSection<ELFT>::StringTableSection(StringRef Name, bool
>>> Dynamic)
>>> -    : OutputSectionBase<ELFT>(Name, SHT_STRTAB,
>>> -                              Dynamic ? (uintX_t)SHF_ALLOC : 0),
>>> +    : OutputSectionBase(Name, SHT_STRTAB, Dynamic ? (uintX_t)SHF_ALLOC
>>> : 0),
>>>        Dynamic(Dynamic) {
>>>    // ELF string tables start with a NUL byte, so 1.
>>>    this->Size = 1;
>>> @@ -1400,9 +1397,9 @@ template <class ELFT> uint32_t DynamicRe
>>>  template <class ELFT>
>>>  SymbolTableSection<ELFT>::SymbolTableSection(
>>>      StringTableSection<ELFT> &StrTabSec)
>>> -    : OutputSectionBase<ELFT>(StrTabSec.isDynamic() ? ".dynsym" :
>>> ".symtab",
>>> -                              StrTabSec.isDynamic() ? SHT_DYNSYM :
>>> SHT_SYMTAB,
>>> -                              StrTabSec.isDynamic() ?
>>> (uintX_t)SHF_ALLOC : 0),
>>> +    : OutputSectionBase(StrTabSec.isDynamic() ? ".dynsym" : ".symtab",
>>> +                        StrTabSec.isDynamic() ? SHT_DYNSYM : SHT_SYMTAB,
>>> +                        StrTabSec.isDynamic() ? (uintX_t)SHF_ALLOC : 0),
>>>        StrTabSec(StrTabSec) {
>>>    this->Entsize = sizeof(Elf_Sym);
>>>    this->Addralign = sizeof(uintX_t);
>>> @@ -1501,7 +1498,7 @@ void SymbolTableSection<ELFT>::writeLoca
>>>          ESym->st_shndx = SHN_ABS;
>>>          ESym->st_value = Body.Value;
>>>        } else {
>>> -        const OutputSectionBase<ELFT> *OutSec = Section->OutSec;
>>> +        const OutputSectionBase *OutSec = Section->OutSec;
>>>          ESym->st_shndx = OutSec->SectionIndex;
>>>          ESym->st_value = OutSec->Addr + Section->getOffset(Body);
>>>        }
>>> @@ -1531,7 +1528,7 @@ void SymbolTableSection<ELFT>::writeGlob
>>>      ESym->setVisibility(Body->symbol()->Visibility);
>>>      ESym->st_value = Body->getVA<ELFT>();
>>>
>>> -    if (const OutputSectionBase<ELFT> *OutSec = getOutputSection(Body))
>>> +    if (const OutputSectionBase *OutSec = getOutputSection(Body))
>>>        ESym->st_shndx = OutSec->SectionIndex;
>>>      else if (isa<DefinedRegular<ELFT>>(Body))
>>>        ESym->st_shndx = SHN_ABS;
>>> @@ -1554,7 +1551,7 @@ void SymbolTableSection<ELFT>::writeGlob
>>>  }
>>>
>>>  template <class ELFT>
>>> -const OutputSectionBase<ELFT> *
>>> +const OutputSectionBase *
>>>  SymbolTableSection<ELFT>::getOutputSection(SymbolBody *Sym) {
>>>    switch (Sym->kind()) {
>>>    case SymbolBody::DefinedSyntheticKind:
>>> @@ -1581,7 +1578,7 @@ SymbolTableSection<ELFT>::getOutputSecti
>>>
>>>  template <class ELFT>
>>>  VersionDefinitionSection<ELFT>::VersionDefinitionSection()
>>> -    : OutputSectionBase<ELFT>(".gnu.version_d", SHT_GNU_verdef,
>>> SHF_ALLOC) {
>>> +    : OutputSectionBase(".gnu.version_d", SHT_GNU_verdef, SHF_ALLOC) {
>>>    this->Addralign = sizeof(uint32_t);
>>>  }
>>>
>>> @@ -1638,7 +1635,7 @@ void VersionDefinitionSection<ELFT>::wri
>>>
>>>  template <class ELFT>
>>>  VersionTableSection<ELFT>::VersionTableSection()
>>> -    : OutputSectionBase<ELFT>(".gnu.version", SHT_GNU_versym,
>>> SHF_ALLOC) {
>>> +    : OutputSectionBase(".gnu.version", SHT_GNU_versym, SHF_ALLOC) {
>>>    this->Addralign = sizeof(uint16_t);
>>>  }
>>>
>>> @@ -1661,7 +1658,7 @@ template <class ELFT> void VersionTableS
>>>
>>>  template <class ELFT>
>>>  VersionNeedSection<ELFT>::VersionNeedSection()
>>> -    : OutputSectionBase<ELFT>(".gnu.version_r", SHT_GNU_verneed,
>>> SHF_ALLOC) {
>>> +    : OutputSectionBase(".gnu.version_r", SHT_GNU_verneed, SHF_ALLOC) {
>>>    this->Addralign = sizeof(uint32_t);
>>>
>>>    // Identifiers in verneed section start at 2 because 0 and 1 are
>>> reserved
>>> @@ -1764,7 +1761,7 @@ static SectionKey<ELFT::Is64Bits> create
>>>  }
>>>
>>>  template <class ELFT>
>>> -std::pair<OutputSectionBase<ELFT> *, bool>
>>> +std::pair<OutputSectionBase *, bool>
>>>  OutputSectionFactory<ELFT>::create(InputSectionBase<ELFT> *C,
>>>                                     StringRef OutsecName) {
>>>    SectionKey<ELFT::Is64Bits> Key = createKey(C, OutsecName);
>>> @@ -1772,11 +1769,11 @@ OutputSectionFactory<ELFT>::create(Input
>>>  }
>>>
>>>  template <class ELFT>
>>> -std::pair<OutputSectionBase<ELFT> *, bool>
>>> +std::pair<OutputSectionBase *, bool>
>>>  OutputSectionFactory<ELFT>::create(const SectionKey<ELFT::Is64Bits>
>>> &Key,
>>>                                     InputSectionBase<ELFT> *C) {
>>>    uintX_t Flags = getOutFlags(C);
>>> -  OutputSectionBase<ELFT> *&Sec = Map[Key];
>>> +  OutputSectionBase *&Sec = Map[Key];
>>>    if (Sec) {
>>>      Sec->Flags |= Flags;
>>>      return {Sec, false};
>>> @@ -1830,10 +1827,11 @@ template struct DenseMapInfo<SectionKey<
>>>
>>>  namespace lld {
>>>  namespace elf {
>>> -template class OutputSectionBase<ELF32LE>;
>>> -template class OutputSectionBase<ELF32BE>;
>>> -template class OutputSectionBase<ELF64LE>;
>>> -template class OutputSectionBase<ELF64BE>;
>>> +
>>> +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 EhFrameHeader<ELF32LE>;
>>>  template class EhFrameHeader<ELF32BE>;
>>>
>>> Modified: lld/trunk/ELF/OutputSections.h
>>> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSect
>>> ions.h?rev=286414&r1=286413&r2=286414&view=diff
>>> ============================================================
>>> ==================
>>> --- lld/trunk/ELF/OutputSections.h (original)
>>> +++ lld/trunk/ELF/OutputSections.h Wed Nov  9 17:23:45 2016
>>> @@ -42,10 +42,8 @@ template <class ELFT> class DefinedRegul
>>>  // input sections, others are created by the linker.
>>>  // The writer creates multiple OutputSections and assign them unique,
>>>  // non-overlapping file offsets and VAs.
>>> -template <class ELFT> class OutputSectionBase {
>>> +class OutputSectionBase {
>>>  public:
>>> -  typedef typename ELFT::uint uintX_t;
>>> -  typedef typename ELFT::Shdr Elf_Shdr;
>>>    enum Kind {
>>>      Base,
>>>      Dynamic,
>>> @@ -66,15 +64,15 @@ public:
>>>      VersTable
>>>    };
>>>
>>> -  OutputSectionBase(StringRef Name, uint32_t Type, uintX_t Flags);
>>> -  void setLMAOffset(uintX_t LMAOff) { LMAOffset = LMAOff; }
>>> -  uintX_t getLMA() const { return Addr + LMAOffset; }
>>> -  void writeHeaderTo(Elf_Shdr *SHdr);
>>> +  OutputSectionBase(StringRef Name, uint32_t Type, uint64_t Flags);
>>> +  void setLMAOffset(uint64_t LMAOff) { LMAOffset = LMAOff; }
>>> +  uint64_t getLMA() const { return Addr + LMAOffset; }
>>> +  template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr
>>> *SHdr);
>>>    StringRef getName() const { return Name; }
>>>
>>> -  virtual void addSection(InputSectionBase<ELFT> *C) {}
>>> +  virtual void addSection(InputSectionData *C) {}
>>>    virtual Kind getKind() const { return Base; }
>>> -  static bool classof(const OutputSectionBase<ELFT> *B) {
>>> +  static bool classof(const OutputSectionBase *B) {
>>>      return B->getKind() == Base;
>>>    }
>>>
>>> @@ -82,7 +80,7 @@ public:
>>>
>>>    uint32_t getPhdrFlags() const;
>>>
>>> -  void updateAlignment(uintX_t Alignment) {
>>> +  void updateAlignment(uint64_t Alignment) {
>>>      if (Alignment > Addralign)
>>>        Addralign = Alignment;
>>>    }
>>> @@ -97,7 +95,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<ELFT> *FirstInPtLoad = nullptr;
>>> +  OutputSectionBase *FirstInPtLoad = nullptr;
>>>
>>>    virtual void finalize() {}
>>>    virtual void finalizePieces() {}
>>> @@ -108,21 +106,20 @@ public:
>>>    StringRef Name;
>>>
>>>    // The following fields correspond to Elf_Shdr members.
>>> -  uintX_t Size = 0;
>>> -  uintX_t Entsize = 0;
>>> -  uintX_t Addralign = 0;
>>> -  uintX_t Offset = 0;
>>> -  uintX_t Flags = 0;
>>> -  uintX_t LMAOffset = 0;
>>> -  uintX_t Addr = 0;
>>> +  uint64_t Size = 0;
>>> +  uint64_t Entsize = 0;
>>> +  uint64_t Addralign = 0;
>>> +  uint64_t Offset = 0;
>>> +  uint64_t Flags = 0;
>>> +  uint64_t LMAOffset = 0;
>>> +  uint64_t Addr = 0;
>>>    uint32_t ShName = 0;
>>>    uint32_t Type = 0;
>>>    uint32_t Info = 0;
>>>    uint32_t Link = 0;
>>>  };
>>>
>>> -template <class ELFT>
>>> -class GdbIndexSection final : public OutputSectionBase<ELFT> {
>>> +template <class ELFT> class GdbIndexSection final : public
>>> OutputSectionBase {
>>>    typedef typename ELFT::uint uintX_t;
>>>
>>>    const unsigned OffsetTypeSize = 4;
>>> @@ -146,8 +143,7 @@ private:
>>>    uint32_t CuTypesOffset;
>>>  };
>>>
>>> -template <class ELFT> class GotSection final : public
>>> OutputSectionBase<ELFT> {
>>> -  typedef OutputSectionBase<ELFT> Base;
>>> +template <class ELFT> class GotSection final : public OutputSectionBase
>>> {
>>>    typedef typename ELFT::uint uintX_t;
>>>
>>>  public:
>>> @@ -163,8 +159,10 @@ public:
>>>    uintX_t getMipsGotOffset(const SymbolBody &B, uintX_t Addend) const;
>>>    uintX_t getGlobalDynAddr(const SymbolBody &B) const;
>>>    uintX_t getGlobalDynOffset(const SymbolBody &B) const;
>>> -  typename Base::Kind getKind() const override { return Base::Got; }
>>> -  static bool classof(const Base *B) { return B->getKind() ==
>>> Base::Got; }
>>> +  Kind getKind() const override { return Got; }
>>> +  static bool classof(const OutputSectionBase *B) {
>>> +    return B->getKind() == Got;
>>> +  }
>>>
>>>    // Returns the symbol which corresponds to the first entry of the
>>> global part
>>>    // of GOT on MIPS platform. It is required to fill up MIPS-specific
>>> dynamic
>>> @@ -192,7 +190,7 @@ private:
>>>    uint32_t TlsIndexOff = -1;
>>>    uint32_t MipsPageEntries = 0;
>>>    // Output sections referenced by MIPS GOT relocations.
>>> -  llvm::SmallPtrSet<const OutputSectionBase<ELFT> *, 10>
>>> MipsOutSections;
>>> +  llvm::SmallPtrSet<const OutputSectionBase *, 10> MipsOutSections;
>>>    llvm::DenseMap<uintX_t, size_t> MipsLocalGotPos;
>>>
>>>    // MIPS ABI requires to create unique GOT entry for each Symbol/Addend
>>> @@ -213,10 +211,8 @@ private:
>>>    void writeMipsGot(uint8_t *Buf);
>>>  };
>>>
>>> -template <class ELFT>
>>> -class GotPltSection final : public OutputSectionBase<ELFT> {
>>> +template <class ELFT> class GotPltSection final : public
>>> OutputSectionBase {
>>>    typedef typename ELFT::uint uintX_t;
>>> -  typedef OutputSectionBase<ELFT> Base;
>>>
>>>  public:
>>>    GotPltSection();
>>> @@ -224,15 +220,16 @@ public:
>>>    void writeTo(uint8_t *Buf) override;
>>>    void addEntry(SymbolBody &Sym);
>>>    bool empty() const;
>>> -  typename Base::Kind getKind() const override { return Base::GotPlt; }
>>> -  static bool classof(const Base *B) { return B->getKind() ==
>>> Base::GotPlt; }
>>> +  Kind getKind() const override { return GotPlt; }
>>> +  static bool classof(const OutputSectionBase *B) {
>>> +    return B->getKind() == GotPlt;
>>> +  }
>>>
>>>  private:
>>>    std::vector<const SymbolBody *> Entries;
>>>  };
>>>
>>> -template <class ELFT> class PltSection final : public
>>> OutputSectionBase<ELFT> {
>>> -  typedef OutputSectionBase<ELFT> Base;
>>> +template <class ELFT> class PltSection final : public OutputSectionBase
>>> {
>>>    typedef typename ELFT::uint uintX_t;
>>>
>>>  public:
>>> @@ -241,8 +238,10 @@ public:
>>>    void writeTo(uint8_t *Buf) override;
>>>    void addEntry(SymbolBody &Sym);
>>>    bool empty() const { return Entries.empty(); }
>>> -  typename Base::Kind getKind() const override { return Base::Plt; }
>>> -  static bool classof(const Base *B) { return B->getKind() ==
>>> Base::Plt; }
>>> +  Kind getKind() const override { return Plt; }
>>> +  static bool classof(const OutputSectionBase *B) {
>>> +    return B->getKind() == Plt;
>>> +  }
>>>
>>>  private:
>>>    std::vector<std::pair<const SymbolBody *, unsigned>> Entries;
>>> @@ -258,7 +257,7 @@ public:
>>>        : Type(Type), Sym(Sym), InputSec(InputSec),
>>> OffsetInSec(OffsetInSec),
>>>          UseSymVA(UseSymVA), Addend(Addend) {}
>>>
>>> -  DynamicReloc(uint32_t Type, const OutputSectionBase<ELFT> *OutputSec,
>>> +  DynamicReloc(uint32_t Type, const OutputSectionBase *OutputSec,
>>>                 uintX_t OffsetInSec, bool UseSymVA, SymbolBody *Sym,
>>>                 uintX_t Addend)
>>>        : Type(Type), Sym(Sym), OutputSec(OutputSec),
>>> OffsetInSec(OffsetInSec),
>>> @@ -267,14 +266,14 @@ public:
>>>    uintX_t getOffset() const;
>>>    uintX_t getAddend() const;
>>>    uint32_t getSymIndex() const;
>>> -  const OutputSectionBase<ELFT> *getOutputSec() const { return
>>> OutputSec; }
>>> +  const OutputSectionBase *getOutputSec() const { return OutputSec; }
>>>
>>>    uint32_t Type;
>>>
>>>  private:
>>>    SymbolBody *Sym;
>>>    const InputSectionBase<ELFT> *InputSec = nullptr;
>>> -  const OutputSectionBase<ELFT> *OutputSec = nullptr;
>>> +  const OutputSectionBase *OutputSec = nullptr;
>>>    uintX_t OffsetInSec;
>>>    bool UseSymVA;
>>>    uintX_t Addend;
>>> @@ -286,8 +285,8 @@ struct SymbolTableEntry {
>>>  };
>>>
>>>  template <class ELFT>
>>> -class SymbolTableSection final : public OutputSectionBase<ELFT> {
>>> -  typedef OutputSectionBase<ELFT> Base;
>>> +class SymbolTableSection final : public OutputSectionBase {
>>> +  typedef OutputSectionBase Base;
>>>
>>>  public:
>>>    typedef typename ELFT::Shdr Elf_Shdr;
>>> @@ -313,7 +312,7 @@ private:
>>>    void writeLocalSymbols(uint8_t *&Buf);
>>>    void writeGlobalSymbols(uint8_t *Buf);
>>>
>>> -  const OutputSectionBase<ELFT> *getOutputSection(SymbolBody *Sym);
>>> +  const OutputSectionBase *getOutputSection(SymbolBody *Sym);
>>>
>>>    // A vector of symbols and their string table offsets.
>>>    std::vector<SymbolTableEntry> Symbols;
>>> @@ -328,17 +327,18 @@ private:
>>>  // The section shall contain an array of Elf_Verdef structures,
>>> optionally
>>>  // followed by an array of Elf_Verdaux structures.
>>>  template <class ELFT>
>>> -class VersionDefinitionSection final : public OutputSectionBase<ELFT> {
>>> +class VersionDefinitionSection final : public OutputSectionBase {
>>>    typedef typename ELFT::Verdef Elf_Verdef;
>>>    typedef typename ELFT::Verdaux Elf_Verdaux;
>>> -  typedef OutputSectionBase<ELFT> Base;
>>>
>>>  public:
>>>    VersionDefinitionSection();
>>>    void finalize() override;
>>>    void writeTo(uint8_t *Buf) override;
>>> -  typename Base::Kind getKind() const override { return Base::VersDef; }
>>> -  static bool classof(const Base *B) { return B->getKind() ==
>>> Base::VersDef; }
>>> +  Kind getKind() const override { return VersDef; }
>>> +  static bool classof(const OutputSectionBase *B) {
>>> +    return B->getKind() == VersDef;
>>> +  }
>>>
>>>  private:
>>>    void writeOne(uint8_t *Buf, uint32_t Index, StringRef Name, size_t
>>> NameOff);
>>> @@ -353,16 +353,17 @@ private:
>>>  // The values 0 and 1 are reserved. All other values are used for
>>> versions in
>>>  // the own object or in any of the dependencies.
>>>  template <class ELFT>
>>> -class VersionTableSection final : public OutputSectionBase<ELFT> {
>>> -  typedef OutputSectionBase<ELFT> Base;
>>> +class VersionTableSection final : public OutputSectionBase {
>>>    typedef typename ELFT::Versym Elf_Versym;
>>>
>>>  public:
>>>    VersionTableSection();
>>>    void finalize() override;
>>>    void writeTo(uint8_t *Buf) override;
>>> -  typename Base::Kind getKind() const override { return
>>> Base::VersTable; }
>>> -  static bool classof(const Base *B) { return B->getKind() ==
>>> Base::VersTable; }
>>> +  Kind getKind() const override { return VersTable; }
>>> +  static bool classof(const OutputSectionBase *B) {
>>> +    return B->getKind() == VersTable;
>>> +  }
>>>  };
>>>
>>>  // The .gnu.version_r section defines the version identifiers used by
>>> @@ -371,8 +372,7 @@ public:
>>>  // a reference to a linked list of Elf_Vernaux data structures which
>>> define the
>>>  // mapping from version identifiers to version names.
>>>  template <class ELFT>
>>> -class VersionNeedSection final : public OutputSectionBase<ELFT> {
>>> -  typedef OutputSectionBase<ELFT> Base;
>>> +class VersionNeedSection final : public OutputSectionBase {
>>>    typedef typename ELFT::Verneed Elf_Verneed;
>>>    typedef typename ELFT::Vernaux Elf_Vernaux;
>>>
>>> @@ -389,16 +389,16 @@ public:
>>>    void finalize() override;
>>>    void writeTo(uint8_t *Buf) override;
>>>    size_t getNeedNum() const { return Needed.size(); }
>>> -  typename Base::Kind getKind() const override { return Base::VersNeed;
>>> }
>>> -  static bool classof(const Base *B) { return B->getKind() ==
>>> Base::VersNeed; }
>>> +  Kind getKind() const override { return VersNeed; }
>>> +  static bool classof(const OutputSectionBase *B) {
>>> +    return B->getKind() == VersNeed;
>>> +  }
>>>  };
>>>
>>> -template <class ELFT>
>>> -class RelocationSection final : public OutputSectionBase<ELFT> {
>>> +template <class ELFT> class RelocationSection final : public
>>> OutputSectionBase {
>>>    typedef typename ELFT::Rel Elf_Rel;
>>>    typedef typename ELFT::Rela Elf_Rela;
>>>    typedef typename ELFT::uint uintX_t;
>>> -  typedef OutputSectionBase<ELFT> Base;
>>>
>>>  public:
>>>    RelocationSection(StringRef Name, bool Sort);
>>> @@ -407,9 +407,11 @@ public:
>>>    void finalize() override;
>>>    void writeTo(uint8_t *Buf) override;
>>>    bool hasRelocs() const { return !Relocs.empty(); }
>>> -  typename Base::Kind getKind() const override { return Base::Reloc; }
>>> +  Kind getKind() const override { return Reloc; }
>>>    size_t getRelativeRelocCount() const { return NumRelativeRelocs; }
>>> -  static bool classof(const Base *B) { return B->getKind() ==
>>> Base::Reloc; }
>>> +  static bool classof(const OutputSectionBase *B) {
>>> +    return B->getKind() == Reloc;
>>> +  }
>>>
>>>  private:
>>>    bool Sort;
>>> @@ -417,9 +419,7 @@ private:
>>>    std::vector<DynamicReloc<ELFT>> Relocs;
>>>  };
>>>
>>> -template <class ELFT>
>>> -class OutputSection final : public OutputSectionBase<ELFT> {
>>> -  typedef OutputSectionBase<ELFT> Base;
>>> +template <class ELFT> class OutputSection final : public
>>> OutputSectionBase {
>>>
>>>  public:
>>>    typedef typename ELFT::Shdr Elf_Shdr;
>>> @@ -428,33 +428,36 @@ public:
>>>    typedef typename ELFT::Rela Elf_Rela;
>>>    typedef typename ELFT::uint uintX_t;
>>>    OutputSection(StringRef Name, uint32_t Type, uintX_t Flags);
>>> -  void addSection(InputSectionBase<ELFT> *C) override;
>>> +  void addSection(InputSectionData *C) override;
>>>    void sortInitFini();
>>>    void sortCtorsDtors();
>>>    void writeTo(uint8_t *Buf) override;
>>>    void finalize() override;
>>>    void assignOffsets() override;
>>> -  typename Base::Kind getKind() const override { return Base::Regular; }
>>> -  static bool classof(const Base *B) { return B->getKind() ==
>>> Base::Regular; }
>>> +  Kind getKind() const override { return Regular; }
>>> +  static bool classof(const OutputSectionBase *B) {
>>> +    return B->getKind() == Regular;
>>> +  }
>>>    std::vector<InputSection<ELFT> *> Sections;
>>>  };
>>>
>>>  template <class ELFT>
>>> -class MergeOutputSection final : public OutputSectionBase<ELFT> {
>>> +class MergeOutputSection final : public OutputSectionBase {
>>>    typedef typename ELFT::uint uintX_t;
>>> -  typedef OutputSectionBase<ELFT> Base;
>>>
>>>  public:
>>>    MergeOutputSection(StringRef Name, uint32_t Type, uintX_t Flags,
>>>                       uintX_t Alignment);
>>> -  void addSection(InputSectionBase<ELFT> *S) override;
>>> +  void addSection(InputSectionData *S) override;
>>>    void writeTo(uint8_t *Buf) override;
>>>    unsigned getOffset(llvm::CachedHashStringRef Val);
>>>    void finalize() override;
>>>    void finalizePieces() override;
>>>    bool shouldTailMerge() const;
>>> -  typename Base::Kind getKind() const override { return Base::Merge; }
>>> -  static bool classof(const Base *B) { return B->getKind() ==
>>> Base::Merge; }
>>> +  Kind getKind() const override { return Merge; }
>>> +  static bool classof(const OutputSectionBase *B) {
>>> +    return B->getKind() == Merge;
>>> +  }
>>>
>>>  private:
>>>    llvm::StringTableBuilder Builder;
>>> @@ -467,13 +470,11 @@ struct CieRecord {
>>>  };
>>>
>>>  // Output section for .eh_frame.
>>> -template <class ELFT>
>>> -class EhOutputSection final : public OutputSectionBase<ELFT> {
>>> +template <class ELFT> class EhOutputSection final : public
>>> OutputSectionBase {
>>>    typedef typename ELFT::uint uintX_t;
>>>    typedef typename ELFT::Shdr Elf_Shdr;
>>>    typedef typename ELFT::Rel Elf_Rel;
>>>    typedef typename ELFT::Rela Elf_Rela;
>>> -  typedef OutputSectionBase<ELFT> Base;
>>>
>>>  public:
>>>    EhOutputSection();
>>> @@ -481,9 +482,11 @@ public:
>>>    void finalize() override;
>>>    bool empty() const { return Sections.empty(); }
>>>
>>> -  void addSection(InputSectionBase<ELFT> *S) override;
>>> -  typename Base::Kind getKind() const override { return Base::EHFrame; }
>>> -  static bool classof(const Base *B) { return B->getKind() ==
>>> Base::EHFrame; }
>>> +  void addSection(InputSectionData *S) override;
>>> +  Kind getKind() const override { return EHFrame; }
>>> +  static bool classof(const OutputSectionBase *B) {
>>> +    return B->getKind() == EHFrame;
>>> +  }
>>>
>>>    size_t NumFdes = 0;
>>>
>>> @@ -509,8 +512,7 @@ private:
>>>  };
>>>
>>>  template <class ELFT>
>>> -class StringTableSection final : public OutputSectionBase<ELFT> {
>>> -  typedef OutputSectionBase<ELFT> Base;
>>> +class StringTableSection final : public OutputSectionBase {
>>>
>>>  public:
>>>    typedef typename ELFT::uint uintX_t;
>>> @@ -518,8 +520,10 @@ public:
>>>    unsigned addString(StringRef S, bool HashIt = true);
>>>    void writeTo(uint8_t *Buf) override;
>>>    bool isDynamic() const { return Dynamic; }
>>> -  typename Base::Kind getKind() const override { return Base::StrTable;
>>> }
>>> -  static bool classof(const Base *B) { return B->getKind() ==
>>> Base::StrTable; }
>>> +  Kind getKind() const override { return StrTable; }
>>> +  static bool classof(const OutputSectionBase *B) {
>>> +    return B->getKind() == StrTable;
>>> +  }
>>>
>>>  private:
>>>    const bool Dynamic;
>>> @@ -527,27 +531,26 @@ private:
>>>    std::vector<StringRef> Strings;
>>>  };
>>>
>>> -template <class ELFT>
>>> -class HashTableSection final : public OutputSectionBase<ELFT> {
>>> +template <class ELFT> class HashTableSection final : public
>>> OutputSectionBase {
>>>    typedef typename ELFT::Word Elf_Word;
>>> -  typedef OutputSectionBase<ELFT> Base;
>>>
>>>  public:
>>>    HashTableSection();
>>>    void finalize() override;
>>>    void writeTo(uint8_t *Buf) override;
>>> -  typename Base::Kind getKind() const override { return
>>> Base::HashTable; }
>>> -  static bool classof(const Base *B) { return B->getKind() ==
>>> Base::HashTable; }
>>> +  Kind getKind() const override { return HashTable; }
>>> +  static bool classof(const OutputSectionBase *B) {
>>> +    return B->getKind() == HashTable;
>>> +  }
>>>  };
>>>
>>>  // Outputs GNU Hash section. For detailed explanation see:
>>>  // https://blogs.oracle.com/ali/entry/gnu_hash_elf_sections
>>>  template <class ELFT>
>>> -class GnuHashTableSection final : public OutputSectionBase<ELFT> {
>>> +class GnuHashTableSection final : public OutputSectionBase {
>>>    typedef typename ELFT::Off Elf_Off;
>>>    typedef typename ELFT::Word Elf_Word;
>>>    typedef typename ELFT::uint uintX_t;
>>> -  typedef OutputSectionBase<ELFT> Base;
>>>
>>>  public:
>>>    GnuHashTableSection();
>>> @@ -557,9 +560,9 @@ public:
>>>    // Adds symbols to the hash table.
>>>    // Sorts the input to satisfy GNU hash section requirements.
>>>    void addSymbols(std::vector<SymbolTableEntry> &Symbols);
>>> -  typename Base::Kind getKind() const override { return
>>> Base::GnuHashTable; }
>>> -  static bool classof(const Base *B) {
>>> -    return B->getKind() == Base::GnuHashTable;
>>> +  Kind getKind() const override { return GnuHashTable; }
>>> +  static bool classof(const OutputSectionBase *B) {
>>> +    return B->getKind() == GnuHashTable;
>>>    }
>>>
>>>  private:
>>> @@ -583,9 +586,7 @@ private:
>>>    unsigned Shift2;
>>>  };
>>>
>>> -template <class ELFT>
>>> -class DynamicSection final : public OutputSectionBase<ELFT> {
>>> -  typedef OutputSectionBase<ELFT> Base;
>>> +template <class ELFT> class DynamicSection final : public
>>> OutputSectionBase {
>>>    typedef typename ELFT::Dyn Elf_Dyn;
>>>    typedef typename ELFT::Rel Elf_Rel;
>>>    typedef typename ELFT::Rela Elf_Rela;
>>> @@ -600,12 +601,12 @@ class DynamicSection final : public Outp
>>>    struct Entry {
>>>      int32_t Tag;
>>>      union {
>>> -      OutputSectionBase<ELFT> *OutSec;
>>> +      OutputSectionBase *OutSec;
>>>        uint64_t Val;
>>>        const SymbolBody *Sym;
>>>      };
>>>      enum KindT { SecAddr, SecSize, SymAddr, PlainInt } Kind;
>>> -    Entry(int32_t Tag, OutputSectionBase<ELFT> *OutSec, KindT Kind =
>>> SecAddr)
>>> +    Entry(int32_t Tag, OutputSectionBase *OutSec, KindT Kind = SecAddr)
>>>          : Tag(Tag), OutSec(OutSec), Kind(Kind) {}
>>>      Entry(int32_t Tag, uint64_t Val) : Tag(Tag), Val(Val),
>>> Kind(PlainInt) {}
>>>      Entry(int32_t Tag, const SymbolBody *Sym)
>>> @@ -621,8 +622,10 @@ public:
>>>    DynamicSection();
>>>    void finalize() override;
>>>    void writeTo(uint8_t *Buf) override;
>>> -  typename Base::Kind getKind() const override { return Base::Dynamic; }
>>> -  static bool classof(const Base *B) { return B->getKind() ==
>>> Base::Dynamic; }
>>> +  Kind getKind() const override { return Dynamic; }
>>> +  static bool classof(const OutputSectionBase *B) {
>>> +    return B->getKind() == Dynamic;
>>> +  }
>>>
>>>  private:
>>>    void addEntries();
>>> @@ -638,19 +641,17 @@ private:
>>>  // Detailed info about internals can be found in Ian Lance Taylor's
>>> blog:
>>>  // http://www.airs.com/blog/archives/460 (".eh_frame")
>>>  // http://www.airs.com/blog/archives/462 (".eh_frame_hdr")
>>> -template <class ELFT>
>>> -class EhFrameHeader final : public OutputSectionBase<ELFT> {
>>> +template <class ELFT> class EhFrameHeader final : public
>>> OutputSectionBase {
>>>    typedef typename ELFT::uint uintX_t;
>>> -  typedef OutputSectionBase<ELFT> Base;
>>>
>>>  public:
>>>    EhFrameHeader();
>>>    void finalize() override;
>>>    void writeTo(uint8_t *Buf) override;
>>>    void addFde(uint32_t Pc, uint32_t FdeVA);
>>> -  typename Base::Kind getKind() const override { return
>>> Base::EHFrameHdr; }
>>> -  static bool classof(const Base *B) {
>>> -    return B->getKind() == Base::EHFrameHdr;
>>> +  Kind getKind() const override { return EHFrameHdr; }
>>> +  static bool classof(const OutputSectionBase *B) {
>>> +    return B->getKind() == EHFrameHdr;
>>>    }
>>>
>>>  private:
>>> @@ -680,7 +681,7 @@ template <class ELFT> struct Out {
>>>    static HashTableSection<ELFT> *HashTab;
>>>    static OutputSection<ELFT> *Bss;
>>>    static OutputSection<ELFT> *MipsRldMap;
>>> -  static OutputSectionBase<ELFT> *Opd;
>>> +  static OutputSectionBase *Opd;
>>>    static uint8_t *OpdBuf;
>>>    static PltSection<ELFT> *Plt;
>>>    static RelocationSection<ELFT> *RelaDyn;
>>> @@ -694,12 +695,12 @@ template <class ELFT> struct Out {
>>>    static VersionTableSection<ELFT> *VerSym;
>>>    static VersionNeedSection<ELFT> *VerNeed;
>>>    static Elf_Phdr *TlsPhdr;
>>> -  static OutputSectionBase<ELFT> *DebugInfo;
>>> -  static OutputSectionBase<ELFT> *ElfHeader;
>>> -  static OutputSectionBase<ELFT> *ProgramHeaders;
>>> -  static OutputSectionBase<ELFT> *PreinitArray;
>>> -  static OutputSectionBase<ELFT> *InitArray;
>>> -  static OutputSectionBase<ELFT> *FiniArray;
>>> +  static OutputSectionBase *DebugInfo;
>>> +  static OutputSectionBase *ElfHeader;
>>> +  static OutputSectionBase *ProgramHeaders;
>>> +  static OutputSectionBase *PreinitArray;
>>> +  static OutputSectionBase *InitArray;
>>> +  static OutputSectionBase *FiniArray;
>>>  };
>>>
>>>  template <bool Is64Bits> struct SectionKey {
>>> @@ -720,13 +721,13 @@ template <class ELFT> class OutputSectio
>>>    typedef typename elf::SectionKey<ELFT::Is64Bits> Key;
>>>
>>>  public:
>>> -  std::pair<OutputSectionBase<ELFT> *, bool>
>>> create(InputSectionBase<ELFT> *C,
>>> -                                                    StringRef
>>> OutsecName);
>>> -  std::pair<OutputSectionBase<ELFT> *, bool>
>>> +  std::pair<OutputSectionBase *, bool> create(InputSectionBase<ELFT> *C,
>>> +                                              StringRef OutsecName);
>>> +  std::pair<OutputSectionBase *, bool>
>>>    create(const SectionKey<ELFT::Is64Bits> &Key, InputSectionBase<ELFT>
>>> *C);
>>>
>>>  private:
>>> -  llvm::SmallDenseMap<Key, OutputSectionBase<ELFT> *> Map;
>>> +  llvm::SmallDenseMap<Key, OutputSectionBase *> Map;
>>>  };
>>>
>>>  template <class ELFT> uint64_t getHeaderSize() {
>>> @@ -746,7 +747,7 @@ template <class ELFT> GotSection<ELFT> *
>>>  template <class ELFT> HashTableSection<ELFT> *Out<ELFT>::HashTab;
>>>  template <class ELFT> OutputSection<ELFT> *Out<ELFT>::Bss;
>>>  template <class ELFT> OutputSection<ELFT> *Out<ELFT>::MipsRldMap;
>>> -template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::Opd;
>>> +template <class ELFT> OutputSectionBase *Out<ELFT>::Opd;
>>>  template <class ELFT> uint8_t *Out<ELFT>::OpdBuf;
>>>  template <class ELFT> PltSection<ELFT> *Out<ELFT>::Plt;
>>>  template <class ELFT> RelocationSection<ELFT> *Out<ELFT>::RelaDyn;
>>> @@ -760,12 +761,12 @@ template <class ELFT> VersionDefinitionS
>>>  template <class ELFT> VersionTableSection<ELFT> *Out<ELFT>::VerSym;
>>>  template <class ELFT> VersionNeedSection<ELFT> *Out<ELFT>::VerNeed;
>>>  template <class ELFT> typename ELFT::Phdr *Out<ELFT>::TlsPhdr;
>>> -template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::DebugInfo;
>>> -template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::ElfHeader;
>>> -template <class ELFT> OutputSectionBase<ELFT>
>>> *Out<ELFT>::ProgramHeaders;
>>> -template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::PreinitArray;
>>> -template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::InitArray;
>>> -template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::FiniArray;
>>> +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;
>>>  } // namespace elf
>>>  } // namespace lld
>>>
>>>
>>> Modified: lld/trunk/ELF/SymbolTable.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTabl
>>> e.cpp?rev=286414&r1=286413&r2=286414&view=diff
>>> ============================================================
>>> ==================
>>> --- lld/trunk/ELF/SymbolTable.cpp (original)
>>> +++ lld/trunk/ELF/SymbolTable.cpp Wed Nov  9 17:23:45 2016
>>> @@ -429,8 +429,7 @@ Symbol *SymbolTable<ELFT>::addRegular(St
>>>  }
>>>
>>>  template <typename ELFT>
>>> -Symbol *SymbolTable<ELFT>::addSynthetic(StringRef N,
>>> -                                        OutputSectionBase<ELFT>
>>> *Section,
>>> +Symbol *SymbolTable<ELFT>::addSynthetic(StringRef N, OutputSectionBase
>>> *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/SymbolTabl
>>> e.h?rev=286414&r1=286413&r2=286414&view=diff
>>> ============================================================
>>> ==================
>>> --- lld/trunk/ELF/SymbolTable.h (original)
>>> +++ lld/trunk/ELF/SymbolTable.h Wed Nov  9 17:23:45 2016
>>> @@ -19,7 +19,7 @@
>>>  namespace lld {
>>>  namespace elf {
>>>  class Lazy;
>>> -template <class ELFT> class OutputSectionBase;
>>> +class OutputSectionBase;
>>>  struct Symbol;
>>>
>>>  typedef llvm::CachedHashStringRef SymName;
>>> @@ -67,8 +67,8 @@ public:
>>>    Symbol *addRegular(StringRef Name, uint8_t StOther,
>>>                       InputSectionBase<ELFT> *Section, uint8_t Binding,
>>>                       uint8_t Type, uintX_t Value);
>>> -  Symbol *addSynthetic(StringRef N, OutputSectionBase<ELFT> *Section,
>>> -                       uintX_t Value, uint8_t StOther);
>>> +  Symbol *addSynthetic(StringRef N, OutputSectionBase *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.cp
>>> p?rev=286414&r1=286413&r2=286414&view=diff
>>> ============================================================
>>> ==================
>>> --- lld/trunk/ELF/Symbols.cpp (original)
>>> +++ lld/trunk/ELF/Symbols.cpp Wed Nov  9 17:23:45 2016
>>> @@ -33,7 +33,7 @@ static typename ELFT::uint getSymVA(cons
>>>    switch (Body.kind()) {
>>>    case SymbolBody::DefinedSyntheticKind: {
>>>      auto &D = cast<DefinedSynthetic<ELFT>>(Body);
>>> -    const OutputSectionBase<ELFT> *Sec = D.Section;
>>> +    const OutputSectionBase *Sec = D.Section;
>>>      if (!Sec)
>>>        return D.Value;
>>>      if (D.Value == DefinedSynthetic<ELFT>::SectionEnd)
>>> @@ -216,7 +216,7 @@ Undefined::Undefined(uint32_t NameOffset
>>>
>>>  template <typename ELFT>
>>>  DefinedSynthetic<ELFT>::DefinedSynthetic(StringRef N, uintX_t Value,
>>> -                                         OutputSectionBase<ELFT>
>>> *Section)
>>> +                                         OutputSectionBase *Section)
>>>      : Defined(SymbolBody::DefinedSyntheticKind, N, STV_HIDDEN, 0 /*
>>> Type */),
>>>        Value(Value), Section(Section) {}
>>>
>>>
>>> Modified: lld/trunk/ELF/Symbols.h
>>> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?
>>> rev=286414&r1=286413&r2=286414&view=diff
>>> ============================================================
>>> ==================
>>> --- lld/trunk/ELF/Symbols.h (original)
>>> +++ lld/trunk/ELF/Symbols.h Wed Nov  9 17:23:45 2016
>>> @@ -31,7 +31,7 @@ class LazyObjectFile;
>>>  class SymbolBody;
>>>  template <class ELFT> class ObjectFile;
>>>  template <class ELFT> class OutputSection;
>>> -template <class ELFT> class OutputSectionBase;
>>> +class OutputSectionBase;
>>>  template <class ELFT> class SharedFile;
>>>
>>>  struct Symbol;
>>> @@ -249,8 +249,7 @@ InputSectionBase<ELFT> *DefinedRegular<E
>>>  template <class ELFT> class DefinedSynthetic : public Defined {
>>>  public:
>>>    typedef typename ELFT::uint uintX_t;
>>> -  DefinedSynthetic(StringRef N, uintX_t Value,
>>> -                   OutputSectionBase<ELFT> *Section);
>>> +  DefinedSynthetic(StringRef N, uintX_t Value, OutputSectionBase
>>> *Section);
>>>
>>>    static bool classof(const SymbolBody *S) {
>>>      return S->kind() == SymbolBody::DefinedSyntheticKind;
>>> @@ -261,7 +260,7 @@ public:
>>>    static const uintX_t SectionEnd = uintX_t(-1);
>>>
>>>    uintX_t Value;
>>> -  const OutputSectionBase<ELFT> *Section;
>>> +  const OutputSectionBase *Section;
>>>  };
>>>
>>>  class Undefined : public SymbolBody {
>>>
>>> Modified: lld/trunk/ELF/Writer.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp
>>> ?rev=286414&r1=286413&r2=286414&view=diff
>>> ============================================================
>>> ==================
>>> --- lld/trunk/ELF/Writer.cpp (original)
>>> +++ lld/trunk/ELF/Writer.cpp Wed Nov  9 17:23:45 2016
>>> @@ -77,13 +77,13 @@ private:
>>>
>>>    std::unique_ptr<FileOutputBuffer> Buffer;
>>>
>>> -  std::vector<OutputSectionBase<ELFT> *> OutputSections;
>>> +  std::vector<OutputSectionBase *> OutputSections;
>>>    OutputSectionFactory<ELFT> Factory;
>>>
>>>    void addRelIpltSymbols();
>>>    void addStartEndSymbols();
>>> -  void addStartStopSymbols(OutputSectionBase<ELFT> *Sec);
>>> -  OutputSectionBase<ELFT> *findSection(StringRef Name);
>>> +  void addStartStopSymbols(OutputSectionBase *Sec);
>>> +  OutputSectionBase *findSection(StringRef Name);
>>>
>>>    std::vector<Phdr> Phdrs;
>>>
>>> @@ -221,9 +221,9 @@ template <class ELFT> void Writer<ELFT>:
>>>    Out<ELFT>::VerSym = make<VersionTableSection<ELFT>>();
>>>    Out<ELFT>::VerNeed = make<VersionNeedSection<ELFT>>();
>>>
>>> -  Out<ELFT>::ElfHeader = make<OutputSectionBase<ELFT>>("", 0,
>>> SHF_ALLOC);
>>> +  Out<ELFT>::ElfHeader = make<OutputSectionBase>("", 0, SHF_ALLOC);
>>>    Out<ELFT>::ElfHeader->Size = sizeof(Elf_Ehdr);
>>> -  Out<ELFT>::ProgramHeaders = make<OutputSectionBase<ELFT>>("", 0,
>>> SHF_ALLOC);
>>> +  Out<ELFT>::ProgramHeaders = make<OutputSectionBase>("", 0, SHF_ALLOC);
>>>    Out<ELFT>::ProgramHeaders->updateAlignment(sizeof(uintX_t));
>>>
>>>    if (needsInterpSection<ELFT>()) {
>>> @@ -411,11 +411,10 @@ static int getPPC64SectionRank(StringRef
>>>        .Default(1);
>>>  }
>>>
>>> -template <class ELFT>
>>> -bool elf::isRelroSection(const OutputSectionBase<ELFT> *Sec) {
>>> +template <class ELFT> bool elf::isRelroSection(const OutputSectionBase
>>> *Sec) {
>>>    if (!Config->ZRelro)
>>>      return false;
>>> -  typename ELFT::uint Flags = Sec->Flags;
>>> +  uint64_t Flags = Sec->Flags;
>>>    if (!(Flags & SHF_ALLOC) || !(Flags & SHF_WRITE))
>>>      return false;
>>>    if (Flags & SHF_TLS)
>>> @@ -434,8 +433,8 @@ bool elf::isRelroSection(const OutputSec
>>>  }
>>>
>>>  template <class ELFT>
>>> -static bool compareSectionsNonScript(const OutputSectionBase<ELFT> *A,
>>> -                                     const OutputSectionBase<ELFT> *B) {
>>> +static bool compareSectionsNonScript(const OutputSectionBase *A,
>>> +                                     const OutputSectionBase *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->getName() == ".interp";
>>> @@ -496,8 +495,8 @@ static bool compareSectionsNonScript(con
>>>      return BIsNoBits;
>>>
>>>    // We place RelRo section before plain r/w ones.
>>> -  bool AIsRelRo = isRelroSection(A);
>>> -  bool BIsRelRo = isRelroSection(B);
>>> +  bool AIsRelRo = isRelroSection<ELFT>(A);
>>> +  bool BIsRelRo = isRelroSection<ELFT>(B);
>>>    if (AIsRelRo != BIsRelRo)
>>>      return AIsRelRo;
>>>
>>> @@ -512,8 +511,8 @@ static bool compareSectionsNonScript(con
>>>
>>>  // Output section ordering is determined by this function.
>>>  template <class ELFT>
>>> -static bool compareSections(const OutputSectionBase<ELFT> *A,
>>> -                            const OutputSectionBase<ELFT> *B) {
>>> +static bool compareSections(const OutputSectionBase *A,
>>> +                            const OutputSectionBase *B) {
>>>    // For now, put sections mentioned in a linker script first.
>>>    int AIndex = Script<ELFT>::X->getSectionIndex(A->getName());
>>>    int BIndex = Script<ELFT>::X->getSectionIndex(B->getName());
>>> @@ -525,7 +524,7 @@ static bool compareSections(const Output
>>>    if (AInScript)
>>>      return AIndex < BIndex;
>>>
>>> -  return compareSectionsNonScript(A, B);
>>> +  return compareSectionsNonScript<ELFT>(A, B);
>>>  }
>>>
>>>  // Program header entry
>>> @@ -535,7 +534,7 @@ PhdrEntry<ELFT>::PhdrEntry(unsigned Type
>>>    H.p_flags = Flags;
>>>  }
>>>
>>> -template <class ELFT> void PhdrEntry<ELFT>::add(OutputSectionBase<ELFT>
>>> *Sec) {
>>> +template <class ELFT> void PhdrEntry<ELFT>::add(OutputSectionBase
>>> *Sec) {
>>>    Last = Sec;
>>>    if (!First)
>>>      First = Sec;
>>> @@ -545,9 +544,9 @@ template <class ELFT> void PhdrEntry<ELF
>>>  }
>>>
>>>  template <class ELFT>
>>> -static Symbol *
>>> -addOptionalSynthetic(StringRef Name, OutputSectionBase<ELFT> *Sec,
>>> -                     typename ELFT::uint Val, uint8_t StOther =
>>> STV_HIDDEN) {
>>> +static Symbol *addOptionalSynthetic(StringRef Name, OutputSectionBase
>>> *Sec,
>>> +                                    typename ELFT::uint Val,
>>> +                                    uint8_t StOther = STV_HIDDEN) {
>>>    SymbolBody *S = Symtab<ELFT>::X->find(Name);
>>>    if (!S)
>>>      return nullptr;
>>> @@ -566,11 +565,11 @@ template <class ELFT> void Writer<ELFT>:
>>>    if (Out<ELFT>::DynSymTab || !Out<ELFT>::RelaPlt)
>>>      return;
>>>    StringRef S = Config->Rela ? "__rela_iplt_start" : "__rel_iplt_start";
>>> -  addOptionalSynthetic(S, Out<ELFT>::RelaPlt, 0);
>>> +  addOptionalSynthetic<ELFT>(S, Out<ELFT>::RelaPlt, 0);
>>>
>>>    S = Config->Rela ? "__rela_iplt_end" : "__rel_iplt_end";
>>> -  addOptionalSynthetic(S, Out<ELFT>::RelaPlt,
>>> -                       DefinedSynthetic<ELFT>::SectionEnd);
>>> +  addOptionalSynthetic<ELFT>(S, Out<ELFT>::RelaPlt,
>>> +                             DefinedSynthetic<ELFT>::SectionEnd);
>>>  }
>>>
>>>  // The linker is expected to define some symbols depending on
>>> @@ -587,7 +586,7 @@ template <class ELFT> void Writer<ELFT>:
>>>      // On MIPS O32 ABI, _gp_disp is a magic symbol designates offset
>>> between
>>>      // start of function and 'gp' pointer into GOT.
>>>      Symbol *Sym =
>>> -        addOptionalSynthetic("_gp_disp", Out<ELFT>::Got, MipsGPOffset);
>>> +        addOptionalSynthetic<ELFT>("_gp_disp", Out<ELFT>::Got,
>>> MipsGPOffset);
>>>      if (Sym)
>>>        ElfSym<ELFT>::MipsGpDisp = Sym->body();
>>>
>>> @@ -595,7 +594,7 @@ template <class ELFT> void Writer<ELFT>:
>>>      // pointer. This symbol is used in the code generated by .cpload
>>> pseudo-op
>>>      // in case of using -mno-shared option.
>>>      // https://sourceware.org/ml/binutils/2004-12/msg00094.html
>>> -    addOptionalSynthetic("__gnu_local_gp", Out<ELFT>::Got,
>>> MipsGPOffset);
>>> +    addOptionalSynthetic<ELFT>("__gnu_local_gp", Out<ELFT>::Got,
>>> MipsGPOffset);
>>>    }
>>>
>>>    // In the assembly for 32 bit x86 the _GLOBAL_OFFSET_TABLE_ symbol
>>> @@ -649,13 +648,13 @@ 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<ELFT>
>>> *S) {
>>> +template <class ELFT> static void sortInitFini(OutputSectionBase *S) {
>>>    if (S)
>>>      reinterpret_cast<OutputSection<ELFT> *>(S)->sortInitFini();
>>>  }
>>>
>>>  // Sort input sections by the special rule for .ctors and .dtors.
>>> -template <class ELFT> static void sortCtorsDtors(OutputSectionBase<ELFT>
>>> *S) {
>>> +template <class ELFT> static void sortCtorsDtors(OutputSectionBase *S)
>>> {
>>>    if (S)
>>>      reinterpret_cast<OutputSection<ELFT> *>(S)->sortCtorsDtors();
>>>  }
>>> @@ -691,7 +690,7 @@ void Writer<ELFT>::addInputSec(InputSect
>>>      reportDiscarded(IS);
>>>      return;
>>>    }
>>> -  OutputSectionBase<ELFT> *Sec;
>>> +  OutputSectionBase *Sec;
>>>    bool IsNew;
>>>    StringRef OutsecName = getOutputSectionName(IS->Name);
>>>    std::tie(Sec, IsNew) = Factory.create(IS, OutsecName);
>>> @@ -704,18 +703,18 @@ template <class ELFT> void Writer<ELFT>:
>>>    for (InputSectionBase<ELFT> *IS : Symtab<ELFT>::X->Sections)
>>>      addInputSec(IS);
>>>
>>> -  sortInitFini(findSection(".init_array"));
>>> -  sortInitFini(findSection(".fini_array"));
>>> -  sortCtorsDtors(findSection(".ctors"));
>>> -  sortCtorsDtors(findSection(".dtors"));
>>> +  sortInitFini<ELFT>(findSection(".init_array"));
>>> +  sortInitFini<ELFT>(findSection(".fini_array"));
>>> +  sortCtorsDtors<ELFT>(findSection(".ctors"));
>>> +  sortCtorsDtors<ELFT>(findSection(".dtors"));
>>>
>>> -  for (OutputSectionBase<ELFT> *Sec : OutputSections)
>>> +  for (OutputSectionBase *Sec : OutputSections)
>>>      Sec->assignOffsets();
>>>  }
>>>
>>>  template <class ELFT>
>>> -static bool canSharePtLoad(const OutputSectionBase<ELFT> &S1,
>>> -                           const OutputSectionBase<ELFT> &S2) {
>>> +static bool canSharePtLoad(const OutputSectionBase &S1,
>>> +                           const OutputSectionBase &S2) {
>>>    if (!(S1.Flags & SHF_ALLOC) || !(S2.Flags & SHF_ALLOC))
>>>      return false;
>>>
>>> @@ -767,15 +766,14 @@ template <class ELFT> void Writer<ELFT>:
>>>    auto I = OutputSections.begin();
>>>    auto E = OutputSections.end();
>>>    auto NonScriptI =
>>> -      std::find_if(OutputSections.begin(), E,
>>> [](OutputSectionBase<ELFT> *S) {
>>> +      std::find_if(OutputSections.begin(), E, [](OutputSectionBase *S)
>>> {
>>>          return Script<ELFT>::X->getSectionIndex(S->getName()) ==
>>> INT_MAX;
>>>        });
>>>    while (NonScriptI != E) {
>>> -    auto BestPos =
>>> -        std::max_element(I, NonScriptI, [&](OutputSectionBase<ELFT> *&A,
>>> -                                            OutputSectionBase<ELFT>
>>> *&B) {
>>> -          bool ACanSharePtLoad = canSharePtLoad(**NonScriptI, *A);
>>> -          bool BCanSharePtLoad = canSharePtLoad(**NonScriptI, *B);
>>> +    auto BestPos = std::max_element(
>>> +        I, NonScriptI, [&](OutputSectionBase *&A, OutputSectionBase
>>> *&B) {
>>> +          bool ACanSharePtLoad = canSharePtLoad<ELFT>(**NonScriptI,
>>> *A);
>>> +          bool BCanSharePtLoad = canSharePtLoad<ELFT>(**NonScriptI,
>>> *B);
>>>            if (ACanSharePtLoad != BCanSharePtLoad)
>>>              return BCanSharePtLoad;
>>>
>>> @@ -812,7 +810,7 @@ template <class ELFT> void Writer<ELFT>:
>>>    // addresses of each section by section name. Add such symbols.
>>>    if (!Config->Relocatable) {
>>>      addStartEndSymbols();
>>> -    for (OutputSectionBase<ELFT> *Sec : OutputSections)
>>> +    for (OutputSectionBase *Sec : OutputSections)
>>>        addStartStopSymbols(Sec);
>>>    }
>>>
>>> @@ -865,7 +863,7 @@ template <class ELFT> void Writer<ELFT>:
>>>    sortSections();
>>>
>>>    unsigned I = 1;
>>> -  for (OutputSectionBase<ELFT> *Sec : OutputSections) {
>>> +  for (OutputSectionBase *Sec : OutputSections) {
>>>      Sec->SectionIndex = I++;
>>>      Sec->ShName = Out<ELFT>::ShStrTab->addString(Sec->getName());
>>>    }
>>> @@ -878,7 +876,7 @@ 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<ELFT> *Sec : OutputSections)
>>> +  for (OutputSectionBase *Sec : OutputSections)
>>>      if (Sec != Out<ELFT>::Dynamic)
>>>        Sec->finalize();
>>>
>>> @@ -887,7 +885,7 @@ template <class ELFT> void Writer<ELFT>:
>>>
>>>    // Now that all output offsets are fixed. Finalize mergeable sections
>>>    // to fix their maps from input offsets to output offsets.
>>> -  for (OutputSectionBase<ELFT> *Sec : OutputSections)
>>> +  for (OutputSectionBase *Sec : OutputSections)
>>>      Sec->finalizePieces();
>>>  }
>>>
>>> @@ -907,7 +905,7 @@ template <class ELFT> bool Writer<ELFT>:
>>>
>>>  // This function add Out<ELFT>::* sections to OutputSections.
>>>  template <class ELFT> void Writer<ELFT>::addPredefinedSections() {
>>> -  auto Add = [&](OutputSectionBase<ELFT> *OS) {
>>> +  auto Add = [&](OutputSectionBase *OS) {
>>>      if (OS)
>>>        OutputSections.push_back(OS);
>>>    };
>>> @@ -958,11 +956,11 @@ 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<ELFT> *OS) {
>>> +  auto Define = [&](StringRef Start, StringRef End, OutputSectionBase
>>> *OS) {
>>>      // These symbols resolve to the image base if the section does not
>>> exist.
>>> -    addOptionalSynthetic(Start, OS, 0);
>>> -    addOptionalSynthetic(End, OS, OS ? DefinedSynthetic<ELFT>::SectionEnd
>>> : 0);
>>> +    addOptionalSynthetic<ELFT>(Start, OS, 0);
>>> +    addOptionalSynthetic<ELFT>(End, OS,
>>> +                               OS ? DefinedSynthetic<ELFT>::SectionEnd
>>> : 0);
>>>    };
>>>
>>>    Define("__preinit_array_start", "__preinit_array_end",
>>> @@ -970,7 +968,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<ELFT> *Sec = findSection(".ARM.exidx"))
>>> +  if (OutputSectionBase *Sec = findSection(".ARM.exidx"))
>>>      Define("__exidx_start", "__exidx_end", Sec);
>>>  }
>>>
>>> @@ -980,24 +978,24 @@ 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<ELFT> *Sec) {
>>> +void Writer<ELFT>::addStartStopSymbols(OutputSectionBase *Sec) {
>>>    StringRef S = Sec->getName();
>>>    if (!isValidCIdentifier(S))
>>>      return;
>>> -  addOptionalSynthetic(Saver.save("__start_" + S), Sec, 0,
>>> STV_DEFAULT);
>>> -  addOptionalSynthetic(Saver.save("__stop_" + S), Sec,
>>> -                       DefinedSynthetic<ELFT>::SectionEnd,
>>> STV_DEFAULT);
>>> +  addOptionalSynthetic<ELFT>(Saver.save("__start_" + S), Sec, 0,
>>> STV_DEFAULT);
>>> +  addOptionalSynthetic<ELFT>(Saver.save("__stop_" + S), Sec,
>>> +                             DefinedSynthetic<ELFT>::SectionEnd,
>>> STV_DEFAULT);
>>>  }
>>>
>>>  template <class ELFT>
>>> -OutputSectionBase<ELFT> *Writer<ELFT>::findSection(StringRef Name) {
>>> -  for (OutputSectionBase<ELFT> *Sec : OutputSections)
>>> +OutputSectionBase *Writer<ELFT>::findSection(StringRef Name) {
>>> +  for (OutputSectionBase *Sec : OutputSections)
>>>      if (Sec->getName() == Name)
>>>        return Sec;
>>>    return nullptr;
>>>  }
>>>
>>> -template <class ELFT> static bool needsPtLoad(OutputSectionBase<ELFT>
>>> *Sec) {
>>> +template <class ELFT> static bool needsPtLoad(OutputSectionBase *Sec) {
>>>    if (!(Sec->Flags & SHF_ALLOC))
>>>      return false;
>>>
>>> @@ -1034,7 +1032,7 @@ template <class ELFT> std::vector<PhdrEn
>>>    Hdr.add(Out<ELFT>::ProgramHeaders);
>>>
>>>    // PT_INTERP must be the second entry if exists.
>>> -  if (OutputSectionBase<ELFT> *Sec = findSection(".interp")) {
>>> +  if (OutputSectionBase *Sec = findSection(".interp")) {
>>>      Phdr &Hdr = *AddHdr(PT_INTERP, Sec->getPhdrFlags());
>>>      Hdr.add(Sec);
>>>    }
>>> @@ -1051,7 +1049,7 @@ template <class ELFT> std::vector<PhdrEn
>>>    Phdr RelRo(PT_GNU_RELRO, PF_R);
>>>    Phdr Note(PT_NOTE, PF_R);
>>>    Phdr ARMExidx(PT_ARM_EXIDX, PF_R);
>>> -  for (OutputSectionBase<ELFT> *Sec : OutputSections) {
>>> +  for (OutputSectionBase *Sec : OutputSections) {
>>>      if (!(Sec->Flags & SHF_ALLOC))
>>>        break;
>>>
>>> @@ -1061,7 +1059,7 @@ template <class ELFT> std::vector<PhdrEn
>>>      if (Sec->Flags & SHF_TLS)
>>>        TlsHdr.add(Sec);
>>>
>>> -    if (!needsPtLoad(Sec))
>>> +    if (!needsPtLoad<ELFT>(Sec))
>>>        continue;
>>>
>>>      // Segments are contiguous memory regions that has the same
>>> attributes
>>> @@ -1077,7 +1075,7 @@ template <class ELFT> std::vector<PhdrEn
>>>
>>>      Load->add(Sec);
>>>
>>> -    if (isRelroSection(Sec))
>>> +    if (isRelroSection<ELFT>(Sec))
>>>        RelRo.add(Sec);
>>>      if (Sec->Type == SHT_NOTE)
>>>        Note.add(Sec);
>>> @@ -1109,7 +1107,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<ELFT> *Sec = findSection(".openbsd.randomdata"))
>>> {
>>> +  if (OutputSectionBase *Sec = findSection(".openbsd.randomdata")) {
>>>      Phdr &Hdr = *AddHdr(PT_OPENBSD_RANDOMIZE, Sec->getPhdrFlags());
>>>      Hdr.add(Sec);
>>>    }
>>> @@ -1154,8 +1152,8 @@ template <class ELFT> void Writer<ELFT>:
>>>      auto I = std::find(OutputSections.begin(), End, P.Last);
>>>      if (I == End || (I + 1) == End)
>>>        continue;
>>> -    OutputSectionBase<ELFT> *Sec = *(I + 1);
>>> -    if (needsPtLoad(Sec))
>>> +    OutputSectionBase *Sec = *(I + 1);
>>> +    if (needsPtLoad<ELFT>(Sec))
>>>        Sec->PageAlign = true;
>>>    }
>>>  }
>>> @@ -1175,7 +1173,7 @@ template <class ELFT> void Writer<ELFT>:
>>>  template <class ELFT> void Writer<ELFT>::assignAddresses() {
>>>    uintX_t VA = Config->ImageBase + getHeaderSize<ELFT>();
>>>    uintX_t ThreadBssOffset = 0;
>>> -  for (OutputSectionBase<ELFT> *Sec : OutputSections) {
>>> +  for (OutputSectionBase *Sec : OutputSections) {
>>>      uintX_t Alignment = Sec->Addralign;
>>>      if (Sec->PageAlign)
>>>        Alignment = std::max<uintX_t>(Alignment, Config->MaxPageSize);
>>> @@ -1185,7 +1183,7 @@ template <class ELFT> void Writer<ELFT>:
>>>        VA = I->second;
>>>
>>>      // We only assign VAs to allocated sections.
>>> -    if (needsPtLoad(Sec)) {
>>> +    if (needsPtLoad<ELFT>(Sec)) {
>>>        VA = alignTo(VA, Alignment);
>>>        Sec->Addr = VA;
>>>        VA += Sec->Size;
>>> @@ -1203,13 +1201,13 @@ 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<ELFT>
>>> *Sec) {
>>> +static uintX_t getFileAlignment(uintX_t Off, OutputSectionBase *Sec) {
>>>    uintX_t Alignment = Sec->Addralign;
>>>    if (Sec->PageAlign)
>>>      Alignment = std::max<uintX_t>(Alignment, Config->MaxPageSize);
>>>    Off = alignTo(Off, Alignment);
>>>
>>> -  OutputSectionBase<ELFT> *First = Sec->FirstInPtLoad;
>>> +  OutputSectionBase *First = Sec->FirstInPtLoad;
>>>    // If the section is not in a PT_LOAD, we have no other constraint.
>>>    if (!First)
>>>      return Off;
>>> @@ -1222,7 +1220,7 @@ static uintX_t getFileAlignment(uintX_t
>>>  }
>>>
>>>  template <class ELFT, class uintX_t>
>>> -void setOffset(OutputSectionBase<ELFT> *Sec, uintX_t &Off) {
>>> +void setOffset(OutputSectionBase *Sec, uintX_t &Off) {
>>>    if (Sec->Type == SHT_NOBITS) {
>>>      Sec->Offset = Off;
>>>      return;
>>> @@ -1235,20 +1233,20 @@ void setOffset(OutputSectionBase<ELFT> *
>>>
>>>  template <class ELFT> void Writer<ELFT>::assignFileOffsetsBinary() {
>>>    uintX_t Off = 0;
>>> -  for (OutputSectionBase<ELFT> *Sec : OutputSections)
>>> +  for (OutputSectionBase *Sec : OutputSections)
>>>      if (Sec->Flags & SHF_ALLOC)
>>> -      setOffset(Sec, Off);
>>> +      setOffset<ELFT>(Sec, Off);
>>>    FileSize = alignTo(Off, sizeof(uintX_t));
>>>  }
>>>
>>>  // Assign file offsets to output sections.
>>>  template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
>>>    uintX_t Off = 0;
>>> -  setOffset(Out<ELFT>::ElfHeader, Off);
>>> -  setOffset(Out<ELFT>::ProgramHeaders, Off);
>>> +  setOffset<ELFT>(Out<ELFT>::ElfHeader, Off);
>>> +  setOffset<ELFT>(Out<ELFT>::ProgramHeaders, Off);
>>>
>>> -  for (OutputSectionBase<ELFT> *Sec : OutputSections)
>>> -    setOffset(Sec, Off);
>>> +  for (OutputSectionBase *Sec : OutputSections)
>>> +    setOffset<ELFT>(Sec, Off);
>>>
>>>    SectionHeaderOff = alignTo(Off, sizeof(uintX_t));
>>>    FileSize = SectionHeaderOff + (OutputSections.size() + 1) *
>>> sizeof(Elf_Shdr);
>>> @@ -1259,8 +1257,8 @@ template <class ELFT> void Writer<ELFT>:
>>>  template <class ELFT> void Writer<ELFT>::setPhdrs() {
>>>    for (Phdr &P : Phdrs) {
>>>      Elf_Phdr &H = P.H;
>>> -    OutputSectionBase<ELFT> *First = P.First;
>>> -    OutputSectionBase<ELFT> *Last = P.Last;
>>> +    OutputSectionBase *First = P.First;
>>> +    OutputSectionBase *Last = P.Last;
>>>      if (First) {
>>>        H.p_filesz = Last->Offset - First->Offset;
>>>        if (Last->Type != SHT_NOBITS)
>>> @@ -1382,8 +1380,8 @@ 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<ELFT> *Sec : OutputSections)
>>> -    Sec->writeHeaderTo(++SHdrs);
>>> +  for (OutputSectionBase *Sec : OutputSections)
>>> +    Sec->writeHeaderTo<ELFT>(++SHdrs);
>>>  }
>>>
>>>  template <class ELFT> void Writer<ELFT>::openFile() {
>>> @@ -1398,7 +1396,7 @@ template <class ELFT> void Writer<ELFT>:
>>>
>>>  template <class ELFT> void Writer<ELFT>::writeSectionsBinary() {
>>>    uint8_t *Buf = Buffer->getBufferStart();
>>> -  for (OutputSectionBase<ELFT> *Sec : OutputSections)
>>> +  for (OutputSectionBase *Sec : OutputSections)
>>>      if (Sec->Flags & SHF_ALLOC)
>>>        Sec->writeTo(Buf + Sec->Offset);
>>>  }
>>> @@ -1477,11 +1475,11 @@ template <class ELFT> void Writer<ELFT>:
>>>      Out<ELFT>::Opd->writeTo(Buf + Out<ELFT>::Opd->Offset);
>>>    }
>>>
>>> -  for (OutputSectionBase<ELFT> *Sec : OutputSections)
>>> +  for (OutputSectionBase *Sec : OutputSections)
>>>      if (Sec != Out<ELFT>::Opd && Sec != Out<ELFT>::EhFrameHdr)
>>>        Sec->writeTo(Buf + Sec->Offset);
>>>
>>> -  OutputSectionBase<ELFT> *ARMExidx = findSection(".ARM.exidx");
>>> +  OutputSectionBase *ARMExidx = findSection(".ARM.exidx");
>>>    if (!Config->Relocatable)
>>>      if (auto *OS = dyn_cast_or_null<OutputSection<ELFT>>(ARMExidx))
>>>        sortARMExidx(Buf + OS->Offset, OS->Addr, OS->Size);
>>> @@ -1512,10 +1510,10 @@ template struct elf::PhdrEntry<ELF32BE>;
>>>  template struct elf::PhdrEntry<ELF64LE>;
>>>  template struct elf::PhdrEntry<ELF64BE>;
>>>
>>> -template bool elf::isRelroSection<ELF32LE>(const
>>> OutputSectionBase<ELF32LE> *);
>>> -template bool elf::isRelroSection<ELF32BE>(const
>>> OutputSectionBase<ELF32BE> *);
>>> -template bool elf::isRelroSection<ELF64LE>(const
>>> OutputSectionBase<ELF64LE> *);
>>> -template bool elf::isRelroSection<ELF64BE>(const
>>> OutputSectionBase<ELF64BE> *);
>>> +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 void elf::reportDiscarded<ELF32LE>(InputSectionBase<ELF32LE>
>>> *);
>>>  template void elf::reportDiscarded<ELF32BE>(InputSectionBase<ELF32BE>
>>> *);
>>>
>>> Modified: lld/trunk/ELF/Writer.h
>>> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.h?r
>>> ev=286414&r1=286413&r2=286414&view=diff
>>> ============================================================
>>> ==================
>>> --- lld/trunk/ELF/Writer.h (original)
>>> +++ lld/trunk/ELF/Writer.h Wed Nov  9 17:23:45 2016
>>> @@ -17,24 +17,24 @@
>>>  namespace lld {
>>>  namespace elf {
>>>  class InputFile;
>>> -template <class ELFT> class OutputSectionBase;
>>> +class OutputSectionBase;
>>>  template <class ELFT> 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<ELFT>
>>> *Sec);
>>> +template <class ELFT> bool isRelroSection(const OutputSectionBase *Sec);
>>>
>>>  // This describes a program header entry.
>>>  // Each contains type, access flags and range of output sections that
>>> will be
>>>  // placed in it.
>>>  template <class ELFT> struct PhdrEntry {
>>>    PhdrEntry(unsigned Type, unsigned Flags);
>>> -  void add(OutputSectionBase<ELFT> *Sec);
>>> +  void add(OutputSectionBase *Sec);
>>>
>>>    typename ELFT::Phdr H = {};
>>> -  OutputSectionBase<ELFT> *First = nullptr;
>>> -  OutputSectionBase<ELFT> *Last = nullptr;
>>> +  OutputSectionBase *First = nullptr;
>>> +  OutputSectionBase *Last = nullptr;
>>>    bool HasLMA = false;
>>>  };
>>>
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>>
>>
>>
>> _______________________________________________
>> 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/20161112/d091882e/attachment-0001.html>


More information about the llvm-commits mailing list