[lld] r249904 - ELF2: Move Target and entry initialization from SymbolTable to Driver.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 9 14:12:41 PDT 2015


Author: ruiu
Date: Fri Oct  9 16:12:40 2015
New Revision: 249904

URL: http://llvm.org/viewvc/llvm-project?rev=249904&view=rev
Log:
ELF2: Move Target and entry initialization from SymbolTable to Driver.

SymbolTable was not a right place for initialization. We had to do that
because Driver didn't know what type of ELF objects are being handled.
We taught Driver that, so we can now move this code to Driver.

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

Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=249904&r1=249903&r2=249904&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Fri Oct  9 16:12:40 2015
@@ -18,6 +18,8 @@
 namespace lld {
 namespace elf2 {
 
+class SymbolBody;
+
 enum ELFKind {
   ELFNoneKind,
   ELF32LEKind,
@@ -27,6 +29,7 @@ enum ELFKind {
 };
 
 struct Configuration {
+  SymbolBody *EntrySym = nullptr;
   llvm::StringRef DynamicLinker;
   llvm::StringRef Entry;
   llvm::StringRef Fini;

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=249904&r1=249903&r2=249904&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Fri Oct  9 16:12:40 2015
@@ -12,6 +12,7 @@
 #include "Error.h"
 #include "InputFiles.h"
 #include "SymbolTable.h"
+#include "Target.h"
 #include "Writer.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringExtras.h"
@@ -70,6 +71,26 @@ static void setELFType(StringRef Emul) {
   error(Twine("Unknown emulation: ") + Emul);
 }
 
+static TargetInfo *createTarget() {
+  switch (Config->EMachine) {
+  case EM_386:
+    return new X86TargetInfo();
+  case EM_AARCH64:
+    return new AArch64TargetInfo();
+  case EM_ARM:
+    return new ARMTargetInfo();
+  case EM_MIPS:
+    return new MipsTargetInfo();
+  case EM_PPC:
+    return new PPCTargetInfo();
+  case EM_PPC64:
+    return new PPC64TargetInfo();
+  case EM_X86_64:
+    return new X86_64TargetInfo();
+  }
+  error("Unknown target machine");
+}
+
 // Makes a path by concatenating Dir and File.
 // If Dir starts with '=' the result will be preceded by Sysroot,
 // which can be set with --sysroot command line switch.
@@ -257,12 +278,33 @@ void LinkerDriver::createFiles(opt::Inpu
 
 template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
   SymbolTable<ELFT> Symtab;
+  Target.reset(createTarget());
+
+  if (!Config->Shared) {
+    // Add entry symbol.
+    Config->EntrySym = Symtab.addUndefined(
+        Config->Entry.empty() ? Target->getDefaultEntry() : Config->Entry);
+
+    // In the assembly for 32 bit x86 the _GLOBAL_OFFSET_TABLE_ symbol
+    // is magical and is used to produce a R_386_GOTPC relocation.
+    // The R_386_GOTPC relocation value doesn't actually depend on the
+    // symbol value, so it could use an index of STN_UNDEF which, according
+    // to the spec, means the symbol value is 0.
+    // Unfortunately both gas and MC keep the _GLOBAL_OFFSET_TABLE_ symbol in
+    // the object file.
+    // The situation is even stranger on x86_64 where the assembly doesn't
+    // need the magical symbol, but gas still puts _GLOBAL_OFFSET_TABLE_ as
+    // an undefined symbol in the .o files.
+    // Given that the symbol is effectively unused, we just create a dummy
+    // hidden one to avoid the undefined symbol error.
+    Symtab.addIgnoredSym("_GLOBAL_OFFSET_TABLE_");
+  }
 
   for (std::unique_ptr<InputFile> &F : Files)
     Symtab.addFile(std::move(F));
 
   for (auto *Arg : Args.filtered(OPT_undefined))
-    Symtab.addUndefinedSym(Arg->getValue());
+    Symtab.addUndefinedOpt(Arg->getValue());
 
   if (Config->OutputFile.empty())
     Config->OutputFile = "a.out";

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=249904&r1=249903&r2=249904&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Fri Oct  9 16:12:40 2015
@@ -11,7 +11,6 @@
 #include "Config.h"
 #include "Error.h"
 #include "Symbols.h"
-#include "Target.h"
 
 using namespace llvm;
 using namespace llvm::object;
@@ -47,28 +46,18 @@ void SymbolTable<ELFT>::addFile(std::uni
   addELFFile(cast<ELFFileBase>(File.release()));
 }
 
-static TargetInfo *createTarget(uint16_t EMachine) {
-  switch (EMachine) {
-  case EM_386:
-    return new X86TargetInfo();
-  case EM_AARCH64:
-    return new AArch64TargetInfo();
-  case EM_ARM:
-    return new ARMTargetInfo();
-  case EM_MIPS:
-    return new MipsTargetInfo();
-  case EM_PPC:
-    return new PPCTargetInfo();
-  case EM_PPC64:
-    return new PPC64TargetInfo();
-  case EM_X86_64:
-    return new X86_64TargetInfo();
-  }
-  error("Unknown target machine");
+template <class ELFT>
+SymbolBody *SymbolTable<ELFT>::addUndefined(StringRef Name) {
+  auto *Sym = new (Alloc) Undefined<ELFT>(Name, Undefined<ELFT>::Required);
+  resolve(Sym);
+  return Sym;
 }
 
-template <class ELFT> void SymbolTable<ELFT>::addUndefinedSym(StringRef Name) {
-  resolve(new (Alloc) Undefined<ELFT>(Name, Undefined<ELFT>::Optional));
+template <class ELFT>
+SymbolBody *SymbolTable<ELFT>::addUndefinedOpt(StringRef Name) {
+  auto *Sym = new (Alloc) Undefined<ELFT>(Name, Undefined<ELFT>::Optional);
+  resolve(Sym);
+  return Sym;
 }
 
 template <class ELFT>
@@ -89,40 +78,12 @@ template <class ELFT> void SymbolTable<E
   resolve(Sym);
 }
 
-template <class ELFT> void SymbolTable<ELFT>::init(uint16_t EMachine) {
-  Target.reset(createTarget(EMachine));
-  if (Config->Shared)
-    return;
-  EntrySym = new (Alloc) Undefined<ELFT>(
-      Config->Entry.empty() ? Target->getDefaultEntry() : Config->Entry,
-      Undefined<ELFT>::Required);
-  resolve(EntrySym);
-
-  // In the assembly for 32 bit x86 the _GLOBAL_OFFSET_TABLE_ symbol is magical
-  // and is used to produce a R_386_GOTPC relocation.
-  // The R_386_GOTPC relocation value doesn't actually depend on the
-  // symbol value, so it could use an index of STN_UNDEF which, according to the
-  // spec, means the symbol value is 0.
-  // Unfortunately both gas and MC keep the _GLOBAL_OFFSET_TABLE_ symbol in
-  // the object file.
-  // The situation is even stranger on x86_64 where the assembly doesn't
-  // need the magical symbol, but gas still puts _GLOBAL_OFFSET_TABLE_ as
-  // an undefined symbol in the .o files.
-  // Given that the symbol is effectively unused, we just create a dummy
-  // hidden one to avoid the undefined symbol error.
-  addIgnoredSym("_GLOBAL_OFFSET_TABLE_");
-}
-
 template <class ELFT> void SymbolTable<ELFT>::addELFFile(ELFFileBase *File) {
-  const ELFFileBase *Old = getFirstELF();
   if (auto *O = dyn_cast<ObjectFile<ELFT>>(File))
     ObjectFiles.emplace_back(O);
   else if (auto *S = dyn_cast<SharedFile<ELFT>>(File))
     SharedFiles.emplace_back(S);
 
-  if (!Old)
-    init(File->getEMachine());
-
   if (auto *O = dyn_cast<ObjectFileBase>(File)) {
     for (SymbolBody *Body : O->getSymbols())
       resolve(Body);

Modified: lld/trunk/ELF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=249904&r1=249903&r2=249904&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Fri Oct  9 16:12:40 2015
@@ -55,17 +55,10 @@ public:
     return SharedFiles;
   }
 
-  SymbolBody *getEntrySym() const {
-    if (!EntrySym)
-      return nullptr;
-    return EntrySym->repl();
-  }
-
-  void addUndefinedSym(StringRef Name);
-
+  SymbolBody *addUndefined(StringRef Name);
+  SymbolBody *addUndefinedOpt(StringRef Name);
   void addSyntheticSym(StringRef Name, OutputSection<ELFT> &Section,
                        typename llvm::object::ELFFile<ELFT>::uintX_t Value);
-
   void addIgnoredSym(StringRef Name);
 
 private:
@@ -97,8 +90,6 @@ private:
 
   std::vector<std::unique_ptr<SharedFile<ELFT>>> SharedFiles;
   llvm::DenseSet<StringRef> IncludedSoNames;
-
-  SymbolBody *EntrySym = nullptr;
 };
 
 } // namespace elf2

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=249904&r1=249903&r2=249904&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Oct  9 16:12:40 2015
@@ -580,8 +580,9 @@ template <class ELFT> void Writer<ELFT>:
   EHdr->e_type = Config->Shared ? ET_DYN : ET_EXEC;
   EHdr->e_machine = FirstObj.getEMachine();
   EHdr->e_version = EV_CURRENT;
-  SymbolBody *Entry = Symtab.getEntrySym();
-  EHdr->e_entry = Entry ? getSymVA<ELFT>(cast<ELFSymbolBody<ELFT>>(*Entry)) : 0;
+  if (Config->EntrySym)
+    if (auto *E = dyn_cast<ELFSymbolBody<ELFT>>(Config->EntrySym->repl()))
+      EHdr->e_entry = getSymVA<ELFT>(*E);
   EHdr->e_phoff = ProgramHeaderOff;
   EHdr->e_shoff = SectionHeaderOff;
   EHdr->e_ehsize = sizeof(Elf_Ehdr);




More information about the llvm-commits mailing list