[lld] r249023 - ELF2: Define Driver::addFile() as a one-stop place to open a file.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 1 08:23:10 PDT 2015


Author: ruiu
Date: Thu Oct  1 10:23:09 2015
New Revision: 249023

URL: http://llvm.org/viewvc/llvm-project?rev=249023&view=rev
Log:
ELF2: Define Driver::addFile() as a one-stop place to open a file.

Opening a file and dispatching to readLinkerScript() or createFile()
is a common operation. We want to use that at least from Driver and
from LinkerScript. In COFF, we had the same problem. This patch
resolves the problem in the same way as we did for COFF.

Now, if you have a path that you want to open, just call
Driver->addFile(StringRef). That function opens the file and handles
that as if that were given by command line. This function is the
only place we call identify_magic().

Modified:
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/Driver.h
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/InputFiles.h
    lld/trunk/ELF/LinkerScript.cpp

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=249023&r1=249022&r2=249023&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Thu Oct  1 10:23:09 2015
@@ -23,31 +23,15 @@ using namespace llvm;
 using namespace lld;
 using namespace lld::elf2;
 
-namespace lld {
-namespace elf2 {
+Configuration *lld::elf2::Config;
+LinkerDriver *lld::elf2::Driver;
 
-Configuration *Config;
-std::vector<std::unique_ptr<MemoryBuffer>> *MemoryBufferPool;
-
-void link(ArrayRef<const char *> Args) {
+void lld::elf2::link(ArrayRef<const char *> Args) {
   Configuration C;
+  LinkerDriver D;
   Config = &C;
-  std::vector<std::unique_ptr<MemoryBuffer>> V;
-  MemoryBufferPool = &V;
-  LinkerDriver().link(Args.slice(1));
-}
-
-// Opens a file. Path has to be resolved already.
-// Newly created memory buffers are owned by this driver.
-MemoryBufferRef openFile(StringRef Path) {
-  ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr = MemoryBuffer::getFile(Path);
-  error(MBOrErr, Twine("cannot open ") + Path);
-  std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
-  MemoryBufferRef MBRef = MB->getMemBufferRef();
-  MemoryBufferPool->push_back(std::move(MB)); // transfer ownership
-  return MBRef;
-}
-}
+  Driver = &D;
+  Driver->link(Args.slice(1));
 }
 
 // Makes a path by concatenating Dir and File.
@@ -82,10 +66,29 @@ static std::string searchLibrary(StringR
   error(Twine("Unable to find library -l") + Path);
 }
 
-// Returns true if MB looks like a linker script.
-static bool isLinkerScript(MemoryBufferRef MB) {
+// Opens and parses a file. Path has to be resolved already.
+// Newly created memory buffers are owned by this driver.
+void LinkerDriver::addFile(StringRef Path) {
   using namespace llvm::sys::fs;
-  return identify_magic(MB.getBuffer()) == file_magic::unknown;
+  auto MBOrErr = MemoryBuffer::getFile(Path);
+  error(MBOrErr, Twine("cannot open ") + Path);
+  std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
+  MemoryBufferRef MBRef = MB->getMemBufferRef();
+  OwningMBs.push_back(std::move(MB)); // take MB ownership
+
+  switch (identify_magic(MBRef.getBuffer())) {
+  case file_magic::unknown:
+    readLinkerScript(MBRef);
+    return;
+  case file_magic::archive:
+    Symtab.addFile(make_unique<ArchiveFile>(MBRef));
+    return;
+  case file_magic::elf_shared_object:
+    Symtab.addFile(createELFFile<SharedFile>(MBRef));
+    return;
+  default:
+    Symtab.addFile(createELFFile<ObjectFile>(MBRef));
+  }
 }
 
 void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
@@ -121,20 +124,13 @@ void LinkerDriver::link(ArrayRef<const c
   Config->NoInhibitExec = Args.hasArg(OPT_noinhibit_exec);
   Config->Shared = Args.hasArg(OPT_shared);
 
-  // Create a symbol table.
-  SymbolTable Symtab;
-
   for (auto *Arg : Args.filtered(OPT_l, OPT_INPUT)) {
-    std::string Path = Arg->getValue();
-    if (Arg->getOption().getID() == OPT_l)
-      Path = searchLibrary(Path);
-    MemoryBufferRef MB = openFile(Path);
-    if (isLinkerScript(MB)) {
-      // readLinkerScript may add files to the symbol table.
-      readLinkerScript(&Symtab, MB);
-      continue;
+    StringRef Path = Arg->getValue();
+    if (Arg->getOption().getID() == OPT_l) {
+      addFile(searchLibrary(Path));
+    } else {
+      addFile(Path);
     }
-    Symtab.addFile(createFile(MB));
   }
 
   if (Symtab.getObjectFiles().empty())

Modified: lld/trunk/ELF/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.h?rev=249023&r1=249022&r2=249023&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.h (original)
+++ lld/trunk/ELF/Driver.h Thu Oct  1 10:23:09 2015
@@ -10,6 +10,7 @@
 #ifndef LLD_ELF_DRIVER_H
 #define LLD_ELF_DRIVER_H
 
+#include "SymbolTable.h"
 #include "lld/Core/LLVM.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Option/ArgList.h"
@@ -17,11 +18,7 @@
 namespace lld {
 namespace elf2 {
 
-class SymbolTable;
-
-// The owner of all opened files.
-extern std::vector<std::unique_ptr<MemoryBuffer>> *MemoryBufferPool;
-MemoryBufferRef openFile(StringRef Path);
+extern class LinkerDriver *Driver;
 
 // Entry point of the ELF linker.
 void link(ArrayRef<const char *> Args);
@@ -38,9 +35,12 @@ private:
 class LinkerDriver {
 public:
   void link(ArrayRef<const char *> Args);
+  void addFile(StringRef Path);
 
 private:
+  SymbolTable Symtab;
   ArgParser Parser;
+  std::vector<std::unique_ptr<MemoryBuffer>> OwningMBs;
 };
 
 // Create enum with OPT_xxx values for each option in Options.td
@@ -52,7 +52,7 @@ enum {
 };
 
 // Parses a linker script. Calling this function updates the Symtab and Config.
-void readLinkerScript(SymbolTable *Symtab, MemoryBufferRef MB);
+void readLinkerScript(MemoryBufferRef MB);
 
 } // namespace elf2
 } // namespace lld

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=249023&r1=249022&r2=249023&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Thu Oct  1 10:23:09 2015
@@ -21,15 +21,6 @@ using namespace llvm::sys::fs;
 using namespace lld;
 using namespace lld::elf2;
 
-std::unique_ptr<InputFile> lld::elf2::createFile(MemoryBufferRef MB) {
-  file_magic Magic = identify_magic(MB.getBuffer());
-  if (Magic == file_magic::archive)
-    return make_unique<ArchiveFile>(MB);
-  if (Magic == file_magic::elf_shared_object)
-    return createELFFile<SharedFile>(MB);
-  return createELFFile<ObjectFile>(MB);
-}
-
 template <class ELFT> static uint16_t getEMachine(const ELFFileBase &B) {
   bool IsShared = isa<SharedFileBase>(B);
   if (IsShared)

Modified: lld/trunk/ELF/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=249023&r1=249022&r2=249023&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.h (original)
+++ lld/trunk/ELF/InputFiles.h Thu Oct  1 10:23:09 2015
@@ -29,8 +29,6 @@ class InputFile;
 class Lazy;
 class SymbolBody;
 
-std::unique_ptr<InputFile> createFile(MemoryBufferRef MB);
-
 // The root class of input files.
 class InputFile {
 public:

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=249023&r1=249022&r2=249023&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Thu Oct  1 10:23:09 2015
@@ -26,7 +26,7 @@ using namespace lld::elf2;
 namespace {
 class LinkerScript {
 public:
-  LinkerScript(SymbolTable *T, StringRef S) : Symtab(T), Tokens(tokenize(S)) {}
+  LinkerScript(StringRef S) : Tokens(tokenize(S)) {}
   void run();
 
 private:
@@ -40,7 +40,6 @@ private:
   void readGroup();
   void readOutputFormat();
 
-  SymbolTable *Symtab;
   std::vector<StringRef> Tokens;
   size_t Pos = 0;
 };
@@ -125,7 +124,7 @@ void LinkerScript::readAsNeeded() {
     StringRef Tok = next();
     if (Tok == ")")
       return;
-    Symtab->addFile(createFile(openFile(Tok)));
+    Driver->addFile(Tok);
   }
 }
 
@@ -139,7 +138,7 @@ void LinkerScript::readGroup() {
       readAsNeeded();
       continue;
     }
-    Symtab->addFile(createFile(openFile(Tok)));
+    Driver->addFile(Tok);
   }
 }
 
@@ -151,6 +150,6 @@ void LinkerScript::readOutputFormat() {
 }
 
 // Entry point. The other functions or classes are private to this file.
-void lld::elf2::readLinkerScript(SymbolTable *Symtab, MemoryBufferRef MB) {
-  LinkerScript(Symtab, MB.getBuffer()).run();
+void lld::elf2::readLinkerScript(MemoryBufferRef MB) {
+  LinkerScript(MB.getBuffer()).run();
 }




More information about the llvm-commits mailing list