diff options
Diffstat (limited to 'lld/lib/ReaderWriter')
-rw-r--r-- | lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp | 36 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/ExecutableAtoms.h | 95 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/File.h | 73 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableAtoms.h | 2 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/OutputELFWriter.h | 24 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h | 1 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h | 1 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h | 18 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp | 25 |
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); } |