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().
llvm-svn: 249023
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 5c65fb7..49d10fc 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -23,31 +23,15 @@
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 @@
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 @@
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())
diff --git a/lld/ELF/Driver.h b/lld/ELF/Driver.h
index a83abb5..94d2ff4 100644
--- a/lld/ELF/Driver.h
+++ b/lld/ELF/Driver.h
@@ -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 @@
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 @@
};
// 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
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 93d6230..a58359d 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -21,15 +21,6 @@
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)
diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index 1827cc7..a4d85c5 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -29,8 +29,6 @@
class Lazy;
class SymbolBody;
-std::unique_ptr<InputFile> createFile(MemoryBufferRef MB);
-
// The root class of input files.
class InputFile {
public:
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 746af74..44c045a 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -26,7 +26,7 @@
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 @@
void readGroup();
void readOutputFormat();
- SymbolTable *Symtab;
std::vector<StringRef> Tokens;
size_t Pos = 0;
};
@@ -125,7 +124,7 @@
StringRef Tok = next();
if (Tok == ")")
return;
- Symtab->addFile(createFile(openFile(Tok)));
+ Driver->addFile(Tok);
}
}
@@ -139,7 +138,7 @@
readAsNeeded();
continue;
}
- Symtab->addFile(createFile(openFile(Tok)));
+ Driver->addFile(Tok);
}
}
@@ -151,6 +150,6 @@
}
// 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();
}