[lld] r274089 - Refactor ELF type inference functions.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 28 18:30:50 PDT 2016


Author: ruiu
Date: Tue Jun 28 20:30:50 2016
New Revision: 274089

URL: http://llvm.org/viewvc/llvm-project?rev=274089&view=rev
Log:
Refactor ELF type inference functions.

Previously, we initialized Config->EKind and Config->EMachine when
we instantiate ELF objects. That was not an ideal location to do that
because the logic was buried too deep inside a concrete logic.

This patch moves the code to the driver so that the initialization
becomes explicit.

Differential Revision: http://reviews.llvm.org/D21784

Modified:
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/InputFiles.h
    lld/trunk/ELF/SymbolTable.cpp
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=274089&r1=274088&r2=274089&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Tue Jun 28 20:30:50 2016
@@ -313,9 +313,6 @@ void LinkerDriver::readConfigs(opt::Inpu
     Config->Emulation = S;
   }
 
-  if (Config->EMachine == EM_MIPS && Config->EKind == ELF64LEKind)
-    Config->Mips64EL = true;
-
   Config->AllowMultipleDefinition = Args.hasArg(OPT_allow_multiple_definition);
   Config->Bsymbolic = Args.hasArg(OPT_Bsymbolic);
   Config->BsymbolicFunctions = Args.hasArg(OPT_Bsymbolic_functions);
@@ -470,6 +467,17 @@ void LinkerDriver::createFiles(opt::Inpu
 
   if (Files.empty() && !HasError)
     error("no input files.");
+
+  // If -m <machine_type> was not given, infer it from object files.
+  if (Config->EKind == ELFNoneKind) {
+    for (std::unique_ptr<InputFile> &F : Files) {
+      if (F->EKind == ELFNoneKind)
+        continue;
+      Config->EKind = F->EKind;
+      Config->EMachine = F->EMachine;
+      break;
+    }
+  }
 }
 
 // Do actual linking. Note that when this function is called,
@@ -484,6 +492,8 @@ template <class ELFT> void LinkerDriver:
   Script<ELFT>::X = &LS;
 
   Config->Rela = ELFT::Is64Bits;
