diff --git a/lld/include/lld/Core/LinkingContext.h b/lld/include/lld/Core/LinkingContext.h index b29f3a59626dd5733d32e7d8f24f56abd7a1d4b5..b1569474504ccede896b33c9fa41d7cdba9fd882 100644 --- a/lld/include/lld/Core/LinkingContext.h +++ b/lld/include/lld/Core/LinkingContext.h @@ -33,8 +33,7 @@ class SharedLibraryFile; /// /// The base class LinkingContext contains the options needed by core linking. /// Subclasses of LinkingContext have additional options needed by specific -/// Writers. For example, ELFLinkingContext has methods that supplies -/// options to the ELF Writer and ELF Passes. +/// Writers. class LinkingContext { public: /// \brief The types of output file that the linker creates. diff --git a/lld/include/lld/Core/Reader.h b/lld/include/lld/Core/Reader.h index 9324da475e3dcd8cf3669bb9787ef375e473dc12..6b3d049a5d26a9f2c54c172bd889f960db3bb1e1 100644 --- a/lld/include/lld/Core/Reader.h +++ b/lld/include/lld/Core/Reader.h @@ -27,7 +27,6 @@ class IO; } namespace lld { -class ELFLinkingContext; class File; class LinkingContext; class PECOFFLinkingContext; @@ -117,8 +116,6 @@ public: void addSupportCOFFObjects(PECOFFLinkingContext &); void addSupportCOFFImportLibraries(PECOFFLinkingContext &); void addSupportMachOObjects(MachOLinkingContext &); - void addSupportELFObjects(ELFLinkingContext &); - void addSupportELFDynamicSharedObjects(ELFLinkingContext &); /// To convert between kind values and names, the registry walks the list /// of registered kind tables. Each table is a zero terminated array of diff --git a/lld/include/lld/Core/Writer.h b/lld/include/lld/Core/Writer.h index 8214ed6203f26d60216a97d895a1254e76131404..3d9c8369b797451906becc53a08cca36932a98d8 100644 --- a/lld/include/lld/Core/Writer.h +++ b/lld/include/lld/Core/Writer.h @@ -15,7 +15,6 @@ #include namespace lld { -class ELFLinkingContext; class File; class LinkingContext; class MachOLinkingContext; @@ -41,7 +40,6 @@ protected: Writer(); }; -std::unique_ptr createWriterELF(const ELFLinkingContext &); std::unique_ptr createWriterMachO(const MachOLinkingContext &); std::unique_ptr createWriterPECOFF(const PECOFFLinkingContext &); std::unique_ptr createWriterYAML(const LinkingContext &); diff --git a/lld/include/lld/Driver/Driver.h b/lld/include/lld/Driver/Driver.h index 7b4a381c036866d077584fbfa95586c35e4348c7..37ef4945b5e66c05f53450cc35afb999a9886764 100644 --- a/lld/include/lld/Driver/Driver.h +++ b/lld/include/lld/Driver/Driver.h @@ -30,7 +30,6 @@ class LinkingContext; class CoreLinkingContext; class MachOLinkingContext; class PECOFFLinkingContext; -class ELFLinkingContext; typedef std::vector> FileVector; @@ -65,42 +64,6 @@ private: UniversalDriver() = delete; }; -/// Driver for gnu/binutil 'ld' command line options. -class GnuLdDriver : public Driver { -public: - /// Parses command line arguments same as gnu/binutils ld and performs link. - /// Returns true iff an error occurred. - static bool linkELF(llvm::ArrayRef args, - raw_ostream &diag = llvm::errs()); - - /// Uses gnu/binutils style ld command line options to fill in options struct. - /// Returns true iff there was an error. - static bool parse(llvm::ArrayRef args, - std::unique_ptr &context, - raw_ostream &diag = llvm::errs()); - - /// Parses a given memory buffer as a linker script and evaluate that. - /// Public function for testing. - static std::error_code evalLinkerScript(ELFLinkingContext &ctx, - std::unique_ptr mb, - raw_ostream &diag, bool nostdlib); - - /// A factory method to create an instance of ELFLinkingContext. - static std::unique_ptr - createELFLinkingContext(llvm::Triple triple); - -private: - static llvm::Triple getDefaultTarget(const char *progName); - static bool applyEmulation(llvm::Triple &triple, - llvm::opt::InputArgList &args, - raw_ostream &diag); - static void addPlatformSearchDirs(ELFLinkingContext &ctx, - llvm::Triple &triple, - llvm::Triple &baseTriple); - - GnuLdDriver() = delete; -}; - /// Driver for darwin/ld64 'ld' command line options. class DarwinLdDriver : public Driver { public: diff --git a/lld/include/lld/ReaderWriter/ELFLinkingContext.h b/lld/include/lld/ReaderWriter/ELFLinkingContext.h deleted file mode 100644 index d1a5b28bb61f174b1b3f9d15655c3169bfff8a19..0000000000000000000000000000000000000000 --- a/lld/include/lld/ReaderWriter/ELFLinkingContext.h +++ /dev/null @@ -1,422 +0,0 @@ -//===- lld/ReaderWriter/ELFLinkingContext.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_LINKER_CONTEXT_H -#define LLD_READER_WRITER_ELF_LINKER_CONTEXT_H - -#include "lld/Core/LinkingContext.h" -#include "lld/Core/Pass.h" -#include "lld/Core/PassManager.h" -#include "lld/Core/STDExtras.h" -#include "lld/Core/range.h" -#include "lld/Core/Reader.h" -#include "lld/Core/Writer.h" -#include "lld/ReaderWriter/LinkerScript.h" -#include "llvm/ADT/StringSet.h" -#include "llvm/ADT/Triple.h" -#include "llvm/Object/ELF.h" -#include "llvm/Support/ELF.h" -#include -#include -#include - -namespace llvm { -class FileOutputBuffer; -} - -namespace lld { -struct AtomLayout; -class File; -class Reference; - -namespace elf { -using llvm::object::ELF32LE; -using llvm::object::ELF32BE; -using llvm::object::ELF64LE; -using llvm::object::ELF64BE; - -class ELFWriter; - -std::unique_ptr createAArch64LinkingContext(llvm::Triple); -std::unique_ptr createAMDGPULinkingContext(llvm::Triple); -std::unique_ptr createARMLinkingContext(llvm::Triple); -std::unique_ptr createExampleLinkingContext(llvm::Triple); -std::unique_ptr createHexagonLinkingContext(llvm::Triple); -std::unique_ptr createMipsLinkingContext(llvm::Triple); -std::unique_ptr createX86LinkingContext(llvm::Triple); -std::unique_ptr createX86_64LinkingContext(llvm::Triple); - -class TargetRelocationHandler { -public: - virtual ~TargetRelocationHandler() {} - - virtual std::error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &, - const lld::AtomLayout &, - const Reference &) const = 0; -}; - -} // namespace elf - -/// \brief TargetHandler contains all the information responsible to handle a -/// a particular target on ELF. A target might wish to override implementation -/// of creating atoms and how the atoms are written to the output file. -class TargetHandler { -public: - virtual ~TargetHandler() {} - - /// Determines how relocations need to be applied. - virtual const elf::TargetRelocationHandler &getRelocationHandler() const = 0; - - /// Returns a reader for object files. - virtual std::unique_ptr getObjReader() = 0; - - /// Returns a reader for .so files. - virtual std::unique_ptr getDSOReader() = 0; - - /// Returns a writer to write an ELF file. - virtual std::unique_ptr getWriter() = 0; -}; - -class ELFLinkingContext : public LinkingContext { -public: - /// \brief The type of ELF executable that the linker - /// creates. - enum class OutputMagic : uint8_t { - // The default mode, no specific magic set - DEFAULT, - // Disallow shared libraries and don't align sections - // PageAlign Data, Mark Text Segment/Data segment RW - NMAGIC, - // Disallow shared libraries and don't align sections, - // Mark Text Segment/Data segment RW - OMAGIC, - }; - - /// \brief ELF DT_FLAGS. - enum DTFlag : uint32_t { - DT_NOW = 1 << 1, - DT_ORIGIN = 1 << 2, - }; - - llvm::Triple getTriple() const { return _triple; } - - uint64_t getPageSize() const { return _maxPageSize; } - void setMaxPageSize(uint64_t v) { _maxPageSize = v; } - - OutputMagic getOutputMagic() const { return _outputMagic; } - uint16_t getOutputELFType() const { return _outputELFType; } - uint16_t getOutputMachine() const; - bool mergeCommonStrings() const { return _mergeCommonStrings; } - virtual int getMachineType() const = 0; - virtual uint64_t getBaseAddress() const { return _baseAddress; } - virtual void setBaseAddress(uint64_t address) { _baseAddress = address; } - - void notifySymbolTableCoalesce(const Atom *existingAtom, const Atom *newAtom, - bool &useNew) override; - - /// This controls if undefined atoms need to be created for undefines that are - /// present in a SharedLibrary. If this option is set, undefined atoms are - /// created for every undefined symbol that are present in the dynamic table - /// in the shared library - bool useShlibUndefines() const { return _useShlibUndefines; } - - /// \brief Returns true if a given relocation should be added to the - /// dynamic relocation table. - /// - /// This table is evaluated at loadtime by the dynamic loader and is - /// referenced by the DT_RELA{,ENT,SZ} entries in the dynamic table. - /// Relocations that return true will be added to the dynamic relocation - /// table. - virtual bool isDynamicRelocation(const Reference &) const { return false; } - - /// \brief Returns true if a given reference is a copy relocation. - /// - /// If this is a copy relocation, its target must be an ObjectAtom. We must - /// include in DT_NEEDED the name of the library where this object came from. - virtual bool isCopyRelocation(const Reference &) const { return false; } - - bool validateImpl(raw_ostream &diagnostics) override; - - /// \brief Returns true if the linker allows dynamic libraries to be - /// linked with. - /// - /// This is true when the output mode of the executable is set to be - /// having NMAGIC/OMAGIC - bool allowLinkWithDynamicLibraries() const { - if (_outputMagic == OutputMagic::NMAGIC || - _outputMagic == OutputMagic::OMAGIC || _noAllowDynamicLibraries) - return false; - return true; - } - - /// \brief Use Elf_Rela format to output relocation tables. - virtual bool isRelaOutputFormat() const { return true; } - - /// \brief Returns true if a given relocation should be added to PLT. - /// - /// This table holds all of the relocations used for delayed symbol binding. - /// It will be evaluated at load time if LD_BIND_NOW is set. It is referenced - /// by the DT_{JMPREL,PLTRELSZ} entries in the dynamic table. - /// Relocations that return true will be added to the dynamic plt relocation - /// table. - virtual bool isPLTRelocation(const Reference &) const { return false; } - - /// \brief The path to the dynamic interpreter - virtual StringRef getDefaultInterpreter() const { - return "/lib64/ld-linux-x86-64.so.2"; - } - - /// \brief The dynamic linker path set by the --dynamic-linker option - StringRef getInterpreter() const { - if (_dynamicLinkerPath.hasValue()) - return _dynamicLinkerPath.getValue(); - return getDefaultInterpreter(); - } - - /// \brief Returns true if the output have dynamic sections. - bool isDynamic() const; - - /// \brief Returns true if we are creating a shared library. - bool isDynamicLibrary() const { return _outputELFType == llvm::ELF::ET_DYN; } - - /// \brief Returns true if a given relocation is a relative relocation. - virtual bool isRelativeReloc(const Reference &r) const; - - TargetHandler &getTargetHandler() const { - assert(_targetHandler && "Got null TargetHandler!"); - return *_targetHandler; - } - - virtual void registerRelocationNames(Registry &) = 0; - - void addPasses(PassManager &pm) override; - - void setTriple(llvm::Triple trip) { _triple = trip; } - void setNoInhibitExec(bool v) { _noInhibitExec = v; } - void setExportDynamic(bool v) { _exportDynamic = v; } - void setIsStaticExecutable(bool v) { _isStaticExecutable = v; } - void setMergeCommonStrings(bool v) { _mergeCommonStrings = v; } - void setUseShlibUndefines(bool use) { _useShlibUndefines = use; } - void setOutputELFType(uint32_t type) { _outputELFType = type; } - - bool shouldExportDynamic() const { return _exportDynamic; } - - void createInternalFiles(std::vector> &) const override; - - void finalizeInputFiles() override; - - /// \brief Set the dynamic linker path - void setInterpreter(StringRef s) { _dynamicLinkerPath = s; } - - /// \brief Set NMAGIC output kind when the linker specifies --nmagic - /// or -n in the command line - /// Set OMAGIC output kind when the linker specifies --omagic - /// or -N in the command line - void setOutputMagic(OutputMagic magic) { _outputMagic = magic; } - - /// \brief Disallow dynamic libraries during linking - void setNoAllowDynamicLibraries() { _noAllowDynamicLibraries = true; } - - /// Searches directories for a match on the input File - ErrorOr searchLibrary(StringRef libName) const; - - /// \brief Searches directories for a match on the input file. - /// If \p fileName is an absolute path and \p isSysRooted is true, check - /// the file under sysroot directory. If \p fileName is a relative path - /// and is not in the current directory, search the file through library - /// search directories. - ErrorOr searchFile(StringRef fileName, bool isSysRooted) const; - - /// Get the entry symbol name - StringRef entrySymbolName() const override; - - /// \brief Set new initializer function - void setInitFunction(StringRef name) { _initFunction = name; } - - /// \brief Return an initializer function name. - /// Either default "_init" or configured by the -init command line option. - StringRef initFunction() const { return _initFunction; } - - /// \brief Set new finalizer function - void setFiniFunction(StringRef name) { _finiFunction = name; } - - /// \brief Return a finalizer function name. - /// Either default "_fini" or configured by the -fini command line option. - StringRef finiFunction() const { return _finiFunction; } - - /// Add an absolute symbol. Used for --defsym. - void addInitialAbsoluteSymbol(StringRef name, uint64_t addr) { - _absoluteSymbols[name] = addr; - } - - StringRef sharedObjectName() const { return _soname; } - void setSharedObjectName(StringRef soname) { _soname = soname; } - - StringRef getSysroot() const { return _sysrootPath; } - void setSysroot(StringRef path) { _sysrootPath = path; } - - void addRpath(StringRef path) { _rpathList.push_back(path); } - range getRpathList() const { return _rpathList; } - - void addRpathLink(StringRef path) { _rpathLinkList.push_back(path); } - range getRpathLinkList() const { return _rpathLinkList; } - - const std::map &getAbsoluteSymbols() const { - return _absoluteSymbols; - } - - /// \brief Helper function to allocate strings. - StringRef allocateString(StringRef ref) const { - char *x = _allocator.Allocate(ref.size() + 1); - memcpy(x, ref.data(), ref.size()); - x[ref.size()] = '\0'; - return x; - } - - // add search path to list. - void addSearchPath(StringRef ref) { _inputSearchPaths.push_back(ref); } - - // Retrieve search path list. - StringRefVector getSearchPaths() { return _inputSearchPaths; } - - // By default, the linker would merge sections that are read only with - // segments that have read and execute permissions. When the user specifies a - // flag --rosegment, a separate segment needs to be created. - bool mergeRODataToTextSegment() const { return _mergeRODataToTextSegment; } - - void setCreateSeparateROSegment() { _mergeRODataToTextSegment = false; } - - bool isDynamicallyExportedSymbol(StringRef name) const { - return _dynamicallyExportedSymbols.count(name) != 0; - } - - /// \brief Demangle symbols. - std::string demangle(StringRef symbolName) const override; - bool demangleSymbols() const { return _demangle; } - void setDemangleSymbols(bool d) { _demangle = d; } - - /// \brief Align segments. - bool alignSegments() const { return _alignSegments; } - void setAlignSegments(bool align) { _alignSegments = align; } - - /// \brief Enable new dtags. - /// If this flag is set lld emits DT_RUNPATH instead of - /// DT_RPATH. They are functionally equivalent except for - /// the following two differences: - /// - DT_RUNPATH is searched after LD_LIBRARY_PATH, while - /// DT_RPATH is searched before. - /// - DT_RUNPATH is used only to search for direct dependencies - /// of the object it's contained in, while DT_RPATH is used - /// for indirect dependencies as well. - bool getEnableNewDtags() const { return _enableNewDtags; } - void setEnableNewDtags(bool e) { _enableNewDtags = e; } - - /// \brief Discard local symbols. - bool discardLocals() const { return _discardLocals; } - void setDiscardLocals(bool d) { _discardLocals = d; } - - /// \brief Discard temprorary local symbols. - bool discardTempLocals() const { return _discardTempLocals; } - void setDiscardTempLocals(bool d) { _discardTempLocals = d; } - - /// \brief Strip symbols. - bool stripSymbols() const { return _stripSymbols; } - void setStripSymbols(bool strip) { _stripSymbols = strip; } - - /// \brief Collect statistics. - bool collectStats() const { return _collectStats; } - void setCollectStats(bool s) { _collectStats = s; } - - // --wrap option. - void addWrapForSymbol(StringRef sym) { _wrapCalls.insert(sym); } - - // \brief Set DT_FLAGS flag. - void setDTFlag(DTFlag f) { _dtFlags |= f; } - bool getDTFlag(DTFlag f) { return (_dtFlags & f); } - - const llvm::StringSet<> &wrapCalls() const { return _wrapCalls; } - - void setUndefinesResolver(std::unique_ptr resolver); - - script::Sema &linkerScriptSema() { return _linkerScriptSema; } - const script::Sema &linkerScriptSema() const { return _linkerScriptSema; } - - /// Notify the ELFLinkingContext when the new ELF section is read. - void notifyInputSectionName(StringRef name); - /// Encountered C-ident input section names. - const llvm::StringSet<> &cidentSectionNames() const { - return _cidentSections; - } - - // Set R_ARM_TARGET1 relocation behaviour - bool armTarget1Rel() const { return _armTarget1Rel; } - void setArmTarget1Rel(bool value) { _armTarget1Rel = value; } - - // Set R_MIPS_EH relocation behaviour. - bool mipsPcRelEhRel() const { return _mipsPcRelEhRel; } - void setMipsPcRelEhRel(bool value) { _mipsPcRelEhRel = value; } - -protected: - ELFLinkingContext(llvm::Triple triple, std::unique_ptr handler) - : _triple(triple), _targetHandler(std::move(handler)) {} - - Writer &writer() const override; - - /// Method to create a internal file for an undefined symbol - std::unique_ptr createUndefinedSymbolFile() const override; - - uint16_t _outputELFType = llvm::ELF::ET_EXEC; - llvm::Triple _triple; - std::unique_ptr _targetHandler; - uint64_t _baseAddress = 0; - bool _isStaticExecutable = false; - bool _noInhibitExec = false; - bool _exportDynamic = false; - bool _mergeCommonStrings = false; - bool _useShlibUndefines = true; - bool _dynamicLinkerArg = false; - bool _noAllowDynamicLibraries = false; - bool _mergeRODataToTextSegment = true; - bool _demangle = true; - bool _discardTempLocals = false; - bool _discardLocals = false; - bool _stripSymbols = false; - bool _alignSegments = true; - bool _enableNewDtags = false; - bool _collectStats = false; - bool _armTarget1Rel = false; - bool _mipsPcRelEhRel = false; - uint64_t _maxPageSize = 0x1000; - uint32_t _dtFlags = 0; - - OutputMagic _outputMagic = OutputMagic::DEFAULT; - StringRefVector _inputSearchPaths; - std::unique_ptr _writer; - llvm::Optional _dynamicLinkerPath; - StringRef _initFunction = "_init"; - StringRef _finiFunction = "_fini"; - StringRef _sysrootPath = ""; - StringRef _soname; - StringRefVector _rpathList; - StringRefVector _rpathLinkList; - llvm::StringSet<> _wrapCalls; - std::map _absoluteSymbols; - llvm::StringSet<> _dynamicallyExportedSymbols; - std::unique_ptr _resolver; - std::mutex _cidentMutex; - llvm::StringSet<> _cidentSections; - - // The linker script semantic object, which owns all script ASTs, is stored - // in the current linking context via _linkerScriptSema. - script::Sema _linkerScriptSema; -}; - -} // end namespace lld - -#endif diff --git a/lld/lib/Driver/CMakeLists.txt b/lld/lib/Driver/CMakeLists.txt index 840ccce50ab35879016ca4d639a8e97fe86ddbcb..40b1b2b86c4b86efa825f2f42bad9da777e9cfeb 100644 --- a/lld/lib/Driver/CMakeLists.txt +++ b/lld/lib/Driver/CMakeLists.txt @@ -1,7 +1,5 @@ set(LLVM_TARGET_DEFINITIONS UniversalDriverOptions.td) tablegen(LLVM UniversalDriverOptions.inc -gen-opt-parser-defs) -set(LLVM_TARGET_DEFINITIONS GnuLdOptions.td) -tablegen(LLVM GnuLdOptions.inc -gen-opt-parser-defs) set(LLVM_TARGET_DEFINITIONS CoreOptions.td) tablegen(LLVM CoreOptions.inc -gen-opt-parser-defs) set(LLVM_TARGET_DEFINITIONS DarwinLdOptions.td) @@ -12,7 +10,6 @@ add_lld_library(lldDriver CoreDriver.cpp DarwinLdDriver.cpp Driver.cpp - GnuLdDriver.cpp UniversalDriver.cpp ADDITIONAL_HEADER_DIRS @@ -22,15 +19,7 @@ add_lld_library(lldDriver lldConfig lldMachO lldCOFF - lldELF lldELF2 - lldAArch64ELFTarget - lldARMELFTarget - lldHexagonELFTarget - lldMipsELFTarget - lldX86ELFTarget - lldExampleSubTarget - lldX86_64ELFTarget lldCore lldReaderWriter lldYAML diff --git a/lld/lib/Driver/GnuLdDriver.cpp b/lld/lib/Driver/GnuLdDriver.cpp deleted file mode 100644 index 1cff481dd8d7ad21f8899d4e20739fa0fbff2c38..0000000000000000000000000000000000000000 --- a/lld/lib/Driver/GnuLdDriver.cpp +++ /dev/null @@ -1,782 +0,0 @@ -//===- lib/Driver/GnuLdDriver.cpp -----------------------------------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// -/// Concrete instance of the Driver for GNU's ld. -/// -//===----------------------------------------------------------------------===// - -#include "lld/Driver/Driver.h" -#include "lld/ReaderWriter/ELFLinkingContext.h" -#include "lld/ReaderWriter/LinkerScript.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/Optional.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/ADT/Triple.h" -#include "llvm/Option/Arg.h" -#include "llvm/Option/Option.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Errc.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Host.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/PrettyStackTrace.h" -#include "llvm/Support/Signals.h" -#include "llvm/Support/StringSaver.h" -#include "llvm/Support/Timer.h" -#include "llvm/Support/raw_ostream.h" -#include -#include - -using namespace lld; - -using llvm::BumpPtrAllocator; - -namespace { - -// Create enum with OPT_xxx values for each option in GnuLdOptions.td -enum { - OPT_INVALID = 0, -#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ - HELP, META) \ - OPT_##ID, -#include "GnuLdOptions.inc" -#undef OPTION -}; - -// Create prefix string literals used in GnuLdOptions.td -#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE; -#include "GnuLdOptions.inc" -#undef PREFIX - -// Create table mapping all options defined in GnuLdOptions.td -static const llvm::opt::OptTable::Info infoTable[] = { -#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ - HELPTEXT, METAVAR) \ - { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \ - PARAM, FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS }, -#include "GnuLdOptions.inc" -#undef OPTION -}; - - -// Create OptTable class for parsing actual command line arguments -class GnuLdOptTable : public llvm::opt::OptTable { -public: - GnuLdOptTable() : OptTable(infoTable){} -}; - -} // anonymous namespace - -// If a command line option starts with "@", the driver reads its suffix as a -// file, parse its contents as a list of command line options, and insert them -// at the original @file position. If file cannot be read, @file is not expanded -// and left unmodified. @file can appear in a response file, so it's a recursive -// process. -static llvm::ArrayRef -maybeExpandResponseFiles(llvm::ArrayRef args, - BumpPtrAllocator &alloc) { - // Expand response files. - SmallVector smallvec; - for (const char *arg : args) - smallvec.push_back(arg); - llvm::StringSaver saver(alloc); - llvm::cl::ExpandResponseFiles(saver, llvm::cl::TokenizeGNUCommandLine, smallvec); - - // Pack the results to a C-array and return it. - const char **copy = alloc.Allocate(smallvec.size() + 1); - std::copy(smallvec.begin(), smallvec.end(), copy); - copy[smallvec.size()] = nullptr; - return llvm::makeArrayRef(copy, smallvec.size() + 1); -} - -// Parses an argument of --defsym== -static bool parseDefsymAsAbsolute(StringRef opt, StringRef &sym, - uint64_t &addr) { - size_t equalPos = opt.find('='); - if (equalPos == 0 || equalPos == StringRef::npos) - return false; - sym = opt.substr(0, equalPos); - if (opt.substr(equalPos + 1).getAsInteger(0, addr)) - return false; - return true; -} - -// Parses an argument of --defsym== -static bool parseDefsymAsAlias(StringRef opt, StringRef &sym, - StringRef &target) { - size_t equalPos = opt.find('='); - if (equalPos == 0 || equalPos == StringRef::npos) - return false; - sym = opt.substr(0, equalPos); - target = opt.substr(equalPos + 1); - return !target.empty(); -} - -// Parses -z max-page-size= -static bool parseMaxPageSize(StringRef opt, uint64_t &val) { - size_t equalPos = opt.find('='); - if (equalPos == 0 || equalPos == StringRef::npos) - return false; - StringRef value = opt.substr(equalPos + 1); - val = 0; - if (value.getAsInteger(0, val) || !val) - return false; - return true; -} - -bool GnuLdDriver::linkELF(llvm::ArrayRef args, - raw_ostream &diag) { - BumpPtrAllocator alloc; - args = maybeExpandResponseFiles(args, alloc); - std::unique_ptr options; - if (!parse(args, options, diag)) - return false; - if (!options) - return true; - bool linked = link(*options, diag); - - // Handle --stats. - if (options->collectStats()) { - llvm::TimeRecord t = llvm::TimeRecord::getCurrentTime(true); - diag << "total time in link " << t.getProcessTime() << "\n"; - diag << "data size " << t.getMemUsed() << "\n"; - } - return linked; -} - -static llvm::Optional -getArchType(const llvm::Triple &triple, StringRef value) { - switch (triple.getArch()) { - case llvm::Triple::x86: - case llvm::Triple::x86_64: - if (value == "elf_i386") - return llvm::Triple::x86; - if (value == "elf_x86_64") - return llvm::Triple::x86_64; - return llvm::None; - case llvm::Triple::mips: - case llvm::Triple::mipsel: - case llvm::Triple::mips64: - case llvm::Triple::mips64el: - return llvm::StringSwitch>(value) - .Cases("elf32btsmip", "elf32btsmipn32", llvm::Triple::mips) - .Cases("elf32ltsmip", "elf32ltsmipn32", llvm::Triple::mipsel) - .Case("elf64btsmip", llvm::Triple::mips64) - .Case("elf64ltsmip", llvm::Triple::mips64el) - .Default(llvm::None); - case llvm::Triple::aarch64: - if (value == "aarch64linux") - return llvm::Triple::aarch64; - return llvm::None; - case llvm::Triple::arm: - if (value == "armelf_linux_eabi") - return llvm::Triple::arm; - return llvm::None; - default: - return llvm::None; - } -} - -static bool isLinkerScript(StringRef path, raw_ostream &diag) { - llvm::sys::fs::file_magic magic = llvm::sys::fs::file_magic::unknown; - if (std::error_code ec = llvm::sys::fs::identify_magic(path, magic)) { - diag << "unknown input file format: " << path << ": " - << ec.message() << "\n"; - return false; - } - return magic == llvm::sys::fs::file_magic::unknown; -} - -static ErrorOr -findFile(ELFLinkingContext &ctx, StringRef path, bool dashL) { - // If the path was referred to by using a -l argument, let's search - // for the file in the search path. - if (dashL) { - ErrorOr pathOrErr = ctx.searchLibrary(path); - if (std::error_code ec = pathOrErr.getError()) - return make_dynamic_error_code( - Twine("Unable to find library -l") + path + ": " + ec.message()); - path = pathOrErr.get(); - } - if (!llvm::sys::fs::exists(path)) - return make_dynamic_error_code( - Twine("lld: cannot find file ") + path); - return path; -} - -static bool isPathUnderSysroot(StringRef sysroot, StringRef path) { - if (sysroot.empty()) - return false; - while (!path.empty() && !llvm::sys::fs::equivalent(sysroot, path)) - path = llvm::sys::path::parent_path(path); - return !path.empty(); -} - -static std::error_code -addFilesFromLinkerScript(ELFLinkingContext &ctx, StringRef scriptPath, - const std::vector &inputPaths, - raw_ostream &diag) { - bool sysroot = (!ctx.getSysroot().empty() - && isPathUnderSysroot(ctx.getSysroot(), scriptPath)); - for (const script::Path &path : inputPaths) { - ErrorOr pathOrErr = path._isDashlPrefix - ? ctx.searchLibrary(path._path) : ctx.searchFile(path._path, sysroot); - if (std::error_code ec = pathOrErr.getError()) { - auto file = llvm::make_unique(path._path, ec); - ctx.getNodes().push_back(llvm::make_unique(std::move(file))); - continue; - } - - std::vector> files - = loadFile(ctx, pathOrErr.get(), false); - for (std::unique_ptr &file : files) { - if (ctx.logInputFiles()) - diag << file->path() << "\n"; - ctx.getNodes().push_back(llvm::make_unique(std::move(file))); - } - } - return std::error_code(); -} - -std::error_code GnuLdDriver::evalLinkerScript(ELFLinkingContext &ctx, - std::unique_ptr mb, - raw_ostream &diag, - bool nostdlib) { - // Read the script file from disk and parse. - StringRef path = mb->getBufferIdentifier(); - auto parser = llvm::make_unique(std::move(mb)); - if (std::error_code ec = parser->parse()) - return ec; - script::LinkerScript *script = parser->get(); - if (!script) - return LinkerScriptReaderError::parse_error; - // Evaluate script commands. - // Currently we only recognize this subset of linker script commands. - for (const script::Command *c : script->_commands) { - if (auto *input = dyn_cast(c)) - if (std::error_code ec = addFilesFromLinkerScript( - ctx, path, input->getPaths(), diag)) - return ec; - if (auto *group = dyn_cast(c)) { - int origSize = ctx.getNodes().size(); - if (std::error_code ec = addFilesFromLinkerScript( - ctx, path, group->getPaths(), diag)) - return ec; - size_t groupSize = ctx.getNodes().size() - origSize; - ctx.getNodes().push_back(llvm::make_unique(groupSize)); - } - if (auto *searchDir = dyn_cast(c)) - if (!nostdlib) - ctx.addSearchPath(searchDir->getSearchPath()); - if (auto *entry = dyn_cast(c)) - ctx.setEntrySymbolName(entry->getEntryName()); - if (auto *output = dyn_cast(c)) - ctx.setOutputPath(output->getOutputFileName()); - if (auto *externs = dyn_cast(c)) { - for (auto symbol : *externs) { - ctx.addInitialUndefinedSymbol(symbol); - } - } - } - // Transfer ownership of the script to the linking context - ctx.linkerScriptSema().addLinkerScript(std::move(parser)); - return std::error_code(); -} - -bool GnuLdDriver::applyEmulation(llvm::Triple &triple, - llvm::opt::InputArgList &args, - raw_ostream &diag) { - llvm::opt::Arg *arg = args.getLastArg(OPT_m); - if (!arg) - return true; - llvm::Optional arch = - getArchType(triple, arg->getValue()); - if (!arch) { - diag << "error: unsupported emulation '" << arg->getValue() << "'.\n"; - return false; - } - triple.setArch(*arch); - return true; -} - -void GnuLdDriver::addPlatformSearchDirs(ELFLinkingContext &ctx, - llvm::Triple &triple, - llvm::Triple &baseTriple) { - if (triple.getOS() == llvm::Triple::NetBSD && - triple.getArch() == llvm::Triple::x86 && - baseTriple.getArch() == llvm::Triple::x86_64) { - ctx.addSearchPath("=/usr/lib/i386"); - return; - } - ctx.addSearchPath("=/usr/lib"); -} - -std::unique_ptr -GnuLdDriver::createELFLinkingContext(llvm::Triple triple) { - std::unique_ptr p; - if ((p = elf::createAArch64LinkingContext(triple))) return p; - if ((p = elf::createARMLinkingContext(triple))) return p; - if ((p = elf::createExampleLinkingContext(triple))) return p; - if ((p = elf::createHexagonLinkingContext(triple))) return p; - if ((p = elf::createMipsLinkingContext(triple))) return p; - if ((p = elf::createX86LinkingContext(triple))) return p; - if ((p = elf::createX86_64LinkingContext(triple))) return p; - return nullptr; -} - -static llvm::Optional -getBool(const llvm::opt::InputArgList &parsedArgs, - unsigned yesFlag, unsigned noFlag) { - if (auto *arg = parsedArgs.getLastArg(yesFlag, noFlag)) - return arg->getOption().getID() == yesFlag; - return llvm::None; -} - -bool GnuLdDriver::parse(llvm::ArrayRef args, - std::unique_ptr &context, - raw_ostream &diag) { - // Parse command line options using GnuLdOptions.td - GnuLdOptTable table; - unsigned missingIndex; - unsigned missingCount; - - llvm::opt::InputArgList parsedArgs = - table.ParseArgs(args.slice(1), missingIndex, missingCount); - if (missingCount) { - diag << "error: missing arg value for '" - << parsedArgs.getArgString(missingIndex) << "' expected " - << missingCount << " argument(s).\n"; - return false; - } - - // Handle --help - if (parsedArgs.hasArg(OPT_help)) { - table.PrintHelp(llvm::outs(), args[0], "LLVM Linker", false); - return true; - } - - // Use -target or use default target triple to instantiate LinkingContext - llvm::Triple baseTriple; - if (auto *arg = parsedArgs.getLastArg(OPT_target)) { - baseTriple = llvm::Triple(arg->getValue()); - } else { - baseTriple = getDefaultTarget(args[0]); - } - llvm::Triple triple(baseTriple); - - if (!applyEmulation(triple, parsedArgs, diag)) - return false; - - std::unique_ptr ctx(createELFLinkingContext(triple)); - - if (!ctx) { - diag << "unknown target triple\n"; - return false; - } - - // Copy mllvm - for (auto *arg : parsedArgs.filtered(OPT_mllvm)) - ctx->appendLLVMOption(arg->getValue()); - - // Ignore unknown arguments. - for (auto unknownArg : parsedArgs.filtered(OPT_UNKNOWN)) - diag << "warning: ignoring unknown argument: " - << unknownArg->getValue() << "\n"; - - // Set sys root path. - if (auto *arg = parsedArgs.getLastArg(OPT_sysroot)) - ctx->setSysroot(arg->getValue()); - - // Handle --demangle option(For compatibility) - if (parsedArgs.hasArg(OPT_demangle)) - ctx->setDemangleSymbols(true); - - // Handle --no-demangle option. - if (parsedArgs.hasArg(OPT_no_demangle)) - ctx->setDemangleSymbols(false); - - // Figure out output kind (-r, -static, -shared) - if (parsedArgs.hasArg(OPT_relocatable)) { - ctx->setOutputELFType(llvm::ELF::ET_REL); - ctx->setPrintRemainingUndefines(false); - ctx->setAllowRemainingUndefines(true); - } - - if (parsedArgs.hasArg(OPT_static)) { - ctx->setOutputELFType(llvm::ELF::ET_EXEC); - ctx->setIsStaticExecutable(true); - } - - if (parsedArgs.hasArg(OPT_shared)) { - ctx->setOutputELFType(llvm::ELF::ET_DYN); - ctx->setAllowShlibUndefines(true); - ctx->setUseShlibUndefines(false); - ctx->setPrintRemainingUndefines(false); - ctx->setAllowRemainingUndefines(true); - } - - // Handle --stats. - if (parsedArgs.hasArg(OPT_stats)) { - ctx->setCollectStats(true); - } - - // Figure out if the output type is nmagic/omagic - if (auto *arg = - parsedArgs.getLastArg(OPT_nmagic, OPT_omagic, OPT_no_omagic)) { - switch (arg->getOption().getID()) { - case OPT_nmagic: - ctx->setOutputMagic(ELFLinkingContext::OutputMagic::NMAGIC); - ctx->setIsStaticExecutable(true); - break; - case OPT_omagic: - ctx->setOutputMagic(ELFLinkingContext::OutputMagic::OMAGIC); - ctx->setIsStaticExecutable(true); - break; - case OPT_no_omagic: - ctx->setOutputMagic(ELFLinkingContext::OutputMagic::DEFAULT); - ctx->setNoAllowDynamicLibraries(); - break; - } - } - - if (parsedArgs.hasArg(OPT_discard_loc)) - ctx->setDiscardLocals(true); - - if (parsedArgs.hasArg(OPT_discard_temp_loc)) - ctx->setDiscardTempLocals(true); - - if (parsedArgs.hasArg(OPT_strip_all)) - ctx->setStripSymbols(true); - - if (auto *arg = parsedArgs.getLastArg(OPT_soname)) - ctx->setSharedObjectName(arg->getValue()); - - if (parsedArgs.hasArg(OPT_rosegment)) - ctx->setCreateSeparateROSegment(); - - if (parsedArgs.hasArg(OPT_no_align_segments)) - ctx->setAlignSegments(false); - - if (auto *arg = parsedArgs.getLastArg(OPT_image_base)) { - uint64_t baseAddress = 0; - StringRef inputValue = arg->getValue(); - if (inputValue.getAsInteger(0, baseAddress) || !baseAddress) { - diag << "invalid value for image base " << inputValue << "\n"; - return false; - } - ctx->setBaseAddress(baseAddress); - } - - if (parsedArgs.hasArg(OPT_merge_strings)) - ctx->setMergeCommonStrings(true); - - if (parsedArgs.hasArg(OPT_t)) - ctx->setLogInputFiles(true); - - if (parsedArgs.hasArg(OPT_use_shlib_undefs)) - ctx->setUseShlibUndefines(true); - - if (auto val = getBool(parsedArgs, OPT_allow_shlib_undefs, - OPT_no_allow_shlib_undefs)) - ctx->setAllowShlibUndefines(*val); - - if (auto *arg = parsedArgs.getLastArg(OPT_e)) - ctx->setEntrySymbolName(arg->getValue()); - - if (auto *arg = parsedArgs.getLastArg(OPT_output)) - ctx->setOutputPath(arg->getValue()); - - if (parsedArgs.hasArg(OPT_noinhibit_exec)) - ctx->setAllowRemainingUndefines(true); - - if (auto val = getBool(parsedArgs, OPT_export_dynamic, OPT_no_export_dynamic)) - ctx->setExportDynamic(*val); - - if (parsedArgs.hasArg(OPT_allow_multiple_definition)) - ctx->setAllowDuplicates(true); - - if (auto *arg = parsedArgs.getLastArg(OPT_dynamic_linker)) - ctx->setInterpreter(arg->getValue()); - - if (auto *arg = parsedArgs.getLastArg(OPT_init)) - ctx->setInitFunction(arg->getValue()); - - if (auto *arg = parsedArgs.getLastArg(OPT_fini)) - ctx->setFiniFunction(arg->getValue()); - - if (auto *arg = parsedArgs.getLastArg(OPT_output_filetype)) - ctx->setOutputFileType(arg->getValue()); - - // Process ELF/ARM specific options - bool hasArmTarget1Rel = parsedArgs.hasArg(OPT_target1_rel); - bool hasArmTarget1Abs = parsedArgs.hasArg(OPT_target1_abs); - if (triple.getArch() == llvm::Triple::arm) { - if (hasArmTarget1Rel && hasArmTarget1Abs) { - diag << "error: options --target1-rel and --target1-abs" - " can't be used together.\n"; - return false; - } else if (hasArmTarget1Rel || hasArmTarget1Abs) { - ctx->setArmTarget1Rel(hasArmTarget1Rel && !hasArmTarget1Abs); - } - } else { - for (const auto *arg : parsedArgs.filtered(OPT_grp_arm_targetopts)) { - diag << "warning: ignoring unsupported ARM/ELF specific argument: " - << arg->getSpelling() << "\n"; - } - } - - // Process MIPS specific options. - if (triple.getArch() == llvm::Triple::mips || - triple.getArch() == llvm::Triple::mipsel || - triple.getArch() == llvm::Triple::mips64 || - triple.getArch() == llvm::Triple::mips64el) { - ctx->setMipsPcRelEhRel(parsedArgs.hasArg(OPT_pcrel_eh_reloc)); - auto *hashArg = parsedArgs.getLastArg(OPT_hash_style); - if (hashArg && hashArg->getValue() != StringRef("sysv")) { - diag << "error: .gnu.hash is incompatible with the MIPS ABI\n"; - return false; - } - } - else { - for (const auto *arg : parsedArgs.filtered(OPT_grp_mips_targetopts)) { - diag << "warning: ignoring unsupported MIPS specific argument: " - << arg->getSpelling() << "\n"; - } - } - - for (auto *arg : parsedArgs.filtered(OPT_L)) - ctx->addSearchPath(arg->getValue()); - - // Add the default search directory specific to the target. - if (!parsedArgs.hasArg(OPT_nostdlib)) - addPlatformSearchDirs(*ctx, triple, baseTriple); - - for (auto *arg : parsedArgs.filtered(OPT_u)) - ctx->addInitialUndefinedSymbol(arg->getValue()); - - for (auto *arg : parsedArgs.filtered(OPT_defsym)) { - StringRef sym, target; - uint64_t addr; - if (parseDefsymAsAbsolute(arg->getValue(), sym, addr)) { - ctx->addInitialAbsoluteSymbol(sym, addr); - } else if (parseDefsymAsAlias(arg->getValue(), sym, target)) { - ctx->addAlias(sym, target); - } else { - diag << "invalid --defsym: " << arg->getValue() << "\n"; - return false; - } - } - - for (auto *arg : parsedArgs.filtered(OPT_z)) { - StringRef opt = arg->getValue(); - if (opt == "muldefs") - ctx->setAllowDuplicates(true); - else if (opt == "now") - ctx->setDTFlag(ELFLinkingContext::DTFlag::DT_NOW); - else if (opt == "origin") - ctx->setDTFlag(ELFLinkingContext::DTFlag::DT_ORIGIN); - else if (opt.startswith("max-page-size")) { - // Parse -z max-page-size option. - // The default page size is considered the minimum page size the user - // can set, check the user input if its atleast the minimum page size - // and does not exceed the maximum page size allowed for the target. - uint64_t maxPageSize = 0; - - // Error if the page size user set is less than the maximum page size - // and greather than the default page size and the user page size is a - // modulo of the default page size. - if ((!parseMaxPageSize(opt, maxPageSize)) || - (maxPageSize < ctx->getPageSize()) || - (maxPageSize % ctx->getPageSize())) { - diag << "invalid option: " << opt << "\n"; - return false; - } - ctx->setMaxPageSize(maxPageSize); - } else { - diag << "warning: ignoring unknown argument for -z: " << opt << "\n"; - } - } - - for (auto *arg : parsedArgs.filtered(OPT_rpath)) { - SmallVector rpaths; - StringRef(arg->getValue()).split(rpaths, ":"); - for (auto path : rpaths) - ctx->addRpath(path); - } - - for (auto *arg : parsedArgs.filtered(OPT_rpath_link)) { - SmallVector rpaths; - StringRef(arg->getValue()).split(rpaths, ":"); - for (auto path : rpaths) - ctx->addRpathLink(path); - } - - // Enable new dynamic tags. - if (parsedArgs.hasArg(OPT_enable_newdtags)) - ctx->setEnableNewDtags(true); - - // Support --wrap option. - for (auto *arg : parsedArgs.filtered(OPT_wrap)) - ctx->addWrapForSymbol(arg->getValue()); - - // Register possible input file parsers. - ctx->registry().addSupportELFObjects(*ctx); - ctx->registry().addSupportArchives(ctx->logInputFiles()); - ctx->registry().addSupportYamlFiles(); - if (ctx->allowLinkWithDynamicLibraries()) - ctx->registry().addSupportELFDynamicSharedObjects(*ctx); - - // Parse the LLVM options before we process files in case the file handling - // makes use of things like DEBUG(). - parseLLVMOptions(*ctx); - - std::stack groupStack; - int numfiles = 0; - bool asNeeded = false; - bool wholeArchive = false; - - // Process files - for (auto arg : parsedArgs) { - switch (arg->getOption().getID()) { - case OPT_no_whole_archive: - wholeArchive = false; - break; - - case OPT_whole_archive: - wholeArchive = true; - break; - - case OPT_as_needed: - asNeeded = true; - break; - - case OPT_no_as_needed: - asNeeded = false; - break; - - case OPT_start_group: - groupStack.push(numfiles); - break; - - case OPT_end_group: { - if (groupStack.empty()) { - diag << "stray --end-group\n"; - return false; - } - int startGroupPos = groupStack.top(); - ctx->getNodes().push_back( - llvm::make_unique(numfiles - startGroupPos)); - groupStack.pop(); - break; - } - - case OPT_INPUT: - case OPT_l: - case OPT_T: { - bool dashL = (arg->getOption().getID() == OPT_l); - StringRef path = arg->getValue(); - - ErrorOr pathOrErr = findFile(*ctx, path, dashL); - if (std::error_code ec = pathOrErr.getError()) { - auto file = llvm::make_unique(path, ec); - auto node = llvm::make_unique(std::move(file)); - node->setAsNeeded(asNeeded); - ctx->getNodes().push_back(std::move(node)); - break; - } - StringRef realpath = pathOrErr.get(); - - bool isScript = - (!path.endswith(".objtxt") && isLinkerScript(realpath, diag)); - if (isScript) { - if (ctx->logInputFiles()) - diag << path << "\n"; - ErrorOr> mb = - MemoryBuffer::getFileOrSTDIN(realpath); - if (std::error_code ec = mb.getError()) { - diag << "Cannot open " << path << ": " << ec.message() << "\n"; - return false; - } - bool nostdlib = parsedArgs.hasArg(OPT_nostdlib); - std::error_code ec = - evalLinkerScript(*ctx, std::move(mb.get()), diag, nostdlib); - if (ec) { - diag << path << ": Error parsing linker script: " - << ec.message() << "\n"; - return false; - } - break; - } - std::vector> files - = loadFile(*ctx, realpath, wholeArchive); - for (std::unique_ptr &file : files) { - if (ctx->logInputFiles()) - diag << file->path() << "\n"; - auto node = llvm::make_unique(std::move(file)); - node->setAsNeeded(asNeeded); - ctx->getNodes().push_back(std::move(node)); - } - numfiles += files.size(); - break; - } - } - } - - if (ctx->getNodes().empty()) { - diag << "No input files\n"; - return false; - } - - // Set default output file name if the output file was not specified. - if (ctx->outputPath().empty()) { - switch (ctx->outputFileType()) { - case LinkingContext::OutputFileType::YAML: - ctx->setOutputPath("-"); - break; - default: - ctx->setOutputPath("a.out"); - break; - } - } - - // Validate the combination of options used. - if (!ctx->validate(diag)) - return false; - - // Perform linker script semantic actions - if (auto ec = ctx->linkerScriptSema().perform()) { - diag << "Error in the linker script's semantics: " << ec.message() << "\n"; - return false; - } - - context.swap(ctx); - return true; -} - -/// Get the default target triple based on either the program name -/// (e.g. "x86-ibm-linux-lld") or the primary target llvm was configured for. -llvm::Triple GnuLdDriver::getDefaultTarget(const char *progName) { - SmallVector components; - llvm::SplitString(llvm::sys::path::stem(progName), components, "-"); - // If has enough parts to be start with a triple. - if (components.size() >= 4) { - llvm::Triple triple(components[0], components[1], components[2], - components[3]); - // If first component looks like an arch. - if (triple.getArch() != llvm::Triple::UnknownArch) - return triple; - } - - // Fallback to use whatever default triple llvm was configured for. - return llvm::Triple(llvm::sys::getDefaultTargetTriple()); -} diff --git a/lld/lib/Driver/GnuLdOptions.td b/lld/lib/Driver/GnuLdOptions.td deleted file mode 100644 index 7d850d4d002e6168a6cb91a144fc7fab77119713..0000000000000000000000000000000000000000 --- a/lld/lib/Driver/GnuLdOptions.td +++ /dev/null @@ -1,378 +0,0 @@ -include "llvm/Option/OptParser.td" - -//===----------------------------------------------------------------------===// -/// Utility Functions -//===----------------------------------------------------------------------===// -// Single and multiple dash options combined -multiclass smDash { - // Option - def "" : Separate<["-"], opt1>, HelpText; - def opt1_eq : Joined<["-"], opt1#"=">, - Alias(opt1)>; - // Compatibility aliases - def opt2_dashdash : Separate<["--"], opt2>, - Alias(opt1)>; - def opt2_dashdash_eq : Joined<["--"], opt2#"=">, - Alias(opt1)>; -} - -// Support -