summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter
diff options
context:
space:
mode:
Diffstat (limited to 'lld/lib/ReaderWriter')
-rw-r--r--lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp36
-rw-r--r--lld/lib/ReaderWriter/ELF/ExecutableAtoms.h95
-rw-r--r--lld/lib/ReaderWriter/ELF/File.h73
-rw-r--r--lld/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableAtoms.h2
-rw-r--r--lld/lib/ReaderWriter/ELF/OutputELFWriter.h24
-rw-r--r--lld/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h1
-rw-r--r--lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h1
-rw-r--r--lld/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h18
-rw-r--r--lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp25
9 files changed, 130 insertions, 145 deletions
diff --git a/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp b/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
index e19a4be573b..7e013705647 100644
--- a/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
+++ b/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
@@ -9,6 +9,7 @@
#include "lld/ReaderWriter/ELFLinkingContext.h"
+#include "File.h"
#include "TargetHandler.h"
#include "Targets.h"
@@ -22,6 +23,17 @@
#include "llvm/Support/Path.h"
namespace lld {
+
+class CommandLineUndefinedAtom : public SimpleUndefinedAtom {
+public:
+ CommandLineUndefinedAtom(const File &f, StringRef name)
+ : SimpleUndefinedAtom(f, name) {}
+
+ virtual CanBeNull canBeNull() const {
+ return CanBeNull::canBeNullAtBuildtime;
+ }
+};
+
ELFLinkingContext::ELFLinkingContext(
llvm::Triple triple, std::unique_ptr<TargetHandlerBase> targetHandler)
: _outputFileType(elf::ET_EXEC), _triple(triple),
@@ -29,8 +41,7 @@ ELFLinkingContext::ELFLinkingContext(
_isStaticExecutable(false), _outputYAML(false), _noInhibitExec(false),
_mergeCommonStrings(false), _runLayoutPass(true),
_useShlibUndefines(false), _dynamicLinkerArg(false),
- _noAllowDynamicLibraries(false),
- _outputMagic(OutputMagic::DEFAULT) {}
+ _noAllowDynamicLibraries(false), _outputMagic(OutputMagic::DEFAULT) {}
bool ELFLinkingContext::is64Bits() const { return getTriple().isArch64Bit(); }
@@ -59,11 +70,13 @@ uint16_t ELFLinkingContext::getOutputMachine() const {
}
}
-bool ELFLinkingContext::validateImpl(raw_ostream &diagnostics) {
- if (_outputFileType == elf::ET_EXEC && _entrySymbolName.empty()) {
- _entrySymbolName = "_start";
- }
+StringRef ELFLinkingContext::entrySymbolName() const {
+ if (_outputFileType == elf::ET_EXEC && _entrySymbolName.empty())
+ return "_start";
+ return _entrySymbolName;
+}
+bool ELFLinkingContext::validateImpl(raw_ostream &diagnostics) {
_elfReader = createReaderELF(*this);
_linkerScriptReader.reset(new ReaderLinkerScript(*this));
_writer = _outputYAML ? createWriterYAML(*this) : createWriterELF(*this);
@@ -157,4 +170,15 @@ StringRef ELFLinkingContext::searchLibrary(
return libName;
}
+std::unique_ptr<File> ELFLinkingContext::createUndefinedSymbolFile() {
+ if (_initialUndefinedSymbols.empty())
+ return nullptr;
+ std::unique_ptr<SimpleFile> undefinedSymFile(
+ new SimpleFile(*this, "command line option -u"));
+ for (auto undefSymStr : _initialUndefinedSymbols)
+ undefinedSymFile->addAtom(*(new (_allocator) CommandLineUndefinedAtom(
+ *undefinedSymFile, undefSymStr)));
+ return std::move(undefinedSymFile);
+}
+
} // end namespace lld
diff --git a/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h b/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h
deleted file mode 100644
index 14d9ab9c97e..00000000000
--- a/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h
+++ /dev/null
@@ -1,95 +0,0 @@
-//===- lib/ReaderWriter/ELF/ExecutableAtoms.h -----------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_ELF_EXECUTABLE_ATOM_H
-#define LLD_READER_WRITER_ELF_EXECUTABLE_ATOM_H
-
-#include "Atoms.h"
-#include "File.h"
-
-#include "lld/Core/DefinedAtom.h"
-#include "lld/Core/File.h"
-#include "lld/Core/Reference.h"
-#include "lld/Core/UndefinedAtom.h"
-#include "lld/ReaderWriter/Writer.h"
-
-namespace lld {
-namespace elf {
-/// \brief All atoms are owned by a File. To add linker specific atoms
-/// the atoms need to be inserted to a file called (CRuntimeFile) which
-/// are basically additional symbols required by libc and other runtime
-/// libraries part of executing a program. This class provides support
-/// for adding absolute symbols and undefined symbols
-template <class ELFT> class CRuntimeFile : public ELFFile<ELFT> {
-public:
- typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
- CRuntimeFile(const ELFLinkingContext &context, StringRef name = "C runtime")
- : ELFFile<ELFT>(context, name) {}
-
- /// \brief add a global absolute atom
- virtual void addAbsoluteAtom(StringRef symbolName) {
- Elf_Sym *symbol = new (_allocator.Allocate<Elf_Sym>()) Elf_Sym;
- symbol->st_name = 0;
- symbol->st_value = 0;
- symbol->st_shndx = llvm::ELF::SHN_ABS;
- symbol->setBindingAndType(llvm::ELF::STB_GLOBAL,
- llvm::ELF::STT_OBJECT);
- symbol->st_other = llvm::ELF::STV_DEFAULT;
- symbol->st_size = 0;
- auto *newAtom =
- new (_allocator) ELFAbsoluteAtom<ELFT>(*this, symbolName, symbol, -1);
- _absoluteAtoms._atoms.push_back(newAtom);
- }
-
- /// \brief add an undefined atom
- virtual void addUndefinedAtom(StringRef symbolName) {
- assert(!symbolName.empty() && "UndefinedAtoms must have a name");
- Elf_Sym *symbol = new (_allocator) Elf_Sym;
- symbol->st_name = 0;
- symbol->st_value = 0;
- symbol->st_shndx = llvm::ELF::SHN_UNDEF;
- symbol->st_other = llvm::ELF::STV_DEFAULT;
- symbol->st_size = 0;
- auto *newAtom =
- new (_allocator) ELFUndefinedAtom<ELFT>(*this, symbolName, symbol);
- _undefinedAtoms._atoms.push_back(newAtom);
- }
-
- virtual const File::atom_collection<DefinedAtom> &defined() const {
- return _definedAtoms;
- }
-
- virtual const File::atom_collection<UndefinedAtom> &undefined() const {
- return _undefinedAtoms;
- }
-
- virtual const File::atom_collection<SharedLibraryAtom> &sharedLibrary() const {
- return _sharedLibraryAtoms;
- }
-
- virtual const File::atom_collection<AbsoluteAtom> &absolute() const {
- return _absoluteAtoms;
- }
-
- // cannot add atoms to C Runtime file
- virtual void addAtom(const Atom &) {
- llvm_unreachable("cannot add atoms to Runtime files");
- }
-
-protected:
- llvm::BumpPtrAllocator _allocator;
- File::atom_collection_vector<DefinedAtom> _definedAtoms;
- File::atom_collection_vector<UndefinedAtom> _undefinedAtoms;
- File::atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
- File::atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
-};
-} // end namespace elf
-} // end namespace lld
-
-#endif
diff --git a/lld/lib/ReaderWriter/ELF/File.h b/lld/lib/ReaderWriter/ELF/File.h
index 33d925067b2..7e0a07691b2 100644
--- a/lld/lib/ReaderWriter/ELF/File.h
+++ b/lld/lib/ReaderWriter/ELF/File.h
@@ -737,6 +737,79 @@ private:
/// \brief the cached options relevant while reading the ELF File
bool _doStringsMerge : 1;
};
+
+/// \brief All atoms are owned by a File. To add linker specific atoms
+/// the atoms need to be inserted to a file called (CRuntimeFile) which
+/// are basically additional symbols required by libc and other runtime
+/// libraries part of executing a program. This class provides support
+/// for adding absolute symbols and undefined symbols
+template <class ELFT> class CRuntimeFile : public ELFFile<ELFT> {
+public:
+ typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
+ CRuntimeFile(const ELFLinkingContext &context, StringRef name = "C runtime")
+ : ELFFile<ELFT>(context, name) {}
+
+ /// \brief add a global absolute atom
+ virtual Atom *addAbsoluteAtom(StringRef symbolName) {
+ assert(!symbolName.empty() && "AbsoluteAtoms must have a name");
+ Elf_Sym *symbol = new (_allocator) Elf_Sym;
+ symbol->st_name = 0;
+ symbol->st_value = 0;
+ symbol->st_shndx = llvm::ELF::SHN_ABS;
+ symbol->setBindingAndType(llvm::ELF::STB_GLOBAL, llvm::ELF::STT_OBJECT);
+ symbol->st_other = llvm::ELF::STV_DEFAULT;
+ symbol->st_size = 0;
+ auto *newAtom =
+ new (_allocator) ELFAbsoluteAtom<ELFT>(*this, symbolName, symbol, -1);
+ _absoluteAtoms._atoms.push_back(newAtom);
+ return newAtom;
+ }
+
+ /// \brief add an undefined atom
+ virtual Atom *addUndefinedAtom(StringRef symbolName) {
+ assert(!symbolName.empty() && "UndefinedAtoms must have a name");
+ Elf_Sym *symbol = new (_allocator) Elf_Sym;
+ symbol->st_name = 0;
+ symbol->st_value = 0;
+ symbol->st_shndx = llvm::ELF::SHN_UNDEF;
+ symbol->st_other = llvm::ELF::STV_DEFAULT;
+ symbol->st_size = 0;
+ auto *newAtom =
+ new (_allocator) ELFUndefinedAtom<ELFT>(*this, symbolName, symbol);
+ _undefinedAtoms._atoms.push_back(newAtom);
+ return newAtom;
+ }
+
+ virtual const File::atom_collection<DefinedAtom> &defined() const {
+ return _definedAtoms;
+ }
+
+ virtual const File::atom_collection<UndefinedAtom> &undefined() const {
+ return _undefinedAtoms;
+ }
+
+ virtual const File::atom_collection<SharedLibraryAtom> &
+ sharedLibrary() const {
+ return _sharedLibraryAtoms;
+ }
+
+ virtual const File::atom_collection<AbsoluteAtom> &absolute() const {
+ return _absoluteAtoms;
+ }
+
+ // cannot add atoms to C Runtime file
+ virtual void addAtom(const Atom &) {
+ llvm_unreachable("cannot add atoms to Runtime files");
+ }
+
+protected:
+ llvm::BumpPtrAllocator _allocator;
+ File::atom_collection_vector<DefinedAtom> _definedAtoms;
+ File::atom_collection_vector<UndefinedAtom> _undefinedAtoms;
+ File::atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
+ File::atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
+};
+
} // end namespace elf
} // end namespace lld
diff --git a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableAtoms.h b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableAtoms.h
index 30996cc249b..e74d2a10f03 100644
--- a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableAtoms.h
+++ b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableAtoms.h
@@ -10,7 +10,7 @@
#ifndef LLD_READER_WRITER_ELF_HEXAGON_EXECUTABLE_ATOM_H
#define LLD_READER_WRITER_ELF_HEXAGON_EXECUTABLE_ATOM_H
-#include "ExecutableAtoms.h"
+#include "File.h"
namespace lld {
namespace elf {
diff --git a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h
index 09e39f4fa02..df9582b9c87 100644
--- a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h
+++ b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h
@@ -17,25 +17,15 @@
#include "llvm/ADT/StringSet.h"
#include "DefaultLayout.h"
+#include "File.h"
#include "TargetLayout.h"
-#include "ExecutableAtoms.h"
namespace lld {
namespace elf {
using namespace llvm;
using namespace llvm::object;
-template<class ELFT>
-class OutputELFWriter;
-
-/// \brief This acts as a internal file that the linker uses to add
-/// undefined symbols that are defined by using the linker options such
-/// as -u, or --defsym option.
-template <class ELFT> class LinkerInternalFile : public CRuntimeFile<ELFT> {
-public:
- LinkerInternalFile(const ELFLinkingContext &context)
- : CRuntimeFile<ELFT>(context, "Linker Internal File") {};
-};
+template <class ELFT> class OutputELFWriter;
//===----------------------------------------------------------------------===//
// OutputELFWriter Class
@@ -123,7 +113,6 @@ protected:
LLD_UNIQUE_BUMP_PTR(HashSection<ELFT>) _hashTable;
llvm::StringSet<> _soNeeded;
/// @}
- LinkerInternalFile<ELFT> _linkerInternalFile;
};
//===----------------------------------------------------------------------===//
@@ -131,8 +120,7 @@ protected:
//===----------------------------------------------------------------------===//
template <class ELFT>
OutputELFWriter<ELFT>::OutputELFWriter(const ELFLinkingContext &context)
- : _context(context), _targetHandler(context.getTargetHandler<ELFT>()),
- _linkerInternalFile(context) {
+ : _context(context), _targetHandler(context.getTargetHandler<ELFT>()) {
_layout = &_targetHandler.targetLayout();
}
@@ -238,12 +226,6 @@ template <class ELFT>
void OutputELFWriter<ELFT>::addFiles(InputFiles &inputFiles) {
// Add all input Files that are defined by the target
_targetHandler.addFiles(inputFiles);
- // Add all symbols that are specified by the -u option
- // as part of the command line argument to lld
- for (auto ai : _context.initialUndefinedSymbols())
- _linkerInternalFile.addUndefinedAtom(ai);
- // Make the linker internal file to be the first file
- inputFiles.prependFile(_linkerInternalFile);
}
template <class ELFT> void OutputELFWriter<ELFT>::createDefaultSections() {
diff --git a/lld/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h b/lld/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h
index 6730351d2d9..fa2026b1f47 100644
--- a/lld/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h
+++ b/lld/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h
@@ -19,6 +19,7 @@
namespace lld {
namespace elf {
+
/// \brief x86-64 internal references.
enum {
/// \brief The 32 bit index of the relocation in the got this reference refers
diff --git a/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h b/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h
index a10a9302cda..f05d9f52c5a 100644
--- a/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h
+++ b/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h
@@ -11,6 +11,7 @@
#define LLD_READER_WRITER_ELF_X86_64_TARGET_HANDLER_H
#include "DefaultTargetHandler.h"
+#include "File.h"
#include "X86_64RelocationHandler.h"
#include "TargetLayout.h"
diff --git a/lld/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h b/lld/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h
index 54d86036fd2..0cf680f352f 100644
--- a/lld/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h
+++ b/lld/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h
@@ -111,23 +111,5 @@ private:
MemberFile _memberFile;
};
-/// An instance of UndefinedSymbolFile has a list of undefined symbols
-/// specified by "/include" command line option. This will be added to the
-/// input file list to force the core linker to try to resolve the undefined
-/// symbols.
-class UndefinedSymbolFile : public SimpleFile {
-public:
- UndefinedSymbolFile(const LinkingContext &ctx)
- : SimpleFile(ctx, "Linker Internal File") {
- for (StringRef symbol : ctx.initialUndefinedSymbols()) {
- UndefinedAtom *atom = new (_alloc) coff::COFFUndefinedAtom(*this, symbol);
- addAtom(*atom);
- }
- }
-
-private:
- llvm::BumpPtrAllocator _alloc;
-};
-
} // end namespace coff
} // end namespace lld
diff --git a/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp b/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
index 88440daf7a3..a5f830b8a8b 100644
--- a/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
+++ b/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
@@ -53,11 +53,28 @@ bool PECOFFLinkingContext::validateImpl(raw_ostream &diagnostics) {
return false;
}
-void PECOFFLinkingContext::addImplicitFiles(InputFiles &files) const {
- // Add a pseudo file for "/include" linker option.
- auto *undefFile = new (_alloc) coff::UndefinedSymbolFile(*this);
- files.prependFile(*undefFile);
+std::unique_ptr<File> PECOFFLinkingContext::createEntrySymbolFile() {
+ if (entrySymbolName().empty())
+ return nullptr;
+ std::unique_ptr<SimpleFile> entryFile(
+ new SimpleFile(*this, "command line option /entry"));
+ entryFile->addAtom(
+ *(new (_allocator) SimpleUndefinedAtom(*entryFile, entrySymbolName())));
+ return std::move(entryFile);
+}
+std::unique_ptr<File> PECOFFLinkingContext::createUndefinedSymbolFile() {
+ if (_initialUndefinedSymbols.empty())
+ return nullptr;
+ std::unique_ptr<SimpleFile> undefinedSymFile(
+ new SimpleFile(*this, "command line option /c (or) /include"));
+ for (auto undefSymStr : _initialUndefinedSymbols)
+ undefinedSymFile->addAtom(*(new (_allocator) SimpleUndefinedAtom(
+ *undefinedSymFile, undefSymStr)));
+ return std::move(undefinedSymFile);
+}
+
+void PECOFFLinkingContext::addImplicitFiles(InputFiles &files) const {
auto *linkerFile = new (_alloc) coff::LinkerGeneratedSymbolFile(*this);
files.appendFile(*linkerFile);
}
OpenPOWER on IntegriCloud