+  Config->Mips64EL =
+      (Config->EMachine == EM_MIPS && Config->EKind == ELF64LEKind);
 
   // Add entry symbol. Note that AMDGPU binaries have no entry points.
   if (Config->Entry.empty() && !Config->Shared && !Config->Relocatable &&

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=274089&r1=274088&r2=274089&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Tue Jun 28 20:30:50 2016
@@ -44,18 +44,20 @@ static ELFFile<ELFT> createELFObj(Memory
   return F;
 }
 
-template <class ELFT>
-ELFFileBase<ELFT>::ELFFileBase(Kind K, MemoryBufferRef MB)
-    : InputFile(K, MB), ELFObj(createELFObj<ELFT>(MB)) {}
-
-template <class ELFT>
-ELFKind ELFFileBase<ELFT>::getELFKind() {
+template <class ELFT> static ELFKind getELFKind() {
   if (ELFT::TargetEndianness == support::little)
     return ELFT::Is64Bits ? ELF64LEKind : ELF32LEKind;
   return ELFT::Is64Bits ? ELF64BEKind : ELF32BEKind;
 }
 
 template <class ELFT>
+ELFFileBase<ELFT>::ELFFileBase(Kind K, MemoryBufferRef MB)
+    : InputFile(K, MB), ELFObj(createELFObj<ELFT>(MB)) {
+  EKind = getELFKind<ELFT>();
+  EMachine = ELFObj.getHeader()->e_machine;
+}
+
+template <class ELFT>
 typename ELFT::SymRange ELFFileBase<ELFT>::getElfSymbols(bool OnlyGlobals) {
   if (!Symtab)
     return Elf_Sym_Range(nullptr, nullptr);
@@ -644,23 +646,6 @@ void BitcodeFile::parse(DenseSet<StringR
       Symbols.push_back(createSymbol<ELFT>(KeptComdats, *Obj, Sym));
 }
 
-template <typename T>
-static std::unique_ptr<InputFile> createELFFileAux(MemoryBufferRef MB) {
-  std::unique_ptr<T> Ret = llvm::make_unique<T>(MB);
-
-  if (!Config->FirstElf)
-    Config->FirstElf = Ret.get();
-
-  if (Config->EKind == ELFNoneKind) {
-    Config->EKind = Ret->getELFKind();
-    Config->EMachine = Ret->getEMachine();
-    if (Config->EMachine == EM_MIPS && Config->EKind == ELF64LEKind)
-      Config->Mips64EL = true;
-  }
-
-  return std::move(Ret);
-}
-
 template <template <class> class T>
 static std::unique_ptr<InputFile> createELFFile(MemoryBufferRef MB) {
   unsigned char Size;
@@ -669,17 +654,21 @@ static std::unique_ptr<InputFile> create
   if (Endian != ELFDATA2LSB && Endian != ELFDATA2MSB)
     fatal("invalid data encoding: " + MB.getBufferIdentifier());
 
-  if (Size == ELFCLASS32) {
-    if (Endian == ELFDATA2LSB)
-      return createELFFileAux<T<ELF32LE>>(MB);
-    return createELFFileAux<T<ELF32BE>>(MB);
-  }
-  if (Size == ELFCLASS64) {
-    if (Endian == ELFDATA2LSB)
-      return createELFFileAux<T<ELF64LE>>(MB);
-    return createELFFileAux<T<ELF64BE>>(MB);
-  }
-  fatal("invalid file class: " + MB.getBufferIdentifier());
+  std::unique_ptr<InputFile> Obj;
+  if (Size == ELFCLASS32 && Endian == ELFDATA2LSB)
+    Obj.reset(new T<ELF32LE>(MB));
+  else if (Size == ELFCLASS32 && Endian == ELFDATA2MSB)
+    Obj.reset(new T<ELF32BE>(MB));
+  else if (Size == ELFCLASS64 && Endian == ELFDATA2LSB)
+    Obj.reset(new T<ELF64LE>(MB));
+  else if (Size == ELFCLASS64 && Endian == ELFDATA2MSB)
+    Obj.reset(new T<ELF64BE>(MB));
+  else
+    fatal("invalid file class: " + MB.getBufferIdentifier());
+
+  if (!Config->FirstElf)
+    Config->FirstElf = Obj.get();
+  return Obj;
 }
 
 static bool isBitcode(MemoryBufferRef MB) {

Modified: lld/trunk/ELF/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=274089&r1=274088&r2=274089&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.h (original)
+++ lld/trunk/ELF/InputFiles.h Tue Jun 28 20:30:50 2016
@@ -56,6 +56,11 @@ public:
   // string for creating error messages.
   StringRef ArchiveName;
 
+  // If this is an architecture-specific file, the following members
+  // have ELF type (i.e. ELF{32,64}{LE,BE}) and target machine type.
+  ELFKind EKind = ELFNoneKind;
+  uint16_t EMachine = llvm::ELF::EM_NONE;
+
 protected:
   InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {}
 
@@ -79,11 +84,9 @@ public:
     return K == ObjectKind || K == SharedKind;
   }
 
-  static ELFKind getELFKind();
   const llvm::object::ELFFile<ELFT> &getObj() const { return ELFObj; }
   llvm::object::ELFFile<ELFT> &getObj() { return ELFObj; }
 
-  uint16_t getEMachine() const { return getObj().getHeader()->e_machine; }
   uint8_t getOSABI() const {
     return getObj().getHeader()->e_ident[llvm::ELF::EI_OSABI];
   }

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=274089&r1=274088&r2=274089&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Tue Jun 28 20:30:50 2016
@@ -35,7 +35,7 @@ template <class ELFT> static bool isComp
   auto *F = dyn_cast<ELFFileBase<ELFT>>(FileP);
   if (!F)
     return true;
-  if (F->getELFKind() == Config->EKind && F->getEMachine() == Config->EMachine)
+  if (F->EKind == Config->EKind && F->EMachine == Config->EMachine)
     return true;
   StringRef A = F->getName();
   StringRef B = Config->Emulation;

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=274089&r1=274088&r2=274089&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Tue Jun 28 20:30:50 2016
@@ -1304,7 +1304,7 @@ template <class ELFT> void Writer<ELFT>:
   EHdr->e_ident[EI_VERSION] = EV_CURRENT;
   EHdr->e_ident[EI_OSABI] = FirstObj.getOSABI();
   EHdr->e_type = getELFType();
-  EHdr->e_machine = FirstObj.getEMachine();
+  EHdr->e_machine = FirstObj.EMachine;
   EHdr->e_version = EV_CURRENT;
   EHdr->e_entry = getEntryAddr<ELFT>();
   EHdr->e_shoff = SectionHeaderOff;




More information about the llvm-commits mailing list