[lld] r357806 - ELF: De-template ELFFileBase. NFCI.

Peter Collingbourne via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 5 13:16:26 PDT 2019


Author: pcc
Date: Fri Apr  5 13:16:26 2019
New Revision: 357806

URL: http://llvm.org/viewvc/llvm-project?rev=357806&view=rev
Log:
ELF: De-template ELFFileBase. NFCI.

Differential Revision: https://reviews.llvm.org/D60304

Modified:
    lld/trunk/ELF/Arch/Mips.cpp
    lld/trunk/ELF/Arch/MipsArchTree.cpp
    lld/trunk/ELF/DWARF.cpp
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/InputFiles.h
    lld/trunk/ELF/Relocations.cpp

Modified: lld/trunk/ELF/Arch/Mips.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/Mips.cpp?rev=357806&r1=357805&r2=357806&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/Mips.cpp (original)
+++ lld/trunk/ELF/Arch/Mips.cpp Fri Apr  5 13:16:26 2019
@@ -350,7 +350,7 @@ bool MIPS<ELFT>::needsThunk(RelExpr Expr
   if (Type != R_MIPS_26 && Type != R_MIPS_PC26_S2 &&
       Type != R_MICROMIPS_26_S1 && Type != R_MICROMIPS_PC26_S1)
     return false;
-  auto *F = dyn_cast_or_null<ELFFileBase<ELFT>>(File);
+  auto *F = dyn_cast_or_null<ObjFile<ELFT>>(File);
   if (!F)
     return false;
   // If current file has PIC code, LA25 stub is not required.

Modified: lld/trunk/ELF/Arch/MipsArchTree.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/MipsArchTree.cpp?rev=357806&r1=357805&r2=357806&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/MipsArchTree.cpp (original)
+++ lld/trunk/ELF/Arch/MipsArchTree.cpp Fri Apr  5 13:16:26 2019
@@ -356,8 +356,8 @@ uint8_t elf::getMipsFpAbiFlag(uint8_t Ol
 }
 
 template <class ELFT> static bool isN32Abi(const InputFile *F) {
-  if (auto *EF = dyn_cast<ELFFileBase<ELFT>>(F))
-    return EF->getObj().getHeader()->e_flags & EF_MIPS_ABI2;
+  if (auto *EF = dyn_cast<ELFFileBase>(F))
+    return EF->template getObj<ELFT>().getHeader()->e_flags & EF_MIPS_ABI2;
   return false;
 }
 

Modified: lld/trunk/ELF/DWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/DWARF.cpp?rev=357806&r1=357805&r2=357806&view=diff
==============================================================================
--- lld/trunk/ELF/DWARF.cpp (original)
+++ lld/trunk/ELF/DWARF.cpp Fri Apr  5 13:16:26 2019
@@ -90,7 +90,7 @@ LLDDwarfObj<ELFT>::findAux(const InputSe
 
   const ObjFile<ELFT> *File = Sec.getFile<ELFT>();
   uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
-  const typename ELFT::Sym &Sym = File->getELFSyms()[SymIndex];
+  const typename ELFT::Sym &Sym = File->template getELFSyms<ELFT>()[SymIndex];
   uint32_t SecIndex = File->getSectionIndex(Sym);
 
   // Broken debug info can point to a non-Defined symbol.

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=357806&r1=357805&r2=357806&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Fri Apr  5 13:16:26 2019
@@ -241,45 +241,46 @@ std::string lld::toString(const InputFil
   return F->ToStringCache;
 }
 
-template <class ELFT>
-ELFFileBase<ELFT>::ELFFileBase(Kind K, MemoryBufferRef MB) : InputFile(K, MB) {
+ELFFileBase::ELFFileBase(Kind K, MemoryBufferRef MB) : InputFile(K, MB) {}
+
+template <class ELFT> void ELFFileBase::parseHeader() {
   if (ELFT::TargetEndianness == support::little)
     EKind = ELFT::Is64Bits ? ELF64LEKind : ELF32LEKind;
   else
     EKind = ELFT::Is64Bits ? ELF64BEKind : ELF32BEKind;
 
-  EMachine = getObj().getHeader()->e_machine;
-  OSABI = getObj().getHeader()->e_ident[llvm::ELF::EI_OSABI];
-  ABIVersion = getObj().getHeader()->e_ident[llvm::ELF::EI_ABIVERSION];
+  EMachine = getObj<ELFT>().getHeader()->e_machine;
+  OSABI = getObj<ELFT>().getHeader()->e_ident[llvm::ELF::EI_OSABI];
+  ABIVersion = getObj<ELFT>().getHeader()->e_ident[llvm::ELF::EI_ABIVERSION];
 }
 
 template <class ELFT>
-typename ELFT::SymRange ELFFileBase<ELFT>::getGlobalELFSyms() {
-  return makeArrayRef(ELFSyms.begin() + FirstGlobal, ELFSyms.end());
-}
-
-template <class ELFT>
-void ELFFileBase<ELFT>::initSymtab(ArrayRef<Elf_Shdr> Sections,
-                                   const Elf_Shdr *Symtab) {
+void ELFFileBase::initSymtab(ArrayRef<typename ELFT::Shdr> Sections,
+                             const typename ELFT::Shdr *Symtab) {
   FirstGlobal = Symtab->sh_info;
-  ELFSyms = CHECK(getObj().symbols(Symtab), this);
+  ArrayRef<typename ELFT::Sym> ELFSyms =
+      CHECK(getObj<ELFT>().symbols(Symtab), this);
   if (FirstGlobal == 0 || FirstGlobal > ELFSyms.size())
     fatal(toString(this) + ": invalid sh_info in symbol table");
+  this->ELFSyms = reinterpret_cast<const void *>(ELFSyms.data());
+  this->NumELFSyms = ELFSyms.size();
 
   StringTable =
-      CHECK(getObj().getStringTableForSymtab(*Symtab, Sections), this);
+      CHECK(getObj<ELFT>().getStringTableForSymtab(*Symtab, Sections), this);
 }
 
 template <class ELFT>
 ObjFile<ELFT>::ObjFile(MemoryBufferRef M, StringRef ArchiveName)
-    : ELFFileBase<ELFT>(Base::ObjKind, M) {
+    : ELFFileBase(ObjKind, M) {
+  parseHeader<ELFT>();
   this->ArchiveName = ArchiveName;
 }
 
 template <class ELFT>
 uint32_t ObjFile<ELFT>::getSectionIndex(const Elf_Sym &Sym) const {
-  return CHECK(this->getObj().getSectionIndex(&Sym, this->ELFSyms, SymtabSHNDX),
-               this);
+  return CHECK(
+      this->getObj().getSectionIndex(&Sym, getELFSyms<ELFT>(), SymtabSHNDX),
+      this);
 }
 
 template <class ELFT> ArrayRef<Symbol *> ObjFile<ELFT>::getLocalSymbols() {
@@ -312,12 +313,12 @@ StringRef ObjFile<ELFT>::getShtGroupSign
                                               const Elf_Shdr &Sec) {
   // Group signatures are stored as symbol names in object files.
   // sh_info contains a symbol index, so we fetch a symbol and read its name.
-  if (this->ELFSyms.empty())
-    this->initSymtab(
+  if (this->getELFSyms<ELFT>().empty())
+    this->initSymtab<ELFT>(
         Sections, CHECK(object::getSection<ELFT>(Sections, Sec.sh_link), this));
 
   const Elf_Sym *Sym =
-      CHECK(object::getSymbol<ELFT>(this->ELFSyms, Sec.sh_info), this);
+      CHECK(object::getSymbol<ELFT>(this->getELFSyms<ELFT>(), Sec.sh_info), this);
   StringRef Signature = CHECK(Sym->getName(this->StringTable), this);
 
   // As a special case, if a symbol is a section symbol and has no name,
@@ -392,7 +393,7 @@ template <class ELFT> void ObjFile<ELFT>
   for (const Elf_Shdr &Sec : ObjSections) {
     if (Sec.sh_type != SHT_SYMTAB)
       continue;
-    this->initSymtab(ObjSections, &Sec);
+    this->initSymtab<ELFT>(ObjSections, &Sec);
     return;
   }
 }
@@ -475,10 +476,10 @@ void ObjFile<ELFT>::initializeSections(
       break;
     }
     case SHT_SYMTAB:
-      this->initSymtab(ObjSections, &Sec);
+      this->initSymtab<ELFT>(ObjSections, &Sec);
       break;
     case SHT_SYMTAB_SHNDX:
-      this->SymtabSHNDX = CHECK(Obj.getSHNDXTable(Sec, ObjSections), this);
+      SymtabSHNDX = CHECK(Obj.getSHNDXTable(Sec, ObjSections), this);
       break;
     case SHT_STRTAB:
     case SHT_NULL:
@@ -678,12 +679,12 @@ InputSectionBase *ObjFile<ELFT>::createI
     }
 
     if (Sec.sh_type == SHT_RELA) {
-      ArrayRef<Elf_Rela> Rels = CHECK(this->getObj().relas(&Sec), this);
+      ArrayRef<Elf_Rela> Rels = CHECK(getObj().relas(&Sec), this);
       Target->FirstRelocation = Rels.begin();
       Target->NumRelocations = Rels.size();
       Target->AreRelocsRela = true;
     } else {
-      ArrayRef<Elf_Rel> Rels = CHECK(this->getObj().rels(&Sec), this);
+      ArrayRef<Elf_Rel> Rels = CHECK(getObj().rels(&Sec), this);
       Target->FirstRelocation = Rels.begin();
       Target->NumRelocations = Rels.size();
       Target->AreRelocsRela = false;
@@ -771,19 +772,19 @@ InputSectionBase *ObjFile<ELFT>::createI
 
 template <class ELFT>
 StringRef ObjFile<ELFT>::getSectionName(const Elf_Shdr &Sec) {
-  return CHECK(this->getObj().getSectionName(&Sec, SectionStringTable), this);
+  return CHECK(getObj().getSectionName(&Sec, SectionStringTable), this);
 }
 
 template <class ELFT> void ObjFile<ELFT>::initializeSymbols() {
-  this->Symbols.reserve(this->ELFSyms.size());
-  for (const Elf_Sym &Sym : this->ELFSyms)
+  this->Symbols.reserve(this->getELFSyms<ELFT>().size());
+  for (const Elf_Sym &Sym : this->getELFSyms<ELFT>())
     this->Symbols.push_back(createSymbol(&Sym));
 }
 
 template <class ELFT> Symbol *ObjFile<ELFT>::createSymbol(const Elf_Sym *Sym) {
   int Binding = Sym->getBinding();
 
-  uint32_t SecIdx = this->getSectionIndex(*Sym);
+  uint32_t SecIdx = getSectionIndex(*Sym);
   if (SecIdx >= this->Sections.size())
     fatal(toString(this) + ": invalid section index: " + Twine(SecIdx));
 
@@ -870,14 +871,16 @@ InputFile *ArchiveFile::fetch(const Arch
 
 template <class ELFT>
 SharedFile<ELFT>::SharedFile(MemoryBufferRef M, StringRef DefaultSoName)
-    : ELFFileBase<ELFT>(Base::SharedKind, M), SoName(DefaultSoName),
-      IsNeeded(!Config->AsNeeded) {}
+    : ELFFileBase(SharedKind, M), SoName(DefaultSoName),
+      IsNeeded(!Config->AsNeeded) {
+  parseHeader<ELFT>();
+}
 
 // Partially parse the shared object file so that we can call
 // getSoName on this object.
 template <class ELFT> void SharedFile<ELFT>::parseDynamic() {
   ArrayRef<Elf_Dyn> DynamicTags;
-  const ELFFile<ELFT> Obj = this->getObj();
+  const ELFFile<ELFT> Obj = this->getObj<ELFT>();
   ArrayRef<Elf_Shdr> Sections = CHECK(Obj.sections(), this);
 
   // Search for .dynsym, .dynamic, .symtab, .gnu.version and .gnu.version_d.
@@ -886,7 +889,7 @@ template <class ELFT> void SharedFile<EL
     default:
       continue;
     case SHT_DYNSYM:
-      this->initSymtab(Sections, &Sec);
+      this->initSymtab<ELFT>(Sections, &Sec);
       break;
     case SHT_DYNAMIC:
       DynamicTags =
@@ -901,7 +904,7 @@ template <class ELFT> void SharedFile<EL
     }
   }
 
-  if (this->VersymSec && this->ELFSyms.empty())
+  if (this->VersymSec && this->getELFSyms<ELFT>().empty())
     error("SHT_GNU_versym should be associated with symbol table");
 
   // Search for a DT_SONAME tag to initialize this->SoName.
@@ -923,7 +926,7 @@ template <class ELFT> void SharedFile<EL
 // Parses ".gnu.version" section which is a parallel array for the symbol table.
 // If a given file doesn't have ".gnu.version" section, returns VER_NDX_GLOBAL.
 template <class ELFT> std::vector<uint32_t> SharedFile<ELFT>::parseVersyms() {
-  size_t Size = this->ELFSyms.size() - this->FirstGlobal;
+  size_t Size = this->getELFSyms<ELFT>().size() - this->FirstGlobal;
   if (!VersymSec)
     return std::vector<uint32_t>(Size, VER_NDX_GLOBAL);
 
@@ -1001,7 +1004,7 @@ uint32_t SharedFile<ELFT>::getAlignment(
 template <class ELFT> void SharedFile<ELFT>::parseRest() {
   Verdefs = parseVerdefs();                       // parse .gnu.version_d
   std::vector<uint32_t> Versyms = parseVersyms(); // parse .gnu.version
-  ArrayRef<Elf_Shdr> Sections = CHECK(this->getObj().sections(), this);
+  ArrayRef<Elf_Shdr> Sections = CHECK(this->getObj<ELFT>().sections(), this);
 
   // System libraries can have a lot of symbols with versions. Using a
   // fixed buffer for computing the versions name (foo at ver) can save a
@@ -1009,7 +1012,7 @@ template <class ELFT> void SharedFile<EL
   SmallString<0> VersionedNameBuffer;
 
   // Add symbols to the symbol table.
-  ArrayRef<Elf_Sym> Syms = this->getGlobalELFSyms();
+  ArrayRef<Elf_Sym> Syms = this->getGlobalELFSyms<ELFT>();
   for (size_t I = 0; I < Syms.size(); ++I) {
     const Elf_Sym &Sym = Syms[I];
 
@@ -1347,11 +1350,6 @@ template void LazyObjFile::parse<ELF32BE
 template void LazyObjFile::parse<ELF64LE>();
 template void LazyObjFile::parse<ELF64BE>();
 
-template class elf::ELFFileBase<ELF32LE>;
-template class elf::ELFFileBase<ELF32BE>;
-template class elf::ELFFileBase<ELF64LE>;
-template class elf::ELFFileBase<ELF64BE>;
-
 template class elf::ObjFile<ELF32LE>;
 template class elf::ObjFile<ELF32BE>;
 template class elf::ObjFile<ELF64LE>;

Modified: lld/trunk/ELF/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=357806&r1=357805&r2=357806&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.h (original)
+++ lld/trunk/ELF/InputFiles.h Fri Apr  5 13:16:26 2019
@@ -145,35 +145,38 @@ private:
   const Kind FileKind;
 };
 
-template <typename ELFT> class ELFFileBase : public InputFile {
+class ELFFileBase : public InputFile {
 public:
-  using Elf_Shdr = typename ELFT::Shdr;
-  using Elf_Sym = typename ELFT::Sym;
-  using Elf_Word = typename ELFT::Word;
-  using Elf_Sym_Range = typename ELFT::SymRange;
-
   ELFFileBase(Kind K, MemoryBufferRef M);
+  template <typename ELFT> void parseHeader();
   static bool classof(const InputFile *F) { return F->isElf(); }
 
-  llvm::object::ELFFile<ELFT> getObj() const {
+  template <typename ELFT> llvm::object::ELFFile<ELFT> getObj() const {
     return check(llvm::object::ELFFile<ELFT>::create(MB.getBuffer()));
   }
 
   StringRef getStringTable() const { return StringTable; }
 
-  Elf_Sym_Range getGlobalELFSyms();
-  Elf_Sym_Range getELFSyms() const { return ELFSyms; }
+  template <typename ELFT> typename ELFT::SymRange getELFSyms() const {
+    return typename ELFT::SymRange(
+        reinterpret_cast<const typename ELFT::Sym *>(ELFSyms), NumELFSyms);
+  }
+  template <typename ELFT> typename ELFT::SymRange getGlobalELFSyms() const {
+    return getELFSyms<ELFT>().slice(FirstGlobal);
+  }
 
 protected:
-  ArrayRef<Elf_Sym> ELFSyms;
+  const void *ELFSyms = nullptr;
+  size_t NumELFSyms = 0;
   uint32_t FirstGlobal = 0;
   StringRef StringTable;
-  void initSymtab(ArrayRef<Elf_Shdr> Sections, const Elf_Shdr *Symtab);
+  template <typename ELFT>
+  void initSymtab(ArrayRef<typename ELFT::Shdr> Sections,
+                  const typename ELFT::Shdr *Symtab);
 };
 
 // .o file.
-template <class ELFT> class ObjFile : public ELFFileBase<ELFT> {
-  using Base = ELFFileBase<ELFT>;
+template <class ELFT> class ObjFile : public ELFFileBase {
   using Elf_Rel = typename ELFT::Rel;
   using Elf_Rela = typename ELFT::Rela;
   using Elf_Sym = typename ELFT::Sym;
@@ -185,7 +188,11 @@ template <class ELFT> class ObjFile : pu
                                  const Elf_Shdr &Sec);
 
 public:
-  static bool classof(const InputFile *F) { return F->kind() == Base::ObjKind; }
+  static bool classof(const InputFile *F) { return F->kind() == ObjKind; }
+
+  llvm::object::ELFFile<ELFT> getObj() const {
+    return this->ELFFileBase::getObj<ELFT>();
+  }
 
   ArrayRef<Symbol *> getLocalSymbols();
   ArrayRef<Symbol *> getGlobalSymbols();
@@ -321,8 +328,7 @@ public:
 };
 
 // .so file.
-template <class ELFT> class SharedFile : public ELFFileBase<ELFT> {
-  using Base = ELFFileBase<ELFT>;
+template <class ELFT> class SharedFile : public ELFFileBase {
   using Elf_Dyn = typename ELFT::Dyn;
   using Elf_Shdr = typename ELFT::Shdr;
   using Elf_Sym = typename ELFT::Sym;
@@ -338,9 +344,7 @@ public:
   std::vector<StringRef> DtNeeded;
   std::string SoName;
 
-  static bool classof(const InputFile *F) {
-    return F->kind() == Base::SharedKind;
-  }
+  static bool classof(const InputFile *F) { return F->kind() == SharedKind; }
 
   SharedFile(MemoryBufferRef M, StringRef DefaultSoName);
 

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=357806&r1=357805&r2=357806&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Fri Apr  5 13:16:26 2019
@@ -483,7 +483,8 @@ template <class ELFT> static bool isRead
 
   // Determine if the symbol is read-only by scanning the DSO's program headers.
   const SharedFile<ELFT> &File = SS.getFile<ELFT>();
-  for (const Elf_Phdr &Phdr : check(File.getObj().program_headers()))
+  for (const Elf_Phdr &Phdr :
+       check(File.template getObj<ELFT>().program_headers()))
     if ((Phdr.p_type == ELF::PT_LOAD || Phdr.p_type == ELF::PT_GNU_RELRO) &&
         !(Phdr.p_flags & ELF::PF_W) && SS.Value >= Phdr.p_vaddr &&
         SS.Value < Phdr.p_vaddr + Phdr.p_memsz)
@@ -503,7 +504,7 @@ static SmallSet<SharedSymbol *, 4> getSy
   SharedFile<ELFT> &File = SS.getFile<ELFT>();
 
   SmallSet<SharedSymbol *, 4> Ret;
-  for (const Elf_Sym &S : File.getGlobalELFSyms()) {
+  for (const Elf_Sym &S : File.template getGlobalELFSyms<ELFT>()) {
     if (S.st_shndx == SHN_UNDEF || S.st_shndx == SHN_ABS ||
         S.getType() == STT_TLS || S.st_value != SS.Value)
       continue;




More information about the llvm-commits mailing list