Index: include/lld/Driver/Driver.h =================================================================== --- include/lld/Driver/Driver.h +++ include/lld/Driver/Driver.h @@ -117,31 +117,6 @@ }; /// Driver for Windows 'link.exe' command line options -class WinLinkDriver : public Driver { -public: - /// Parses command line arguments same as Windows link.exe and performs link. - /// Returns true iff there was an error. - static bool linkPECOFF(llvm::ArrayRef args, - raw_ostream &diag = llvm::errs()); - - /// Uses Windows style link command line options to fill in options struct. - /// Returns true iff there was an error. - static bool parse(llvm::ArrayRef args, - PECOFFLinkingContext &info, - raw_ostream &diag = llvm::errs(), bool isDirective = false); - - // Same as parse(), but restricted to the context of directives. - static bool parseDirectives(int argc, const char **argv, - PECOFFLinkingContext &info, - raw_ostream &diag = llvm::errs()) { - return parse(llvm::makeArrayRef(argv, argc), info, diag, true); - } - -private: - WinLinkDriver() = delete; -}; - -/// Driver for Windows 'link.exe' command line options namespace coff { bool link(llvm::ArrayRef args); } Index: include/lld/Driver/WinLinkModuleDef.h =================================================================== --- include/lld/Driver/WinLinkModuleDef.h +++ /dev/null @@ -1,200 +0,0 @@ -//===- lld/Driver/WinLinkModuleDef.h --------------------------------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// \brief Windows module definition file parser. -/// -//===----------------------------------------------------------------------===// - -#ifndef LLD_DRIVER_WIN_LINK_MODULE_DEF_H -#define LLD_DRIVER_WIN_LINK_MODULE_DEF_H - -#include "lld/Core/LLVM.h" -#include "lld/ReaderWriter/PECOFFLinkingContext.h" -#include "llvm/ADT/Optional.h" -#include "llvm/Support/Allocator.h" -#include - -namespace lld { -namespace moduledef { - -enum class Kind { - unknown, - eof, - identifier, - comma, - equal, - kw_base, - kw_data, - kw_exports, - kw_heapsize, - kw_library, - kw_name, - kw_noname, - kw_private, - kw_stacksize, - kw_version, -}; - -class Token { -public: - Token() : _kind(Kind::unknown) {} - Token(Kind kind, StringRef range) : _kind(kind), _range(range) {} - - Kind _kind; - StringRef _range; -}; - -class Lexer { -public: - explicit Lexer(std::unique_ptr mb) : _buffer(mb->getBuffer()) { - _sourceManager.AddNewSourceBuffer(std::move(mb), llvm::SMLoc()); - } - - Token lex(); - const llvm::SourceMgr &getSourceMgr() const { return _sourceManager; } - -private: - StringRef _buffer; - llvm::SourceMgr _sourceManager; -}; - -class Directive { -public: - enum class Kind { exports, heapsize, library, name, stacksize, version }; - - Kind getKind() const { return _kind; } - virtual ~Directive() {} - -protected: - explicit Directive(Kind k) : _kind(k) {} - -private: - Kind _kind; -}; - -class Exports : public Directive { -public: - explicit Exports(const std::vector &exports) - : Directive(Kind::exports), _exports(exports) {} - - static bool classof(const Directive *dir) { - return dir->getKind() == Kind::exports; - } - - const std::vector &getExports() const { - return _exports; - } - -private: - const std::vector _exports; -}; - -template -class MemorySize : public Directive { -public: - MemorySize(uint64_t reserve, uint64_t commit) - : Directive(kind), _reserve(reserve), _commit(commit) {} - - static bool classof(const Directive *dir) { - return dir->getKind() == kind; - } - - uint64_t getReserve() const { return _reserve; } - uint64_t getCommit() const { return _commit; } - -private: - const uint64_t _reserve; - const uint64_t _commit; -}; - -typedef MemorySize Heapsize; -typedef MemorySize Stacksize; - -class Name : public Directive { -public: - Name(StringRef outputPath, uint64_t baseaddr) - : Directive(Kind::name), _outputPath(outputPath), _baseaddr(baseaddr) {} - - static bool classof(const Directive *dir) { - return dir->getKind() == Kind::name; - } - - StringRef getOutputPath() const { return _outputPath; } - uint64_t getBaseAddress() const { return _baseaddr; } - -private: - const std::string _outputPath; - const uint64_t _baseaddr; -}; - -class Library : public Directive { -public: - Library(StringRef name, uint64_t baseaddr) - : Directive(Kind::library), _name(name), _baseaddr(baseaddr) {} - - static bool classof(const Directive *dir) { - return dir->getKind() == Kind::library; - } - - StringRef getName() const { return _name; } - uint64_t getBaseAddress() const { return _baseaddr; } - -private: - const std::string _name; - const uint64_t _baseaddr; -}; - -class Version : public Directive { -public: - Version(int major, int minor) - : Directive(Kind::version), _major(major), _minor(minor) {} - - static bool classof(const Directive *dir) { - return dir->getKind() == Kind::version; - } - - int getMajorVersion() const { return _major; } - int getMinorVersion() const { return _minor; } - -private: - const int _major; - const int _minor; -}; - -class Parser { -public: - Parser(Lexer &lex, llvm::BumpPtrAllocator &alloc) - : _lex(lex), _alloc(alloc) {} - - bool parse(std::vector &ret); - -private: - void consumeToken(); - bool consumeTokenAsInt(uint64_t &result); - bool expectAndConsume(Kind kind, Twine msg); - - void ungetToken(); - void error(const Token &tok, Twine msg); - - bool parseOne(Directive *&dir); - bool parseExport(PECOFFLinkingContext::ExportDesc &result); - bool parseMemorySize(uint64_t &reserve, uint64_t &commit); - bool parseName(std::string &outfile, uint64_t &baseaddr); - bool parseVersion(int &major, int &minor); - - Lexer &_lex; - llvm::BumpPtrAllocator &_alloc; - Token _tok; - std::vector _tokBuf; -}; -} -} - -#endif Index: include/lld/ReaderWriter/PECOFFLinkingContext.h =================================================================== --- include/lld/ReaderWriter/PECOFFLinkingContext.h +++ /dev/null @@ -1,445 +0,0 @@ -//===- lld/ReaderWriter/PECOFFLinkingContext.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_PECOFF_LINKING_CONTEXT_H -#define LLD_READER_WRITER_PECOFF_LINKING_CONTEXT_H - -#include "lld/Core/LinkingContext.h" -#include "lld/Core/Reader.h" -#include "lld/Core/Writer.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/Support/Allocator.h" -#include "llvm/Support/COFF.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/FileUtilities.h" -#include -#include -#include -#include - -using llvm::COFF::MachineTypes; -using llvm::COFF::WindowsSubsystem; - -static const uint8_t DEFAULT_DOS_STUB[128] = {'M', 'Z'}; - -namespace lld { - -class PECOFFLinkingContext : public LinkingContext { -public: - PECOFFLinkingContext() { setDeadStripping(true); } - - struct Version { - Version(int v1, int v2) : majorVersion(v1), minorVersion(v2) {} - int majorVersion; - int minorVersion; - }; - - struct ExportDesc { - ExportDesc() - : ordinal(-1), noname(false), isData(false), isPrivate(false) {} - - bool operator<(const ExportDesc &other) const { - return getExternalName().compare(other.getExternalName()) < 0; - } - - StringRef getRealName() const { - return mangledName.empty() ? name : mangledName; - } - - StringRef getExternalName() const { - return externalName.empty() ? name : externalName; - } - - std::string name; - std::string externalName; - std::string mangledName; - int ordinal; - bool noname; - bool isData; - bool isPrivate; - }; - - typedef bool (*ParseDirectives)(int, const char **, PECOFFLinkingContext &, - raw_ostream &); - - /// \brief Casting support - static bool classof(const LinkingContext *info) { return true; } - - Writer &writer() const override; - bool validateImpl(raw_ostream &diagnostics) override; - - void addPasses(PassManager &pm) override; - - void createImplicitFiles(std::vector> &result) override; - - bool is64Bit() const { - return _machineType == llvm::COFF::IMAGE_FILE_MACHINE_AMD64; - } - - // Returns a set of all defined symbols in input files. - const std::set &definedSymbols(); - - /// Page size of x86 processor. Some data needs to be aligned at page boundary - /// when loaded into memory. - uint64_t getPageSize() const { - return 0x1000; - } - - void appendInputSearchPath(StringRef dirPath) { - _inputSearchPaths.push_back(dirPath); - } - - const std::vector getInputSearchPaths() { - return _inputSearchPaths; - } - - void registerTemporaryFile(StringRef path) { - std::unique_ptr fileRemover( - new llvm::FileRemover(Twine(allocate(path)))); - _tempFiles.push_back(std::move(fileRemover)); - } - - StringRef searchLibraryFile(StringRef path) const; - - StringRef decorateSymbol(StringRef name) const; - StringRef undecorateSymbol(StringRef name) const; - - void setEntrySymbolName(StringRef name) { _entry = name; } - StringRef getEntrySymbolName() const { return _entry; } - - void setHasEntry(bool val) { _hasEntry = val; } - bool hasEntry() const { return _hasEntry; } - - void setBaseAddress(uint64_t addr) { _baseAddress = addr; } - uint64_t getBaseAddress() const; - - void setStackReserve(uint64_t size) { _stackReserve = size; } - void setStackCommit(uint64_t size) { _stackCommit = size; } - uint64_t getStackReserve() const { return _stackReserve; } - uint64_t getStackCommit() const { return _stackCommit; } - - void setHeapReserve(uint64_t size) { _heapReserve = size; } - void setHeapCommit(uint64_t size) { _heapCommit = size; } - uint64_t getHeapReserve() const { return _heapReserve; } - uint64_t getHeapCommit() const { return _heapCommit; } - - void setSectionDefaultAlignment(uint32_t val) { - _sectionDefaultAlignment = val; - } - uint32_t getSectionDefaultAlignment() const { - return _sectionDefaultAlignment; - } - - void setSubsystem(WindowsSubsystem ss) { _subsystem = ss; } - WindowsSubsystem getSubsystem() const { return _subsystem; } - - void setMachineType(MachineTypes type) { _machineType = type; } - MachineTypes getMachineType() const { return _machineType; } - - void setImageVersion(const Version &version) { _imageVersion = version; } - Version getImageVersion() const { return _imageVersion; } - - void setMinOSVersion(const Version &version) { _minOSVersion = version; } - Version getMinOSVersion() const { return _minOSVersion; } - - void setNxCompat(bool nxCompat) { _nxCompat = nxCompat; } - bool isNxCompat() const { return _nxCompat; } - - void setLargeAddressAware(bool val) { _largeAddressAware = val; } - bool getLargeAddressAware() const { return _largeAddressAware; } - - void setAllowBind(bool val) { _allowBind = val; } - bool getAllowBind() const { return _allowBind; } - - void setAllowIsolation(bool val) { _allowIsolation = val; } - bool getAllowIsolation() const { return _allowIsolation; } - - void setSwapRunFromCD(bool val) { _swapRunFromCD = val; } - bool getSwapRunFromCD() const { return _swapRunFromCD; } - - void setSwapRunFromNet(bool val) { _swapRunFromNet = val; } - bool getSwapRunFromNet() const { return _swapRunFromNet; } - - void setBaseRelocationEnabled(bool val) { _baseRelocationEnabled = val; } - bool getBaseRelocationEnabled() const { return _baseRelocationEnabled; } - - void setTerminalServerAware(bool val) { _terminalServerAware = val; } - bool isTerminalServerAware() const { return _terminalServerAware; } - - void setDynamicBaseEnabled(bool val) { _dynamicBaseEnabled = val; } - bool getDynamicBaseEnabled() const { return _dynamicBaseEnabled; } - - void setCreateManifest(bool val) { _createManifest = val; } - bool getCreateManifest() const { return _createManifest; } - - void setManifestOutputPath(std::string val) { _manifestOutputPath = val; } - const std::string &getManifestOutputPath() const { - return _manifestOutputPath; - } - - void setEmbedManifest(bool val) { _embedManifest = val; } - bool getEmbedManifest() const { return _embedManifest; } - - void setManifestId(int val) { _manifestId = val; } - int getManifestId() const { return _manifestId; } - - void setManifestUAC(bool val) { _manifestUAC = val; } - bool getManifestUAC() const { return _manifestUAC; } - - void setManifestLevel(std::string val) { _manifestLevel = std::move(val); } - const std::string &getManifestLevel() const { return _manifestLevel; } - - void setManifestUiAccess(std::string val) { _manifestUiAccess = val; } - const std::string &getManifestUiAccess() const { return _manifestUiAccess; } - - void setManifestDependency(std::string val) { _manifestDependency = val; } - const std::string &getManifestDependency() const { - return _manifestDependency; - } - - void setIsDll(bool val) { _isDll = val; } - bool isDll() const { return _isDll; } - - void setSafeSEH(bool val) { - if (val) - _requireSEH = true; - else - _noSEH = true; - } - bool requireSEH() const { return _requireSEH; } - bool noSEH() const { return _noSEH; } - - void setHighEntropyVA(bool val) { _highEntropyVA = val; } - bool getHighEntropyVA() const { return _highEntropyVA; } - - void setOutputImportLibraryPath(const std::string &val) { _implib = val; } - std::string getOutputImportLibraryPath() const; - - void setDebug(bool val) { _debug = val; } - bool getDebug() { return _debug; } - - void setPDBFilePath(StringRef str) { _pdbFilePath = str; } - std::string getPDBFilePath() const; - - void addDelayLoadDLL(StringRef dll) { - _delayLoadDLLs.insert(dll.lower()); - } - bool isDelayLoadDLL(StringRef dll) const { - return _delayLoadDLLs.count(dll.lower()) == 1; - } - - StringRef getOutputSectionName(StringRef sectionName) const; - bool addSectionRenaming(raw_ostream &diagnostics, - StringRef from, StringRef to); - - const std::set &getAlternateNames(StringRef name) { - return _alternateNames[name]; - } - - void addAlternateName(StringRef weak, StringRef def) { - _alternateNames[def].insert(weak); - } - - void addNoDefaultLib(StringRef path) { - if (path.endswith_lower(".lib")) - _noDefaultLibs.insert(path.drop_back(4).lower()); - else - _noDefaultLibs.insert(path.lower()); - } - - bool hasNoDefaultLib(StringRef path) const { - if (path.endswith_lower(".lib")) - return _noDefaultLibs.count(path.drop_back(4).lower()) > 0; - return _noDefaultLibs.count(path.lower()) > 0; - } - - void setNoDefaultLibAll(bool val) { _noDefaultLibAll = val; } - bool getNoDefaultLibAll() const { return _noDefaultLibAll; } - - void setSectionSetMask(StringRef sectionName, uint32_t flags); - void setSectionClearMask(StringRef sectionName, uint32_t flags); - uint32_t getSectionAttributes(StringRef sectionName, uint32_t flags) const; - - void setDosStub(ArrayRef data) { _dosStub = data; } - ArrayRef getDosStub() const { return _dosStub; } - - void addDllExport(ExportDesc &desc); - std::vector &getDllExports() { return _dllExports; } - const std::vector &getDllExports() const { return _dllExports; } - - StringRef getDelayLoadHelperName() const { - return is64Bit() ? "__delayLoadHelper2" : "___delayLoadHelper2@8"; - } - - llvm::BumpPtrAllocator &getAllocator() { return _allocator; } - - StringRef allocate(StringRef ref) const { - _allocMutex.lock(); - char *x = _allocator.Allocate(ref.size() + 1); - _allocMutex.unlock(); - memcpy(x, ref.data(), ref.size()); - x[ref.size()] = '\0'; - return x; - } - - ArrayRef allocate(ArrayRef array) const { - size_t size = array.size(); - _allocMutex.lock(); - uint8_t *p = _allocator.Allocate(size); - _allocMutex.unlock(); - memcpy(p, array.data(), size); - return ArrayRef(p, p + array.size()); - } - - template T &allocateCopy(const T &x) const { - _allocMutex.lock(); - T *r = new (_allocator) T(x); - _allocMutex.unlock(); - return *r; - } - - void addLibraryFile(std::unique_ptr file); - - void setModuleDefinitionFile(const std::string val) { - _moduleDefinitionFile = val; - } - std::string getModuleDefinitionFile() const { - return _moduleDefinitionFile; - } - - std::recursive_mutex &getMutex() { return _mutex; } - - void setParseDirectives(ParseDirectives parseDirectives) { - _parseDirectives = parseDirectives; - } - - ParseDirectives getParseDirectives() { - return _parseDirectives; - } - -protected: - /// Method to create a internal file for the entry symbol - std::unique_ptr createEntrySymbolFile() const override; - - /// Method to create a internal file for an undefined symbol - std::unique_ptr createUndefinedSymbolFile() const override; - -private: - enum : uint64_t { - invalidBaseAddress = UINT64_MAX, - pe32DefaultBaseAddress = 0x400000U, - pe32PlusDefaultBaseAddress = 0x140000000U - }; - - std::recursive_mutex _mutex; - mutable std::mutex _allocMutex; - - std::string _entry; - - // False if /noentry option is given. - bool _hasEntry = true; - - // The start address for the program. The default value for the executable is - // 0x400000, but can be altered using /base command line option. - uint64_t _baseAddress = invalidBaseAddress; - uint64_t _stackReserve = 1024 * 1024; - uint64_t _stackCommit = 4096; - uint64_t _heapReserve = 1024 * 1024; - uint64_t _heapCommit = 4096; - bool _noDefaultLibAll = false; - uint32_t _sectionDefaultAlignment = 4096; - WindowsSubsystem _subsystem = llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN; - MachineTypes _machineType = llvm::COFF::IMAGE_FILE_MACHINE_I386; - Version _imageVersion = {0, 0}; - Version _minOSVersion = {6, 0}; - bool _nxCompat = true; - bool _largeAddressAware = false; - bool _allowBind = true; - bool _allowIsolation = true; - bool _swapRunFromCD = false; - bool _swapRunFromNet = false; - bool _baseRelocationEnabled = true; - bool _terminalServerAware = true; - bool _dynamicBaseEnabled = true; - bool _createManifest = true; - std::string _manifestOutputPath; - bool _embedManifest = false; - int _manifestId = 1; - bool _manifestUAC = true; - std::string _manifestLevel = "'asInvoker'"; - std::string _manifestUiAccess = "'false'"; - std::string _manifestDependency; - bool _isDll = false; - bool _highEntropyVA = true; - - // True if /SAFESEH option is specified. Valid only for x86. If true, LLD will - // produce an image with SEH table. If any modules were not compatible with - // SEH, LLD will exit with an error. - bool _requireSEH = false; - - // True if /SAFESEH:no option is specified. Valid only for x86. If true, LLD - // will not produce an image with SEH table even if all input object files are - // compatible with SEH. - bool _noSEH = false; - - // /IMPLIB command line option. - std::string _implib = ""; - - // True if /DEBUG is given. - bool _debug = false; - - // PDB file output path. NB: this is dummy -- LLD just creates the empty file. - std::string _pdbFilePath = ""; - - // /DELAYLOAD option. - std::set _delayLoadDLLs; - - // The set to store /nodefaultlib arguments. - std::set _noDefaultLibs; - - std::vector _inputSearchPaths; - std::unique_ptr _writer; - - // A map for weak aliases. - std::map> _alternateNames; - - // A map for section renaming. For example, if there is an entry in the map - // whose value is .rdata -> .text, the section contens of .rdata will be - // merged to .text in the resulting executable. - std::map _renamedSections; - - // Section attributes specified by /section option. - std::map _sectionSetMask; - std::map _sectionClearMask; - - // DLLExport'ed symbols. - std::vector _dllExports; - - // List of files that will be removed on destruction. - std::vector > _tempFiles; - - // DOS Stub. DOS stub is data located at the beginning of PE/COFF file. - // Windows loader do not really care about DOS stub contents, but it's usually - // a small DOS program that prints out a message "This program requires - // Microsoft Windows." This feature was somewhat useful before Windows 95. - ArrayRef _dosStub = llvm::makeArrayRef(DEFAULT_DOS_STUB); - - // Name of the temporary file for lib.exe subcommand. For debugging - // only. - std::string _moduleDefinitionFile; - - std::set _definedSyms; - std::set _seen; - - ParseDirectives _parseDirectives = nullptr; -}; - -} // end namespace lld - -#endif Index: lib/Driver/CMakeLists.txt =================================================================== --- lib/Driver/CMakeLists.txt +++ lib/Driver/CMakeLists.txt @@ -6,8 +6,6 @@ tablegen(LLVM CoreOptions.inc -gen-opt-parser-defs) set(LLVM_TARGET_DEFINITIONS DarwinLdOptions.td) tablegen(LLVM DarwinLdOptions.inc -gen-opt-parser-defs) -set(LLVM_TARGET_DEFINITIONS WinLinkOptions.td) -tablegen(LLVM WinLinkOptions.inc -gen-opt-parser-defs) add_public_tablegen_target(DriverOptionsTableGen) add_llvm_library(lldDriver @@ -16,13 +14,10 @@ Driver.cpp GnuLdDriver.cpp UniversalDriver.cpp - WinLinkDriver.cpp - WinLinkModuleDef.cpp LINK_LIBS lldConfig lldMachO lldCOFF - lldPECOFF lldELF lldELF2 lldAArch64ELFTarget Index: lib/Driver/UniversalDriver.cpp =================================================================== --- lib/Driver/UniversalDriver.cpp +++ lib/Driver/UniversalDriver.cpp @@ -71,7 +71,6 @@ gnu_ld, // -flavor gnu gnu_ld2, // -flavor gnu2 win_link, // -flavor link - win_link2, // -flavor link2 darwin_ld, // -flavor darwin core // -flavor core OR -core }; @@ -89,8 +88,8 @@ .Case("gnu2", Flavor::gnu_ld2) .Case("link", Flavor::win_link) .Case("lld-link", Flavor::win_link) - .Case("link2", Flavor::win_link2) - .Case("lld-link2", Flavor::win_link2) + .Case("link2", Flavor::win_link) + .Case("lld-link2", Flavor::win_link) .Case("darwin", Flavor::darwin_ld) .Case("core", Flavor::core) .Case("ld", Flavor::gnu_ld) @@ -210,8 +209,6 @@ case Flavor::darwin_ld: return DarwinLdDriver::linkMachO(args, diagnostics); case Flavor::win_link: - return WinLinkDriver::linkPECOFF(args, diagnostics); - case Flavor::win_link2: return coff::link(args); case Flavor::core: return CoreDriver::link(args, diagnostics); Index: lib/Driver/WinLinkDriver.cpp =================================================================== --- lib/Driver/WinLinkDriver.cpp +++ /dev/null @@ -1,1357 +0,0 @@ -//===- lib/Driver/WinLinkDriver.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 Windows link.exe. -/// -//===----------------------------------------------------------------------===// - -#include "lld/Driver/Driver.h" -#include "lld/Driver/WinLinkModuleDef.h" -#include "lld/ReaderWriter/PECOFFLinkingContext.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/Optional.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringSwitch.h" -#include "llvm/Object/COFF.h" -#include "llvm/Option/Arg.h" -#include "llvm/Option/Option.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/Process.h" -#include "llvm/Support/Program.h" -#include "llvm/Support/StringSaver.h" -#include "llvm/Support/raw_ostream.h" -#include -#include -#include -#include -#include -#include - -namespace lld { - -// -// Option definitions -// - -// Create enum with OPT_xxx values for each option in WinLinkOptions.td -enum { - OPT_INVALID = 0, -#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ - HELP, META) \ - OPT_##ID, -#include "WinLinkOptions.inc" -#undef OPTION -}; - -// Create prefix string literals used in WinLinkOptions.td -#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE; -#include "WinLinkOptions.inc" -#undef PREFIX - -// Create table mapping all options defined in WinLinkOptions.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 "WinLinkOptions.inc" -#undef OPTION -}; - -namespace { - -// Create OptTable class for parsing actual command line arguments -class WinLinkOptTable : public llvm::opt::OptTable { -public: - // link.exe's command line options are case insensitive, unlike - // other driver's options for Unix. - WinLinkOptTable() - : OptTable(infoTable, llvm::array_lengthof(infoTable), - /* ignoreCase */ true) {} -}; - -} // anonymous namespace - -// -// Functions to parse each command line option -// - -// Split the given string with spaces. -static std::vector splitArgList(const std::string &str) { - std::stringstream stream(str); - std::istream_iterator begin(stream); - std::istream_iterator end; - return std::vector(begin, end); -} - -// Split the given string with the path separator. -static std::vector splitPathList(StringRef str) { - std::vector ret; - while (!str.empty()) { - StringRef path; - std::tie(path, str) = str.split(';'); - ret.push_back(path); - } - return ret; -} - -// Parse an argument for /alternatename. The expected string is -// "=". -static bool parseAlternateName(StringRef arg, StringRef &weak, StringRef &def, - raw_ostream &diag) { - std::tie(weak, def) = arg.split('='); - if (weak.empty() || def.empty()) { - diag << "Error: malformed /alternatename option: " << arg << "\n"; - return false; - } - return true; -} - -// Parse an argument for /base, /stack or /heap. The expected string -// is "[,]". -static bool parseMemoryOption(StringRef arg, uint64_t &reserve, - uint64_t &commit) { - StringRef reserveStr, commitStr; - std::tie(reserveStr, commitStr) = arg.split(','); - if (reserveStr.getAsInteger(0, reserve)) - return false; - if (!commitStr.empty() && commitStr.getAsInteger(0, commit)) - return false; - return true; -} - -// Parse an argument for /version or /subsystem. The expected string is -// "[.]". -static bool parseVersion(StringRef arg, uint32_t &major, uint32_t &minor) { - StringRef majorVersion, minorVersion; - std::tie(majorVersion, minorVersion) = arg.split('.'); - if (minorVersion.empty()) - minorVersion = "0"; - if (majorVersion.getAsInteger(0, major)) - return false; - if (minorVersion.getAsInteger(0, minor)) - return false; - return true; -} - -// Returns subsystem type for the given string. -static llvm::COFF::WindowsSubsystem stringToWinSubsystem(StringRef str) { - return llvm::StringSwitch(str.lower()) - .Case("windows", llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_GUI) - .Case("console", llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI) - .Case("boot_application", - llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION) - .Case("efi_application", llvm::COFF::IMAGE_SUBSYSTEM_EFI_APPLICATION) - .Case("efi_boot_service_driver", - llvm::COFF::IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) - .Case("efi_rom", llvm::COFF::IMAGE_SUBSYSTEM_EFI_ROM) - .Case("efi_runtime_driver", - llvm::COFF::IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) - .Case("native", llvm::COFF::IMAGE_SUBSYSTEM_NATIVE) - .Case("posix", llvm::COFF::IMAGE_SUBSYSTEM_POSIX_CUI) - .Default(llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN); -} - -// Parse /subsystem command line option. The form of /subsystem is -// "subsystem_name[,majorOSVersion[.minorOSVersion]]". -static bool parseSubsystem(StringRef arg, - llvm::COFF::WindowsSubsystem &subsystem, - llvm::Optional &major, - llvm::Optional &minor, raw_ostream &diag) { - StringRef subsystemStr, osVersion; - std::tie(subsystemStr, osVersion) = arg.split(','); - if (!osVersion.empty()) { - uint32_t v1, v2; - if (!parseVersion(osVersion, v1, v2)) - return false; - major = v1; - minor = v2; - } - subsystem = stringToWinSubsystem(subsystemStr); - if (subsystem == llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN) { - diag << "error: unknown subsystem name: " << subsystemStr << "\n"; - return false; - } - return true; -} - -static llvm::COFF::MachineTypes stringToMachineType(StringRef str) { - // FIXME: we have no way to differentiate between ARM and ARMNT currently. - // However, given that LLVM only supports ARM NT, default to that for now. - return llvm::StringSwitch(str.lower()) - .Case("arm", llvm::COFF::IMAGE_FILE_MACHINE_ARMNT) - .Case("x64", llvm::COFF::IMAGE_FILE_MACHINE_AMD64) - .Case("x86", llvm::COFF::IMAGE_FILE_MACHINE_I386) - .Default(llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN); -} - -// Parse /section:name,[[!]{DEKPRSW}] -// -// /section option is to set non-default bits in the Characteristics fields of -// the section header. D, E, K, P, R, S, and W represent discardable, -// execute, not_cachable, not_pageable, read, shared, and write bits, -// respectively. You can specify multiple flags in one /section option. -// -// If the flag starts with "!", the flags represent a mask that should be turned -// off regardless of the default value. You can even create a section which is -// not readable, writable nor executable with this -- although it's probably -// useless. -static bool parseSection(StringRef option, std::string §ion, - llvm::Optional &flags, - llvm::Optional &mask) { - StringRef flagString; - std::tie(section, flagString) = option.split(","); - - bool negative = false; - if (flagString.startswith("!")) { - negative = true; - flagString = flagString.substr(1); - } - if (flagString.empty()) - return false; - - uint32_t attribs = 0; - for (size_t i = 0, e = flagString.size(); i < e; ++i) { - switch (tolower(flagString[i])) { -#define CASE(c, flag) \ - case c: \ - attribs |= flag; \ - break - CASE('d', llvm::COFF::IMAGE_SCN_MEM_DISCARDABLE); - CASE('e', llvm::COFF::IMAGE_SCN_MEM_EXECUTE); - CASE('k', llvm::COFF::IMAGE_SCN_MEM_NOT_CACHED); - CASE('p', llvm::COFF::IMAGE_SCN_MEM_NOT_PAGED); - CASE('r', llvm::COFF::IMAGE_SCN_MEM_READ); - CASE('s', llvm::COFF::IMAGE_SCN_MEM_SHARED); - CASE('w', llvm::COFF::IMAGE_SCN_MEM_WRITE); -#undef CASE - default: - return false; - } - } - - if (negative) { - mask = attribs; - } else { - flags = attribs; - } - return true; -} - -static bool readFile(PECOFFLinkingContext &ctx, StringRef path, - ArrayRef &result) { - ErrorOr> buf = MemoryBuffer::getFile(path); - if (!buf) - return false; - StringRef Data = buf.get()->getBuffer(); - result = ctx.allocate(ArrayRef( - reinterpret_cast(Data.begin()), Data.size())); - return true; -} - -// Parse /manifest:EMBED[,ID=#]|NO. -static bool parseManifest(StringRef option, bool &enable, bool &embed, - int &id) { - if (option.equals_lower("no")) { - enable = false; - return true; - } - if (!option.startswith_lower("embed")) - return false; - - embed = true; - option = option.substr(strlen("embed")); - if (option.empty()) - return true; - if (!option.startswith_lower(",id=")) - return false; - option = option.substr(strlen(",id=")); - if (option.getAsInteger(0, id)) - return false; - return true; -} - -static bool isLibraryFile(StringRef path) { - return path.endswith_lower(".lib") || path.endswith_lower(".imp"); -} - -static StringRef getObjectPath(PECOFFLinkingContext &ctx, StringRef path) { - std::string result; - if (isLibraryFile(path)) { - result = ctx.searchLibraryFile(path); - } else if (llvm::sys::path::extension(path).empty()) { - result = path.str() + ".obj"; - } else { - result = path; - } - return ctx.allocate(result); -} - -static StringRef getLibraryPath(PECOFFLinkingContext &ctx, StringRef path) { - std::string result = isLibraryFile(path) - ? ctx.searchLibraryFile(path) - : ctx.searchLibraryFile(path.str() + ".lib"); - return ctx.allocate(result); -} - -// Returns true if the given file is a Windows resource file. -static bool isResoruceFile(StringRef path) { - llvm::sys::fs::file_magic fileType; - if (llvm::sys::fs::identify_magic(path, fileType)) { - // If we cannot read the file, assume it's not a resource file. - // The further stage will raise an error on this unreadable file. - return false; - } - return fileType == llvm::sys::fs::file_magic::windows_resource; -} - -// Merge Windows resource files and convert them to a single COFF file. -// The temporary file path is set to result. -static bool convertResourceFiles(PECOFFLinkingContext &ctx, - std::vector inFiles, - std::string &result) { - // Create an output file path. - SmallString<128> outFile; - if (llvm::sys::fs::createTemporaryFile("resource", "obj", outFile)) - return false; - std::string outFileArg = ("/out:" + outFile).str(); - - // Construct CVTRES.EXE command line and execute it. - std::string program = "cvtres.exe"; - ErrorOr programPathOrErr = llvm::sys::findProgramByName(program); - if (!programPathOrErr) { - llvm::errs() << "Unable to find " << program << " in PATH\n"; - return false; - } - const std::string &programPath = *programPathOrErr; - - std::vector args; - args.push_back(programPath.c_str()); - args.push_back(ctx.is64Bit() ? "/machine:x64" : "/machine:x86"); - args.push_back("/readonly"); - args.push_back("/nologo"); - args.push_back(outFileArg.c_str()); - for (const std::string &path : inFiles) - args.push_back(path.c_str()); - args.push_back(nullptr); - - if (llvm::sys::ExecuteAndWait(programPath.c_str(), &args[0]) != 0) { - llvm::errs() << program << " failed\n"; - return false; - } - result = outFile.str(); - return true; -} - -// Parse /manifestuac:(level=|uiAccess=). -// -// The arguments will be embedded to the manifest XML file with no error check, -// so the values given via the command line must be valid as XML attributes. -// This may sound a bit odd, but that's how link.exe works, so we will follow. -static bool parseManifestUAC(StringRef option, - llvm::Optional &level, - llvm::Optional &uiAccess) { - for (;;) { - option = option.ltrim(); - if (option.empty()) - return true; - if (option.startswith_lower("level=")) { - option = option.substr(strlen("level=")); - StringRef value; - std::tie(value, option) = option.split(" "); - level = value.str(); - continue; - } - if (option.startswith_lower("uiaccess=")) { - option = option.substr(strlen("uiaccess=")); - StringRef value; - std::tie(value, option) = option.split(" "); - uiAccess = value.str(); - continue; - } - return false; - } -} - -// Returns the machine type (e.g. x86) of the given input file. -// If the file is not COFF, returns false. -static bool getMachineType(StringRef path, llvm::COFF::MachineTypes &result) { - llvm::sys::fs::file_magic fileType; - if (llvm::sys::fs::identify_magic(path, fileType)) - return false; - if (fileType != llvm::sys::fs::file_magic::coff_object) - return false; - ErrorOr> buf = MemoryBuffer::getFile(path); - if (!buf) - return false; - std::error_code ec; - llvm::object::COFFObjectFile obj(buf.get()->getMemBufferRef(), ec); - if (ec) - return false; - result = static_cast(obj.getMachine()); - return true; -} - -// Parse /export:entryname[=internalname][,@ordinal[,NONAME]][,DATA][,PRIVATE]. -// -// MSDN doesn't say anything about /export:foo=bar style option or PRIVATE -// attribtute, but link.exe actually accepts them. -static bool parseExport(StringRef option, - PECOFFLinkingContext::ExportDesc &ret) { - StringRef name; - StringRef rest; - std::tie(name, rest) = option.split(","); - if (name.empty()) - return false; - if (name.find('=') == StringRef::npos) { - ret.name = name; - } else { - std::tie(ret.externalName, ret.name) = name.split("="); - if (ret.name.empty()) - return false; - } - - for (;;) { - if (rest.empty()) - return true; - StringRef arg; - std::tie(arg, rest) = rest.split(","); - if (arg.equals_lower("noname")) { - if (ret.ordinal < 0) - return false; - ret.noname = true; - continue; - } - if (arg.equals_lower("data")) { - ret.isData = true; - continue; - } - if (arg.equals_lower("private")) { - ret.isPrivate = true; - continue; - } - if (arg.startswith("@")) { - int ordinal; - if (arg.substr(1).getAsInteger(0, ordinal)) - return false; - if (ordinal <= 0 || 65535 < ordinal) - return false; - ret.ordinal = ordinal; - continue; - } - return false; - } -} - -// Read module-definition file. -static bool parseDef(StringRef option, llvm::BumpPtrAllocator &alloc, - std::vector &result) { - ErrorOr> buf = MemoryBuffer::getFile(option); - if (!buf) - return false; - moduledef::Lexer lexer(std::move(buf.get())); - moduledef::Parser parser(lexer, alloc); - return parser.parse(result); -} - -static StringRef replaceExtension(PECOFFLinkingContext &ctx, StringRef path, - StringRef extension) { - SmallString<128> val = path; - llvm::sys::path::replace_extension(val, extension); - return ctx.allocate(val.str()); -} - -// Create a manifest file contents. -static std::string createManifestXml(PECOFFLinkingContext &ctx) { - std::string ret; - llvm::raw_string_ostream out(ret); - // Emit the XML. Note that we do *not* verify that the XML attributes are - // syntactically correct. This is intentional for link.exe compatibility. - out << "\n" - "\n"; - if (ctx.getManifestUAC()) { - out << " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n"; - const std::string &dependency = ctx.getManifestDependency(); - if (!dependency.empty()) { - out << " \n" - " \n" - " \n" - " \n" - " \n"; - } - } - out << "\n"; - out.flush(); - return ret; -} - -// Convert one doublequote to two doublequotes, so that we can embed the string -// into a resource script file. -static void quoteAndPrintXml(raw_ostream &out, StringRef str) { - for (;;) { - if (str.empty()) - return; - StringRef line; - std::tie(line, str) = str.split("\n"); - if (line.empty()) - continue; - out << '\"'; - const char *p = line.data(); - for (int i = 0, size = line.size(); i < size; ++i) { - switch (p[i]) { - case '\"': - out << '\"'; - // fallthrough - default: - out << p[i]; - } - } - out << "\"\n"; - } -} - -// Create a resource file (.res file) containing the manifest XML. This is done -// in two steps: -// -// 1. Create a resource script file containing the XML as a literal string. -// 2. Run RC.EXE command to compile the script file to a resource file. -// -// The temporary file created in step 1 will be deleted on exit from this -// function. The file created in step 2 will have the same lifetime as the -// PECOFFLinkingContext. -static bool createManifestResourceFile(PECOFFLinkingContext &ctx, - raw_ostream &diag, - std::string &resFile) { - // Create a temporary file for the resource script file. - SmallString<128> rcFileSmallString; - if (llvm::sys::fs::createTemporaryFile("tmp", "rc", rcFileSmallString)) { - diag << "Cannot create a temporary file\n"; - return false; - } - StringRef rcFile(rcFileSmallString.str()); - llvm::FileRemover rcFileRemover((Twine(rcFile))); - - // Open the temporary file for writing. - std::error_code ec; - llvm::raw_fd_ostream out(rcFileSmallString, ec, llvm::sys::fs::F_Text); - if (ec) { - diag << "Failed to open " << ctx.getManifestOutputPath() << ": " - << ec.message() << "\n"; - return false; - } - - // Write resource script to the RC file. - out << "#define LANG_ENGLISH 9\n" - << "#define SUBLANG_DEFAULT 1\n" - << "#define APP_MANIFEST " << ctx.getManifestId() << "\n" - << "#define RT_MANIFEST 24\n" - << "LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT\n" - << "APP_MANIFEST RT_MANIFEST {\n"; - quoteAndPrintXml(out, createManifestXml(ctx)); - out << "}\n"; - out.close(); - - // Create output resource file. - SmallString<128> resFileSmallString; - if (llvm::sys::fs::createTemporaryFile("tmp", "res", resFileSmallString)) { - diag << "Cannot create a temporary file"; - return false; - } - resFile = resFileSmallString.str(); - - // Register the resource file path so that the file will be deleted when the - // context's destructor is called. - ctx.registerTemporaryFile(resFile); - - // Run RC.EXE /fo tmp.res tmp.rc - std::string program = "rc.exe"; - ErrorOr programPathOrErr = llvm::sys::findProgramByName(program); - if (!programPathOrErr) { - diag << "Unable to find " << program << " in PATH\n"; - return false; - } - const std::string &programPath = *programPathOrErr; - std::vector args; - args.push_back(programPath.c_str()); - args.push_back("/fo"); - args.push_back(resFile.c_str()); - args.push_back("/nologo"); - args.push_back(rcFileSmallString.c_str()); - args.push_back(nullptr); - - if (llvm::sys::ExecuteAndWait(programPath.c_str(), &args[0]) != 0) { - diag << program << " failed\n"; - return false; - } - return true; -} - - -// Create the a side-by-side manifest file. -// -// The manifest file will convey some information to the linker, such as whether -// the binary needs to run as Administrator or not. Instead of being placed in -// the PE/COFF header, it's in XML format for some reason -- I guess it's -// probably because it's invented in the early dot-com era. -// -// The side-by-side manifest file is a separate XML file having ".manifest" -// extension. It will be created in the same directory as the resulting -// executable. -static bool createSideBySideManifestFile(PECOFFLinkingContext &ctx, - raw_ostream &diag) { - std::string path = ctx.getManifestOutputPath(); - if (path.empty()) { - // Default name of the manifest file is "foo.exe.manifest" where "foo.exe" is - // the output path. - path = ctx.outputPath(); - path.append(".manifest"); - } - - std::error_code ec; - llvm::raw_fd_ostream out(path, ec, llvm::sys::fs::F_Text); - if (ec) { - diag << ec.message() << "\n"; - return false; - } - out << createManifestXml(ctx); - return true; -} - -// Handle /failifmismatch option. -static bool -handleFailIfMismatchOption(StringRef option, - std::map &mustMatch, - raw_ostream &diag) { - StringRef key, value; - std::tie(key, value) = option.split('='); - if (key.empty() || value.empty()) { - diag << "error: malformed /failifmismatch option: " << option << "\n"; - return true; - } - auto it = mustMatch.find(key); - if (it != mustMatch.end() && it->second != value) { - diag << "error: mismatch detected: '" << it->second << "' and '" << value - << "' for key '" << key << "'\n"; - return true; - } - mustMatch[key] = value; - return false; -} - -// -// Environment variable -// - -// Process "LINK" environment variable. If defined, the value of the variable -// should be processed as command line arguments. -static std::vector -processLinkEnv(PECOFFLinkingContext &ctx, llvm::ArrayRef args) { - std::vector ret; - // The first argument is the name of the command. This should stay at the head - // of the argument list. - assert(!args.empty()); - ret.push_back(args[0]); - - // Add arguments specified by the LINK environment variable. - llvm::Optional env = llvm::sys::Process::GetEnv("LINK"); - if (env.hasValue()) - for (std::string &arg : splitArgList(*env)) - ret.push_back(ctx.allocate(arg).data()); - - // Add the rest of arguments passed via the command line. - for (const char *arg : args.slice(1)) - ret.push_back(arg); - ret.push_back(nullptr); - return ret; -} - -// Process "LIB" environment variable. The variable contains a list of search -// paths separated by semicolons. -static void processLibEnv(PECOFFLinkingContext &ctx) { - llvm::Optional env = llvm::sys::Process::GetEnv("LIB"); - if (env.hasValue()) - for (StringRef path : splitPathList(*env)) - ctx.appendInputSearchPath(ctx.allocate(path)); -} - -// Tokenize command line options in a given file and add them to result. -static bool readResponseFile(StringRef path, PECOFFLinkingContext &ctx, - std::vector &result) { - ArrayRef contents; - if (!readFile(ctx, path, contents)) - return false; - StringRef contentsStr(reinterpret_cast(contents.data()), - contents.size()); - llvm::BumpPtrStringSaver saver(ctx.getAllocator()); - SmallVector args; - llvm::cl::TokenizeWindowsCommandLine(contentsStr, saver, args); - for (const char *s : args) - result.push_back(s); - return true; -} - -// Expand arguments starting with "@". It's an error if a specified file does -// not exist. Returns true on success. -static bool expandResponseFiles(llvm::ArrayRef &args, - PECOFFLinkingContext &ctx, raw_ostream &diag, - bool &expanded) { - std::vector newArgv; - for (const char *arg : args) { - if (arg[0] != '@') { - newArgv.push_back(arg); - continue; - } - StringRef filename = StringRef(arg + 1); - if (!readResponseFile(filename, ctx, newArgv)) { - diag << "error: cannot read response file: " << filename << "\n"; - return false; - } - expanded = true; - } - if (!expanded) - return true; - newArgv.push_back(nullptr); - args = llvm::makeArrayRef(&ctx.allocateCopy(newArgv)[0], newArgv.size() - 1); - return true; -} - -// Parses the given command line options and returns the result. Returns NULL if -// there's an error in the options. -static llvm::Optional -parseArgs(llvm::ArrayRef args, PECOFFLinkingContext &ctx, - raw_ostream &diag, bool isReadingDirectiveSection) { - // Expand arguments starting with "@". - bool expanded = false; - if (!expandResponseFiles(args, ctx, diag, expanded)) - return llvm::None; - - // Parse command line options using WinLinkOptions.td - WinLinkOptTable 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 llvm::None; - } - - // Show warning for unknown arguments. In .drectve section, unknown options - // starting with "-?" are silently ignored. This is a COFF's feature to embed a - // new linker option to an object file while keeping backward compatibility. - for (auto unknownArg : parsedArgs.filtered(OPT_UNKNOWN)) { - StringRef arg = unknownArg->getSpelling(); - if (isReadingDirectiveSection && arg.startswith("-?")) - continue; - diag << "warning: ignoring unknown argument: " << arg << "\n"; - } - - // Copy mllvm - for (auto arg : parsedArgs.filtered(OPT_mllvm)) - ctx.appendLLVMOption(arg->getValue()); - - // If we have expaneded response files and /verbose is given, print out the - // final command line. - if (!isReadingDirectiveSection && expanded && - parsedArgs.getLastArg(OPT_verbose)) { - diag << "Command line:"; - for (const char *arg : args) - diag << " " << arg; - diag << "\n\n"; - } - - return std::move(parsedArgs); -} - -// Returns true if the given file node has already been added to the input -// graph. -static bool hasLibrary(PECOFFLinkingContext &ctx, File *file) { - StringRef path = file->path(); - for (std::unique_ptr &p : ctx.getNodes()) - if (auto *f = dyn_cast(p.get())) - if (f->getFile()->path() == path) - return true; - return false; -} - -// If the first command line argument is "/lib", link.exe acts as if it's -// "lib.exe" command. This is for backward compatibility. -// http://msdn.microsoft.com/en-us/library/h34w59b3.aspx -static bool maybeRunLibCommand(llvm::ArrayRef args, - raw_ostream &diag) { - if (args.size() <= 1) - return false; - if (!StringRef(args[1]).equals_lower("/lib")) - return false; - ErrorOr pathOrErr = llvm::sys::findProgramByName("lib.exe"); - if (!pathOrErr) { - diag << "Unable to find lib.exe in PATH\n"; - return true; - } - const std::string &path = *pathOrErr; - - // Run lib.exe - std::vector vec; - vec.push_back(path.c_str()); - for (const char *arg : args.slice(2)) - vec.push_back(arg); - vec.push_back(nullptr); - - if (llvm::sys::ExecuteAndWait(path.c_str(), &vec[0]) != 0) - diag << "lib.exe failed\n"; - return true; -} - -/// \brief Parse the input file to lld::File. -void addFiles(PECOFFLinkingContext &ctx, StringRef path, raw_ostream &diag, - std::vector> &files) { - for (std::unique_ptr &file : loadFile(ctx, path, false)) { - if (ctx.logInputFiles()) - diag << file->path() << "\n"; - files.push_back(std::move(file)); - } -} - -// -// Main driver -// - -bool WinLinkDriver::linkPECOFF(llvm::ArrayRef args, - raw_ostream &diag) { - if (maybeRunLibCommand(args, diag)) - return true; - - PECOFFLinkingContext ctx; - ctx.setParseDirectives(parseDirectives); - ctx.registry().addSupportCOFFObjects(ctx); - ctx.registry().addSupportCOFFImportLibraries(ctx); - ctx.registry().addSupportArchives(ctx.logInputFiles()); - ctx.registry().addSupportYamlFiles(); - - std::vector newargv = processLinkEnv(ctx, args); - processLibEnv(ctx); - if (!parse(llvm::makeArrayRef(newargv).drop_back(1), ctx, diag)) - return false; - - // Create the file if needed. - if (ctx.getCreateManifest() && !ctx.getEmbedManifest()) - if (!createSideBySideManifestFile(ctx, diag)) - return false; - - return link(ctx, diag); -} - -bool WinLinkDriver::parse(llvm::ArrayRef args, - PECOFFLinkingContext &ctx, raw_ostream &diag, - bool isReadingDirectiveSection) { - // Parse may be called from multiple threads simultaneously to parse .drectve - // sections. This function is not thread-safe because it mutates the context - // object. So acquire the lock. - std::lock_guard lock(ctx.getMutex()); - - std::map failIfMismatchMap; - // Parse the options. - llvm::Optional parsedArgs = - parseArgs(args, ctx, diag, isReadingDirectiveSection); - if (!parsedArgs) - return false; - - // The list of input files. - std::vector> files; - std::vector> libraries; - - // Handle /help - if (parsedArgs->hasArg(OPT_help)) { - WinLinkOptTable table; - table.PrintHelp(llvm::outs(), args[0], "LLVM Linker", false); - return false; - } - - // Handle /machine before parsing all the other options, as the target machine - // type affects how to handle other options. For example, x86 needs the - // leading underscore to mangle symbols, while x64 doesn't need it. - if (llvm::opt::Arg *inputArg = parsedArgs->getLastArg(OPT_machine)) { - StringRef arg = inputArg->getValue(); - llvm::COFF::MachineTypes type = stringToMachineType(arg); - if (type == llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN) { - diag << "error: unknown machine type: " << arg << "\n"; - return false; - } - ctx.setMachineType(type); - } else { - // If /machine option is missing, we need to take a look at - // the magic byte of the first object file to infer machine type. - std::vector filePaths; - for (auto arg : *parsedArgs) - if (arg->getOption().getID() == OPT_INPUT) - filePaths.push_back(arg->getValue()); - if (llvm::opt::Arg *arg = parsedArgs->getLastArg(OPT_DASH_DASH)) - filePaths.insert(filePaths.end(), arg->getValues().begin(), - arg->getValues().end()); - for (StringRef path : filePaths) { - llvm::COFF::MachineTypes type; - if (!getMachineType(path, type)) - continue; - if (type == llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN) - continue; - ctx.setMachineType(type); - break; - } - } - - // Handle /nodefaultlib:. The same option without argument is handled in - // the following for loop. - for (auto *arg : parsedArgs->filtered(OPT_nodefaultlib)) - ctx.addNoDefaultLib(arg->getValue()); - - // Handle /defaultlib. Argument of the option is added to the input file list - // unless it's blacklisted by /nodefaultlib. - std::vector defaultLibs; - for (auto *arg : parsedArgs->filtered(OPT_defaultlib)) - defaultLibs.push_back(arg->getValue()); - - // -alternatename:= - for (auto *arg : parsedArgs->filtered(OPT_alternatename)) { - StringRef weak, def; - if (!parseAlternateName(arg->getValue(), weak, def, diag)) - return false; - ctx.addAlternateName(weak, def); - } - - // Parse /base command line option. The argument for the parameter is in - // the form of "
[:]". - if (auto *arg = parsedArgs->getLastArg(OPT_base)) { - uint64_t addr, size; - // Size should be set to SizeOfImage field in the COFF header, and if - // it's smaller than the actual size, the linker should warn about that. - // Currently we just ignore the value of size parameter. - if (!parseMemoryOption(arg->getValue(), addr, size)) - return false; - ctx.setBaseAddress(addr); - } - - // Parse /dll command line option - if (parsedArgs->hasArg(OPT_dll)) { - ctx.setIsDll(true); - // Default base address of a DLL is 0x10000000. - if (!parsedArgs->hasArg(OPT_base)) - ctx.setBaseAddress(0x10000000); - } - - // Parse /stack command line option - if (auto *arg = parsedArgs->getLastArg(OPT_stack)) { - uint64_t reserve; - uint64_t commit = ctx.getStackCommit(); - if (!parseMemoryOption(arg->getValue(), reserve, commit)) - return false; - ctx.setStackReserve(reserve); - ctx.setStackCommit(commit); - } - - // Parse /heap command line option - if (auto *arg = parsedArgs->getLastArg(OPT_heap)) { - uint64_t reserve; - uint64_t commit = ctx.getHeapCommit(); - if (!parseMemoryOption(arg->getValue(), reserve, commit)) - return false; - ctx.setHeapReserve(reserve); - ctx.setHeapCommit(commit); - } - - if (auto *arg = parsedArgs->getLastArg(OPT_align)) { - uint32_t align; - StringRef val = arg->getValue(); - if (val.getAsInteger(10, align)) { - diag << "error: invalid value for /align: " << val << "\n"; - return false; - } - ctx.setSectionDefaultAlignment(align); - } - - if (auto *arg = parsedArgs->getLastArg(OPT_version)) { - uint32_t major, minor; - if (!parseVersion(arg->getValue(), major, minor)) - return false; - ctx.setImageVersion(PECOFFLinkingContext::Version(major, minor)); - } - - // Parse /merge:=. - for (auto *arg : parsedArgs->filtered(OPT_merge)) { - StringRef from, to; - std::tie(from, to) = StringRef(arg->getValue()).split('='); - if (from.empty() || to.empty()) { - diag << "error: malformed /merge option: " << arg->getValue() << "\n"; - return false; - } - if (!ctx.addSectionRenaming(diag, from, to)) - return false; - } - - // Parse /subsystem:[,[.]]. - if (auto *arg = parsedArgs->getLastArg(OPT_subsystem)) { - llvm::COFF::WindowsSubsystem subsystem; - llvm::Optional major, minor; - if (!parseSubsystem(arg->getValue(), subsystem, major, minor, diag)) - return false; - ctx.setSubsystem(subsystem); - if (major.hasValue()) - ctx.setMinOSVersion(PECOFFLinkingContext::Version(*major, *minor)); - } - - // Parse /section:name,[[!]{DEKPRSW}] - for (auto *arg : parsedArgs->filtered(OPT_section)) { - std::string section; - llvm::Optional flags, mask; - if (!parseSection(arg->getValue(), section, flags, mask)) { - diag << "Unknown argument for /section: " << arg->getValue() << "\n"; - return false; - } - if (flags.hasValue()) - ctx.setSectionSetMask(section, *flags); - if (mask.hasValue()) - ctx.setSectionClearMask(section, *mask); - } - - // Parse /manifest:EMBED[,ID=#]|NO. - if (auto *arg = parsedArgs->getLastArg(OPT_manifest_colon)) { - bool enable = true; - bool embed = false; - int id = 1; - if (!parseManifest(arg->getValue(), enable, embed, id)) { - diag << "Unknown argument for /manifest: " << arg->getValue() << "\n"; - return false; - } - ctx.setCreateManifest(enable); - ctx.setEmbedManifest(embed); - ctx.setManifestId(id); - } - - // Parse /manifestuac. - if (auto *arg = parsedArgs->getLastArg(OPT_manifestuac)) { - if (StringRef(arg->getValue()).equals_lower("no")) { - ctx.setManifestUAC(false); - } else { - llvm::Optional privilegeLevel; - llvm::Optional uiAccess; - if (!parseManifestUAC(arg->getValue(), privilegeLevel, uiAccess)) { - diag << "Unknown argument for /manifestuac: " << arg->getValue() - << "\n"; - return false; - } - if (privilegeLevel.hasValue()) - ctx.setManifestLevel(privilegeLevel.getValue()); - if (uiAccess.hasValue()) - ctx.setManifestUiAccess(uiAccess.getValue()); - } - } - - if (auto *arg = parsedArgs->getLastArg(OPT_manifestfile)) - ctx.setManifestOutputPath(ctx.allocate(arg->getValue())); - - // /manifestdependency: option. Note that the argument will be - // embedded to the manifest XML file with no error check, for link.exe - // compatibility. We do not gurantete that the resulting XML file is - // valid. - if (auto *arg = parsedArgs->getLastArg(OPT_manifestdependency)) - ctx.setManifestDependency(ctx.allocate(arg->getValue())); - - for (auto *arg : parsedArgs->filtered(OPT_failifmismatch)) - if (handleFailIfMismatchOption(arg->getValue(), failIfMismatchMap, diag)) - return false; - - if (auto *arg = parsedArgs->getLastArg(OPT_entry)) - ctx.setEntrySymbolName(ctx.allocate(arg->getValue())); - - for (auto *arg : parsedArgs->filtered(OPT_export)) { - PECOFFLinkingContext::ExportDesc desc; - if (!parseExport(arg->getValue(), desc)) { - diag << "Error: malformed /export option: " << arg->getValue() << "\n"; - return false; - } - - // Mangle the symbol name only if it is reading user-supplied command line - // arguments. Because the symbol name in the .drectve section is already - // mangled by the compiler, we shouldn't add a leading underscore in that - // case. It's odd that the command line option has different semantics in - // the .drectve section, but this behavior is needed for compatibility - // with MSVC's link.exe. - if (!isReadingDirectiveSection) - desc.name = ctx.decorateSymbol(desc.name); - ctx.addDllExport(desc); - } - - for (auto *arg : parsedArgs->filtered(OPT_deffile)) { - llvm::BumpPtrAllocator alloc; - std::vector dirs; - if (!parseDef(arg->getValue(), alloc, dirs)) { - diag << "Error: invalid module-definition file\n"; - return false; - } - for (moduledef::Directive *dir : dirs) { - if (auto *exp = dyn_cast(dir)) { - for (PECOFFLinkingContext::ExportDesc desc : exp->getExports()) { - desc.name = ctx.decorateSymbol(desc.name); - ctx.addDllExport(desc); - } - } else if (auto *hs = dyn_cast(dir)) { - ctx.setHeapReserve(hs->getReserve()); - ctx.setHeapCommit(hs->getCommit()); - } else if (auto *lib = dyn_cast(dir)) { - ctx.setIsDll(true); - ctx.setOutputPath(ctx.allocate(lib->getName())); - if (lib->getBaseAddress() && !ctx.getBaseAddress()) - ctx.setBaseAddress(lib->getBaseAddress()); - } else if (auto *name = dyn_cast(dir)) { - if (!name->getOutputPath().empty() && ctx.outputPath().empty()) - ctx.setOutputPath(ctx.allocate(name->getOutputPath())); - if (name->getBaseAddress() && ctx.getBaseAddress()) - ctx.setBaseAddress(name->getBaseAddress()); - } else if (auto *ver = dyn_cast(dir)) { - ctx.setImageVersion(PECOFFLinkingContext::Version( - ver->getMajorVersion(), ver->getMinorVersion())); - } else { - llvm::dbgs() << static_cast(dir->getKind()) << "\n"; - llvm_unreachable("Unknown module-definition directive.\n"); - } - } - } - - for (auto *arg : parsedArgs->filtered(OPT_libpath)) - ctx.appendInputSearchPath(ctx.allocate(arg->getValue())); - - for (auto *arg : parsedArgs->filtered(OPT_opt)) { - std::string val = StringRef(arg->getValue()).lower(); - if (val == "noref") { - ctx.setDeadStripping(false); - } else if (val != "ref" && val != "icf" && val != "noicf" && - val != "lbr" && val != "nolbr" && - !StringRef(val).startswith("icf=")) { - diag << "unknown option for /opt: " << val << "\n"; - return false; - } - } - - // LLD is not yet capable of creating a PDB file, so /debug does not have - // any effect. - // TODO: This should disable dead stripping. Currently we can't do that - // because removal of associative sections depends on dead stripping. - if (parsedArgs->hasArg(OPT_debug)) - ctx.setDebug(true); - - if (parsedArgs->hasArg(OPT_verbose)) - ctx.setLogInputFiles(true); - - // /force and /force:unresolved mean the same thing. We do not currently - // support /force:multiple. - if (parsedArgs->hasArg(OPT_force) || - parsedArgs->hasArg(OPT_force_unresolved)) { - ctx.setAllowRemainingUndefines(true); - } - - if (parsedArgs->hasArg(OPT_fixed)) { - // /fixed is not compatible with /dynamicbase. Check for it. - if (parsedArgs->hasArg(OPT_dynamicbase)) { - diag << "/dynamicbase must not be specified with /fixed\n"; - return false; - } - ctx.setBaseRelocationEnabled(false); - ctx.setDynamicBaseEnabled(false); - } - - // /swaprun:{cd,net} options set IMAGE_FILE_{REMOVABLE,NET}_RUN_FROM_SWAP - // bits in the COFF header, respectively. If one of the bits is on, the - // Windows loader will copy the entire file to swap area then execute it, - // so that the user can eject a CD or disconnect from the network. - if (parsedArgs->hasArg(OPT_swaprun_cd)) - ctx.setSwapRunFromCD(true); - - if (parsedArgs->hasArg(OPT_swaprun_net)) - ctx.setSwapRunFromNet(true); - - if (parsedArgs->hasArg(OPT_profile)) { - // /profile implies /opt:ref, /opt:noicf, /incremental:no and /fixed:no. - ctx.setDeadStripping(true); - ctx.setBaseRelocationEnabled(true); - ctx.setDynamicBaseEnabled(true); - } - - for (auto *arg : parsedArgs->filtered(OPT_implib)) - ctx.setOutputImportLibraryPath(arg->getValue()); - - for (auto *arg : parsedArgs->filtered(OPT_delayload)) { - ctx.addInitialUndefinedSymbol(ctx.getDelayLoadHelperName()); - ctx.addDelayLoadDLL(arg->getValue()); - } - - if (auto *arg = parsedArgs->getLastArg(OPT_stub)) { - ArrayRef contents; - if (!readFile(ctx, arg->getValue(), contents)) { - diag << "Failed to read DOS stub file " << arg->getValue() << "\n"; - return false; - } - ctx.setDosStub(contents); - } - - for (auto *arg : parsedArgs->filtered(OPT_incl)) - ctx.addInitialUndefinedSymbol(ctx.allocate(arg->getValue())); - - if (parsedArgs->hasArg(OPT_noentry)) - ctx.setHasEntry(false); - - if (parsedArgs->hasArg(OPT_nodefaultlib_all)) - ctx.setNoDefaultLibAll(true); - - if (auto *arg = parsedArgs->getLastArg(OPT_out)) - ctx.setOutputPath(ctx.allocate(arg->getValue())); - - if (auto *arg = parsedArgs->getLastArg(OPT_pdb)) - ctx.setPDBFilePath(arg->getValue()); - - if (auto *arg = parsedArgs->getLastArg(OPT_lldmoduledeffile)) - ctx.setModuleDefinitionFile(arg->getValue()); - - std::vector inputFiles; - for (auto *arg : parsedArgs->filtered(OPT_INPUT)) - inputFiles.push_back(ctx.allocate(arg->getValue())); - -#define BOOLEAN_FLAG(name, setter) \ - if (auto *arg = parsedArgs->getLastArg(OPT_##name, OPT_##name##_no)) \ - ctx.setter(arg->getOption().matches(OPT_##name)); - - BOOLEAN_FLAG(nxcompat, setNxCompat); - BOOLEAN_FLAG(largeaddressaware, setLargeAddressAware); - BOOLEAN_FLAG(allowbind, setAllowBind); - BOOLEAN_FLAG(allowisolation, setAllowIsolation); - BOOLEAN_FLAG(dynamicbase, setDynamicBaseEnabled); - BOOLEAN_FLAG(tsaware, setTerminalServerAware); - BOOLEAN_FLAG(highentropyva, setHighEntropyVA); - BOOLEAN_FLAG(safeseh, setSafeSEH); -#undef BOOLEAN_FLAG - - // Arguments after "--" are interpreted as filenames even if they - // start with a hypen or a slash. This is not compatible with link.exe - // but useful for us to test lld on Unix. - if (llvm::opt::Arg *dashdash = parsedArgs->getLastArg(OPT_DASH_DASH)) - for (const StringRef value : dashdash->getValues()) - inputFiles.push_back(value); - - // Compile Windows resource files to compiled resource file. - if (ctx.getCreateManifest() && ctx.getEmbedManifest() && - !isReadingDirectiveSection) { - std::string resFile; - if (!createManifestResourceFile(ctx, diag, resFile)) - return false; - inputFiles.push_back(ctx.allocate(resFile)); - } - - // A Windows Resource file is not an object file. It contains data, - // such as an icon image, and is not in COFF file format. If resource - // files are given, the linker merge them into one COFF file using - // CVTRES.EXE and then link the resulting file. - { - auto it = std::partition(inputFiles.begin(), inputFiles.end(), - isResoruceFile); - if (it != inputFiles.begin()) { - std::vector resFiles(inputFiles.begin(), it); - std::string resObj; - if (!convertResourceFiles(ctx, resFiles, resObj)) { - diag << "Failed to convert resource files\n"; - return false; - } - inputFiles = std::vector(it, inputFiles.end()); - inputFiles.push_back(ctx.allocate(resObj)); - ctx.registerTemporaryFile(resObj); - } - } - - // Prepare objects to add them to the list of input files. - for (StringRef path : inputFiles) { - path = ctx.allocate(path); - if (isLibraryFile(path)) { - addFiles(ctx, getLibraryPath(ctx, path), diag, libraries); - } else { - addFiles(ctx, getObjectPath(ctx, path), diag, files); - } - } - - // If dead-stripping is enabled, we need to add the entry symbol and - // symbols given by /include to the dead strip root set, so that it - // won't be removed from the output. - if (ctx.deadStrip()) - for (const StringRef symbolName : ctx.initialUndefinedSymbols()) - ctx.addDeadStripRoot(symbolName); - - // Add the libraries specified by /defaultlib unless they are already added - // nor blacklisted by /nodefaultlib. - if (!ctx.getNoDefaultLibAll()) - for (const StringRef path : defaultLibs) - if (!ctx.hasNoDefaultLib(path)) - addFiles(ctx, getLibraryPath(ctx, path.lower()), diag, libraries); - - if (files.empty() && !isReadingDirectiveSection) { - diag << "No input files\n"; - return false; - } - - // If /out option was not specified, the default output file name is - // constructed by replacing an extension of the first input file - // with ".exe". - if (ctx.outputPath().empty()) { - StringRef path = files[0]->path(); - ctx.setOutputPath(replaceExtension(ctx, path, ".exe")); - } - - // Add the input files to the linking context. - for (std::unique_ptr &file : files) { - if (isReadingDirectiveSection) { - File *f = file.get(); - ctx.getTaskGroup().spawn([f] { f->parse(); }); - } - ctx.getNodes().push_back(llvm::make_unique(std::move(file))); - } - - // Add the library group to the linking context. - if (!isReadingDirectiveSection) { - // Add a group-end marker. - ctx.getNodes().push_back(llvm::make_unique(0)); - } - - // Add the library files to the library group. - for (std::unique_ptr &file : libraries) { - if (!hasLibrary(ctx, file.get())) { - if (isReadingDirectiveSection) { - File *f = file.get(); - ctx.getTaskGroup().spawn([f] { f->parse(); }); - } - ctx.addLibraryFile(llvm::make_unique(std::move(file))); - } - } - - // Validate the combination of options used. - return ctx.validate(diag); -} - -} // namespace lld Index: lib/Driver/WinLinkModuleDef.cpp =================================================================== --- lib/Driver/WinLinkModuleDef.cpp +++ /dev/null @@ -1,295 +0,0 @@ -//===- lib/Driver/WinLinkModuleDef.cpp ------------------------------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// \brief Windows module definition file parser. -/// -//===----------------------------------------------------------------------===// - -#include "lld/Driver/WinLinkModuleDef.h" -#include "llvm/ADT/StringSwitch.h" - -namespace lld { -namespace moduledef { - -Token Lexer::lex() { - for (;;) { - _buffer = _buffer.trim(); - if (_buffer.empty() || _buffer[0] == '\0') - return Token(Kind::eof, _buffer); - - switch (_buffer[0]) { - case ';': { - size_t end = _buffer.find('\n'); - _buffer = (end == _buffer.npos) ? "" : _buffer.drop_front(end); - continue; - } - case '=': - _buffer = _buffer.drop_front(); - return Token(Kind::equal, "="); - case ',': - _buffer = _buffer.drop_front(); - return Token(Kind::comma, ","); - case '"': { - size_t end = _buffer.find('"', 1); - Token ret; - if (end == _buffer.npos) { - ret = Token(Kind::identifier, _buffer.substr(1, end)); - _buffer = ""; - } else { - ret = Token(Kind::identifier, _buffer.substr(1, end - 1)); - _buffer = _buffer.drop_front(end + 1); - } - return ret; - } - default: { - size_t end = _buffer.find_first_not_of( - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789_.*~+!@#$%^&*()/"); - StringRef word = _buffer.substr(0, end); - Kind kind = llvm::StringSwitch(word) - .Case("BASE", Kind::kw_base) - .Case("DATA", Kind::kw_data) - .Case("EXPORTS", Kind::kw_exports) - .Case("HEAPSIZE", Kind::kw_heapsize) - .Case("LIBRARY", Kind::kw_library) - .Case("NAME", Kind::kw_name) - .Case("NONAME", Kind::kw_noname) - .Case("PRIVATE", Kind::kw_private) - .Case("STACKSIZE", Kind::kw_stacksize) - .Case("VERSION", Kind::kw_version) - .Default(Kind::identifier); - _buffer = (end == _buffer.npos) ? "" : _buffer.drop_front(end); - return Token(kind, word); - } - } - } -} - -void Parser::consumeToken() { - if (_tokBuf.empty()) { - _tok = _lex.lex(); - return; - } - _tok = _tokBuf.back(); - _tokBuf.pop_back(); -} - -bool Parser::consumeTokenAsInt(uint64_t &result) { - consumeToken(); - if (_tok._kind != Kind::identifier) { - ungetToken(); - error(_tok, "Integer expected"); - return false; - } - if (_tok._range.getAsInteger(10, result)) { - error(_tok, "Integer expected"); - return false; - } - return true; -} - -bool Parser::expectAndConsume(Kind kind, Twine msg) { - consumeToken(); - if (_tok._kind != kind) { - error(_tok, msg); - return false; - } - return true; -} - -void Parser::ungetToken() { _tokBuf.push_back(_tok); } - -void Parser::error(const Token &tok, Twine msg) { - _lex.getSourceMgr().PrintMessage( - llvm::SMLoc::getFromPointer(tok._range.data()), llvm::SourceMgr::DK_Error, - msg); -} - -bool Parser::parse(std::vector &ret) { - for (;;) { - Directive *dir = nullptr; - if (!parseOne(dir)) - return false; - if (!dir) - return true; - ret.push_back(dir); - } -} - -bool Parser::parseOne(Directive *&ret) { - consumeToken(); - switch (_tok._kind) { - case Kind::eof: - return true; - case Kind::kw_exports: { - // EXPORTS - std::vector exports; - for (;;) { - PECOFFLinkingContext::ExportDesc desc; - if (!parseExport(desc)) - break; - exports.push_back(desc); - } - ret = new (_alloc) Exports(exports); - return true; - } - case Kind::kw_heapsize: { - // HEAPSIZE - uint64_t reserve, commit; - if (!parseMemorySize(reserve, commit)) - return false; - ret = new (_alloc) Heapsize(reserve, commit); - return true; - } - case Kind::kw_library: { - // LIBRARY - std::string name; - uint64_t baseaddr; - if (!parseName(name, baseaddr)) - return false; - if (!StringRef(name).endswith_lower(".dll")) - name.append(".dll"); - ret = new (_alloc) Library(name, baseaddr); - return true; - } - case Kind::kw_stacksize: { - // STACKSIZE - uint64_t reserve, commit; - if (!parseMemorySize(reserve, commit)) - return false; - ret = new (_alloc) Stacksize(reserve, commit); - return true; - } - case Kind::kw_name: { - // NAME - std::string outputPath; - uint64_t baseaddr; - if (!parseName(outputPath, baseaddr)) - return false; - ret = new (_alloc) Name(outputPath, baseaddr); - return true; - } - case Kind::kw_version: { - // VERSION - int major, minor; - if (!parseVersion(major, minor)) - return false; - ret = new (_alloc) Version(major, minor); - return true; - } - default: - error(_tok, Twine("Unknown directive: ") + _tok._range); - return false; - } -} - -bool Parser::parseExport(PECOFFLinkingContext::ExportDesc &result) { - consumeToken(); - if (_tok._kind != Kind::identifier) { - ungetToken(); - return false; - } - result.name = _tok._range; - - consumeToken(); - if (_tok._kind == Kind::equal) { - consumeToken(); - if (_tok._kind != Kind::identifier) - return false; - result.externalName = result.name; - result.name = _tok._range; - } else { - ungetToken(); - } - - for (;;) { - consumeToken(); - if (_tok._kind == Kind::identifier && _tok._range[0] == '@') { - _tok._range.drop_front().getAsInteger(10, result.ordinal); - consumeToken(); - if (_tok._kind == Kind::kw_noname) { - result.noname = true; - } else { - ungetToken(); - } - continue; - } - if (_tok._kind == Kind::kw_data) { - result.isData = true; - continue; - } - if (_tok._kind == Kind::kw_private) { - result.isPrivate = true; - continue; - } - ungetToken(); - return true; - } -} - -// HEAPSIZE/STACKSIZE reserve[,commit] -bool Parser::parseMemorySize(uint64_t &reserve, uint64_t &commit) { - if (!consumeTokenAsInt(reserve)) - return false; - - consumeToken(); - if (_tok._kind != Kind::comma) { - ungetToken(); - commit = 0; - return true; - } - - if (!consumeTokenAsInt(commit)) - return false; - return true; -} - -// NAME [outputPath] [BASE=address] -bool Parser::parseName(std::string &outputPath, uint64_t &baseaddr) { - consumeToken(); - if (_tok._kind == Kind::identifier) { - outputPath = _tok._range; - } else { - outputPath = ""; - ungetToken(); - return true; - } - consumeToken(); - if (_tok._kind == Kind::kw_base) { - if (!expectAndConsume(Kind::equal, "'=' expected")) - return false; - if (!consumeTokenAsInt(baseaddr)) - return false; - } else { - ungetToken(); - baseaddr = 0; - } - return true; -} - -// VERSION major[.minor] -bool Parser::parseVersion(int &major, int &minor) { - consumeToken(); - if (_tok._kind != Kind::identifier) - return false; - StringRef v1, v2; - std::tie(v1, v2) = _tok._range.split('.'); - if (v1.getAsInteger(10, major)) - return false; - if (v2.empty()) { - minor = 0; - } else if (v2.getAsInteger(10, minor)) { - return false; - } - return true; -} - -} // moddef -} // namespace lld Index: lib/Driver/WinLinkOptions.td =================================================================== --- lib/Driver/WinLinkOptions.td +++ /dev/null @@ -1,120 +0,0 @@ -include "llvm/Option/OptParser.td" - -// link.exe accepts options starting with either a dash or a slash. - -// Flag that takes no arguments. -class F : Flag<["/", "-", "-?"], name>; - -// Flag that takes one argument after ":". -class P : - Joined<["/", "-", "-?"], name#":">, HelpText; - -// Boolean flag suffixed by ":no". -multiclass B { - def "" : F; - def _no : F, HelpText; -} - -def alternatename : P<"alternatename", "Define weak alias">; -def base : P<"base", "Base address of the program">; -def defaultlib : P<"defaultlib", "Add the library to the list of input files">; -def nodefaultlib : P<"nodefaultlib", "Remove a default library">; -def disallowlib : Joined<["/", "-", "-?"], "disallowlib:">, Alias; -def entry : P<"entry", "Name of entry point symbol">; -// No help text because /failifmismatch is not intended to be used by the user. -def export : P<"export", "Export a function">; -def failifmismatch : P<"failifmismatch", "">; -def heap : P<"heap", "Size of the heap">; -def align : P<"align", "Section alignment">; -def libpath : P<"libpath", "Additional library search path">; -def mllvm : P<"mllvm", "Options to pass to LLVM">; -def out : P<"out", "Path to file to write output">; -def stack : P<"stack", "Size of the stack">; -def machine : P<"machine", "Specify target platform">; -def version : P<"version", "Specify a version number in the PE header">; -def merge : P<"merge", "Combine sections">; -def section : P<"section", "Specify section attributes">; -def subsystem : P<"subsystem", "Specify subsystem">; -def stub : P<"stub", "Specify DOS stub file">; -def opt : P<"opt", "Control optimizations">; -def implib : P<"implib", "Import library name">; -def delayload : P<"delayload", "Delay loaded DLL name">; -def pdb : P<"pdb", "PDB file path">; - -def manifest : F<"manifest">; -def manifest_colon : P<"manifest", "Create manifest file">; -def manifestuac : P<"manifestuac", "User access control">; -def manifestfile : P<"manifestfile", "Manifest file path">; -def manifestdependency : P<"manifestdependency", - "Attributes for in manifest file">; - -// We cannot use multiclass P because class name "incl" is different -// from its command line option name. We do this because "include" is -// a reserved keyword in tablegen. -def incl : Joined<["/", "-"], "include:">, - HelpText<"Force symbol to be added to symbol table as undefined one">; - -// "def" is also a keyword. -def deffile : Joined<["/", "-"], "def:">, - HelpText<"Use module-definition file">; - -def nodefaultlib_all : F<"nodefaultlib">; -def noentry : F<"noentry">; -def dll : F<"dll">; -def verbose : F<"verbose">; -def debug : F<"debug">; -def swaprun_cd : F<"swaprun:cd">; -def swaprun_net : F<"swaprun:net">; -def profile : F<"profile">; - -def force : F<"force">, - HelpText<"Allow undefined symbols when creating executables">; -def force_unresolved : F<"force:unresolved">; - -defm nxcompat : B<"nxcompat", "Disable data execution provention">; -defm largeaddressaware : B<"largeaddressaware", "Disable large addresses">; -defm allowbind: B<"allowbind", "Disable DLL binding">; -defm fixed : B<"fixed", "Enable base relocations">; -defm tsaware : B<"tsaware", "Create non-Terminal Server aware executable">; -defm allowisolation : B<"allowisolation", "Set NO_ISOLATION bit">; -defm dynamicbase : B<"dynamicbase", - "Disable address space layout randomization">; -defm safeseh : B<"safeseh", "Produce an image with Safe Exception Handler">; -defm highentropyva : B<"highentropyva", "Set HIGH_ENTROPY_VA bit">; - -def help : F<"help">; -def help_q : Flag<["/?", "-?"], "">, Alias; - -def DASH_DASH : Option<["--"], "", KIND_REMAINING_ARGS>; - -// Flag for debug -def lldmoduledeffile : Joined<["/", "-"], "lldmoduledeffile:">; - -//============================================================================== -// The flags below do nothing. They are defined only for link.exe compatibility. -//============================================================================== - -class QF : Joined<["/", "-", "-?"], name#":">; - -multiclass QB { - def "" : F; - def _no : F; -} - -def functionpadmin : F<"functionpadmin">; -def ignoreidl : F<"ignoreidl">; -def incremental : F<"incremental">; -def no_incremental : F<"incremental:no">; -def nologo : F<"nologo">; - -def delay : QF<"delay">; -def errorreport : QF<"errorreport">; -def idlout : QF<"idlout">; -def ignore : QF<"ignore">; -def maxilksize : QF<"maxilksize">; -def pdbaltpath : QF<"pdbaltpath">; -def tlbid : QF<"tlbid">; -def tlbout : QF<"tlbout">; -def verbose_all : QF<"verbose">; - -defm wx : QB<"wx">; Index: lib/ReaderWriter/CMakeLists.txt =================================================================== --- lib/ReaderWriter/CMakeLists.txt +++ lib/ReaderWriter/CMakeLists.txt @@ -1,6 +1,5 @@ add_subdirectory(ELF) add_subdirectory(MachO) -add_subdirectory(PECOFF) add_subdirectory(YAML) if (MSVC) Index: lib/ReaderWriter/PECOFF/Atoms.h =================================================================== --- lib/ReaderWriter/PECOFF/Atoms.h +++ /dev/null @@ -1,312 +0,0 @@ -//===- lib/ReaderWriter/PECOFF/Atoms.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_PE_COFF_ATOMS_H -#define LLD_READER_WRITER_PE_COFF_ATOMS_H - -#include "lld/Core/File.h" -#include "lld/Core/Simple.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/Object/COFF.h" -#include - -namespace lld { -namespace pecoff { -class COFFDefinedAtom; - -class COFFUndefinedAtom : public UndefinedAtom { -public: - COFFUndefinedAtom(const File &file, StringRef name, - const UndefinedAtom *fallback = nullptr) - : _owningFile(file), _name(name), _fallback(fallback) {} - - const File &file() const override { return _owningFile; } - StringRef name() const override { return _name; } - CanBeNull canBeNull() const override { return CanBeNull::canBeNullNever; } - const UndefinedAtom *fallback() const override { return _fallback; } - -private: - const File &_owningFile; - StringRef _name; - const UndefinedAtom *_fallback; -}; - -/// The base class of all COFF defined atoms. A derived class of -/// COFFBaseDefinedAtom may represent atoms read from a file or atoms created -/// by the linker. An example of the latter case is the jump table for symbols -/// in a DLL. -class COFFBaseDefinedAtom : public DefinedAtom { -public: - enum class Kind { - File, - Internal - }; - - const File &file() const override { return _file; } - StringRef name() const override { return _name; } - Interposable interposable() const override { return interposeNo; } - Merge merge() const override { return mergeNo; } - Alignment alignment() const override { return 1; } - StringRef customSectionName() const override { return ""; } - DeadStripKind deadStrip() const override { return deadStripNormal; } - - Kind getKind() const { return _kind; } - - void addReference(std::unique_ptr reference) { - _references.push_back(std::move(reference)); - } - - reference_iterator begin() const override { - return reference_iterator(*this, reinterpret_cast(0)); - } - - reference_iterator end() const override { - return reference_iterator( - *this, reinterpret_cast(_references.size())); - } - -protected: - COFFBaseDefinedAtom(const File &file, StringRef name, Kind kind) - : _file(file), _name(name), _kind(kind) {} - -private: - const Reference *derefIterator(const void *iter) const override { - size_t index = reinterpret_cast(iter); - return _references[index].get(); - } - - void incrementIterator(const void *&iter) const override { - size_t index = reinterpret_cast(iter); - iter = reinterpret_cast(index + 1); - } - - const File &_file; - StringRef _name; - Kind _kind; - std::vector> _references; -}; - -/// This is the root class of the atom read from a file. This class have two -/// subclasses; one for the regular atom and another for the BSS atom. -class COFFDefinedFileAtom : public COFFBaseDefinedAtom { -public: - COFFDefinedFileAtom(const File &file, StringRef name, StringRef sectionName, - uint64_t sectionSize, Scope scope, - ContentType contentType, ContentPermissions perms, - uint64_t ordinal) - : COFFBaseDefinedAtom(file, name, Kind::File), _sectionName(sectionName), - _sectionSize(sectionSize), _scope(scope), _contentType(contentType), - _permissions(perms), _ordinal(ordinal), _alignment(1) {} - - static bool classof(const COFFBaseDefinedAtom *atom) { - return atom->getKind() == Kind::File; - } - - void setAlignment(Alignment val) { _alignment = val; } - SectionChoice sectionChoice() const override { return sectionCustomRequired; } - StringRef customSectionName() const override { return _sectionName; } - uint64_t sectionSize() const override { return _sectionSize; } - Scope scope() const override { return _scope; } - ContentType contentType() const override { return _contentType; } - ContentPermissions permissions() const override { return _permissions; } - uint64_t ordinal() const override { return _ordinal; } - Alignment alignment() const override { return _alignment; } - - void addAssociate(const DefinedAtom *other) { - auto *ref = new SimpleReference(Reference::KindNamespace::all, - Reference::KindArch::all, - lld::Reference::kindAssociate, 0, other, 0); - addReference(std::unique_ptr(ref)); - } - -private: - StringRef _sectionName; - uint64_t _sectionSize; - Scope _scope; - ContentType _contentType; - ContentPermissions _permissions; - uint64_t _ordinal; - Alignment _alignment; - std::vector> _references; -}; - -// A COFFDefinedAtom represents an atom read from a file and has contents. -class COFFDefinedAtom : public COFFDefinedFileAtom { -public: - COFFDefinedAtom(const File &file, StringRef name, StringRef sectionName, - uint64_t sectionSize, Scope scope, ContentType type, - bool isComdat, ContentPermissions perms, Merge merge, - ArrayRef data, uint64_t ordinal) - : COFFDefinedFileAtom(file, name, sectionName, sectionSize, - scope, type, perms, ordinal), - _isComdat(isComdat), _merge(merge), _dataref(data) {} - - Merge merge() const override { return _merge; } - uint64_t size() const override { return _dataref.size(); } - ArrayRef rawContent() const override { return _dataref; } - - DeadStripKind deadStrip() const override { - // Only COMDAT symbols would be dead-stripped. - return _isComdat ? deadStripNormal : deadStripNever; - } - -private: - bool _isComdat; - Merge _merge; - ArrayRef _dataref; -}; - -// A COFFDefinedAtom represents an atom for BSS section. -class COFFBSSAtom : public COFFDefinedFileAtom { -public: - COFFBSSAtom(const File &file, StringRef name, Scope scope, - ContentPermissions perms, Merge merge, uint32_t size, - uint64_t ordinal) - : COFFDefinedFileAtom(file, name, ".bss", 0, scope, typeZeroFill, - perms, ordinal), - _merge(merge), _size(size) {} - - Merge merge() const override { return _merge; } - uint64_t size() const override { return _size; } - ArrayRef rawContent() const override { return _contents; } - -private: - Merge _merge; - uint32_t _size; - std::vector _contents; -}; - -/// A COFFLinkerInternalAtom represents a defined atom created by the linker, -/// not read from file. -class COFFLinkerInternalAtom : public COFFBaseDefinedAtom { -public: - SectionChoice sectionChoice() const override { return sectionBasedOnContent; } - uint64_t ordinal() const override { return _ordinal; } - Scope scope() const override { return scopeGlobal; } - Alignment alignment() const override { return 1; } - uint64_t size() const override { return _data.size(); } - ArrayRef rawContent() const override { return _data; } - -protected: - COFFLinkerInternalAtom(const File &file, uint64_t ordinal, - std::vector data, StringRef symbolName = "") - : COFFBaseDefinedAtom(file, symbolName, Kind::Internal), - _ordinal(ordinal), _data(std::move(data)) {} - -private: - uint64_t _ordinal; - std::vector _data; -}; - -class COFFStringAtom : public COFFLinkerInternalAtom { -public: - COFFStringAtom(const File &file, uint64_t ordinal, StringRef sectionName, - StringRef contents) - : COFFLinkerInternalAtom(file, ordinal, stringRefToVector(contents)), - _sectionName(sectionName) {} - - SectionChoice sectionChoice() const override { return sectionCustomRequired; } - StringRef customSectionName() const override { return _sectionName; } - ContentType contentType() const override { return typeData; } - ContentPermissions permissions() const override { return permR__; } - -private: - StringRef _sectionName; - - std::vector stringRefToVector(StringRef name) const { - std::vector ret(name.size() + 1); - memcpy(&ret[0], name.data(), name.size()); - ret[name.size()] = 0; - return ret; - } -}; - -// A COFFSharedLibraryAtom represents a symbol for data in an import library. A -// reference to a COFFSharedLibraryAtom will be transformed to a real reference -// to an import address table entry in Idata pass. -class COFFSharedLibraryAtom : public SharedLibraryAtom { -public: - COFFSharedLibraryAtom(const File &file, uint16_t hint, StringRef symbolName, - StringRef importName, StringRef dllName) - : _file(file), _hint(hint), _mangledName(addImpPrefix(symbolName)), - _importName(importName), _dllName(dllName), _importTableEntry(nullptr) { - } - - const File &file() const override { return _file; } - uint16_t hint() const { return _hint; } - - /// Returns the symbol name to be used by the core linker. - StringRef name() const override { return _mangledName; } - - /// Returns the symbol name to be used in the import description table in the - /// COFF header. - virtual StringRef importName() const { return _importName; } - - StringRef loadName() const override { return _dllName; } - bool canBeNullAtRuntime() const override { return false; } - Type type() const override { return Type::Unknown; } - uint64_t size() const override { return 0; } - - void setImportTableEntry(const DefinedAtom *atom) { - _importTableEntry = atom; - } - - const DefinedAtom *getImportTableEntry() const { return _importTableEntry; } - -private: - /// Mangle the symbol name by adding "__imp_" prefix. See the file comment of - /// ReaderImportHeader.cpp for details about the prefix. - std::string addImpPrefix(StringRef symbolName) { - std::string ret("__imp_"); - ret.append(symbolName); - return ret; - } - - const File &_file; - uint16_t _hint; - std::string _mangledName; - std::string _importName; - StringRef _dllName; - const DefinedAtom *_importTableEntry; -}; - -// An instance of this class represents "input file" for atoms created in a -// pass. Atoms need to be associated to an input file even if it's not read from -// a file, so we use this class for that. -class VirtualFile : public SimpleFile { -public: - VirtualFile(const LinkingContext &ctx) - : SimpleFile(""), _nextOrdinal(0) { - setOrdinal(ctx.getNextOrdinalAndIncrement()); - } - - uint64_t getNextOrdinal() { return _nextOrdinal++; } - -private: - uint64_t _nextOrdinal; -}; - -//===----------------------------------------------------------------------===// -// -// Utility functions to handle layout edges. -// -//===----------------------------------------------------------------------===// - -template -void addLayoutEdge(T *a, U *b, uint32_t which) { - auto ref = new SimpleReference(Reference::KindNamespace::all, - Reference::KindArch::all, - which, 0, b, 0); - a->addReference(std::unique_ptr(ref)); -} - -} // namespace pecoff -} // namespace lld - -#endif Index: lib/ReaderWriter/PECOFF/CMakeLists.txt =================================================================== --- lib/ReaderWriter/PECOFF/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -add_llvm_library(lldPECOFF - EdataPass.cpp - IdataPass.cpp - LinkerGeneratedSymbolFile.cpp - LoadConfigPass.cpp - PECOFFLinkingContext.cpp - Pass.cpp - ReaderCOFF.cpp - ReaderImportHeader.cpp - WriterImportLibrary.cpp - WriterPECOFF.cpp - LINK_LIBS - lldCore - LLVMObject - LLVMSupport - ) Index: lib/ReaderWriter/PECOFF/EdataPass.h =================================================================== --- lib/ReaderWriter/PECOFF/EdataPass.h +++ /dev/null @@ -1,99 +0,0 @@ -//===- lib/ReaderWriter/PECOFF/EdataPass.h --------------------------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file \brief This linker pass creates atoms for the DLL export -/// information. The defined atoms constructed in this pass will go into .edata -/// section. -/// -/// For the details of the .edata section format, see Microsoft PE/COFF -/// Specification section 5.3, The .edata Section. -/// -//===----------------------------------------------------------------------===// - -#ifndef LLD_READER_WRITER_PE_COFF_EDATA_PASS_H -#define LLD_READER_WRITER_PE_COFF_EDATA_PASS_H - -#include "Atoms.h" -#include "lld/Core/File.h" -#include "lld/Core/Pass.h" -#include "lld/Core/Simple.h" -#include "lld/ReaderWriter/PECOFFLinkingContext.h" -#include "llvm/Support/COFF.h" -#include - -using llvm::COFF::ImportDirectoryTableEntry; - -namespace lld { -namespace pecoff { -namespace edata { - -struct TableEntry { - TableEntry(StringRef exp, int ord, const DefinedAtom *a, bool n) - : exportName(exp), ordinal(ord), atom(a), noname(n) {} - std::string exportName; - int ordinal; - const DefinedAtom *atom; - bool noname; -}; - -/// The root class of all edata atoms. -class EdataAtom : public COFFLinkerInternalAtom { -public: - EdataAtom(VirtualFile &file, size_t size) - : COFFLinkerInternalAtom(file, file.getNextOrdinal(), - std::vector(size)) {} - - SectionChoice sectionChoice() const override { return sectionCustomRequired; } - StringRef customSectionName() const override { return ".edata"; } - ContentType contentType() const override { return typeData; } - ContentPermissions permissions() const override { return permR__; } - - template T *getContents() const { - return (T *)const_cast(rawContent().data()); - } -}; - -} // namespace edata - -class EdataPass : public lld::Pass { -public: - EdataPass(PECOFFLinkingContext &ctx) - : _ctx(ctx), _file(ctx), _is64(ctx.is64Bit()), _stringOrdinal(1024) {} - - std::error_code perform(SimpleFile &file) override; - -private: - edata::EdataAtom * - createExportDirectoryTable(const std::vector &namedEntries, - int ordinalBase, int maxOrdinal); - - edata::EdataAtom * - createAddressTable(const std::vector &entries, - int ordinalBase, int maxOrdinal); - - edata::EdataAtom * - createNamePointerTable(const PECOFFLinkingContext &ctx, - const std::vector &entries, - SimpleFile *file); - - edata::EdataAtom * - createOrdinalTable(const std::vector &entries, - int ordinalBase); - - PECOFFLinkingContext &_ctx; - VirtualFile _file; - bool _is64; - int _stringOrdinal; - mutable llvm::BumpPtrAllocator _alloc; -}; - -} // namespace pecoff -} // namespace lld - -#endif Index: lib/ReaderWriter/PECOFF/EdataPass.cpp =================================================================== --- lib/ReaderWriter/PECOFF/EdataPass.cpp +++ /dev/null @@ -1,229 +0,0 @@ -//===- lib/ReaderWriter/PECOFF/EdataPass.cpp ------------------------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "Pass.h" -#include "EdataPass.h" -#include "lld/Core/File.h" -#include "lld/Core/Pass.h" -#include "lld/Core/Simple.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/Path.h" -#include -#include -#include - -using lld::pecoff::edata::EdataAtom; -using lld::pecoff::edata::TableEntry; -using llvm::object::export_address_table_entry; -using llvm::object::export_directory_table_entry; - -namespace lld { -namespace pecoff { - -typedef PECOFFLinkingContext::ExportDesc ExportDesc; - -// dedupExports removes duplicate export entries. If two exports are -// referring the same symbol, they are considered duplicates. -// This could happen if the same symbol name is specified as an argument -// to /export more than once, or an unmangled and mangled name of the -// same symbol are given to /export. In the latter case, we choose -// unmangled (shorter) name. -static void dedupExports(PECOFFLinkingContext &ctx) { - std::vector &exports = ctx.getDllExports(); - // Pass 1: find duplicate entries - std::set dup; - std::map map; - for (ExportDesc &exp : exports) { - if (!exp.externalName.empty()) - continue; - StringRef symbol = exp.getRealName(); - auto it = map.find(symbol); - if (it == map.end()) { - map[symbol] = &exp; - } else if (symbol.size() < it->second->getRealName().size()) { - map[symbol] = &exp; - dup.insert(it->second); - } else { - dup.insert(&exp); - } - } - // Pass 2: remove duplicate entries - auto pred = [&](const ExportDesc &exp) { - return dup.count(&exp) == 1; - }; - exports.erase(std::remove_if(exports.begin(), exports.end(), pred), - exports.end()); -} - -static void assignOrdinals(PECOFFLinkingContext &ctx) { - std::vector &exports = ctx.getDllExports(); - int maxOrdinal = -1; - for (ExportDesc &desc : exports) - maxOrdinal = std::max(maxOrdinal, desc.ordinal); - - std::sort(exports.begin(), exports.end(), - [](const ExportDesc &a, const ExportDesc &b) { - return a.getExternalName().compare(b.getExternalName()) < 0; - }); - - int nextOrdinal = (maxOrdinal == -1) ? 1 : (maxOrdinal + 1); - for (ExportDesc &desc : exports) - if (desc.ordinal == -1) - desc.ordinal = nextOrdinal++; -} - -static bool getExportedAtoms(PECOFFLinkingContext &ctx, const SimpleFile &file, - std::vector &ret) { - std::map definedAtoms; - for (const DefinedAtom *atom : file.defined()) - definedAtoms[atom->name()] = atom; - - for (PECOFFLinkingContext::ExportDesc &desc : ctx.getDllExports()) { - auto it = definedAtoms.find(desc.getRealName()); - if (it == definedAtoms.end()) { - llvm::errs() << "Symbol <" << desc.name - << "> is exported but not defined.\n"; - return false; - } - const DefinedAtom *atom = it->second; - - // One can export a symbol with a different name than the symbol - // name used in DLL. If such name is specified, use it in the - // .edata section. - ret.push_back(TableEntry(ctx.undecorateSymbol(desc.getExternalName()), - desc.ordinal, atom, desc.noname)); - } - std::sort(ret.begin(), ret.end(), - [](const TableEntry &a, const TableEntry &b) { - return a.exportName.compare(b.exportName) < 0; - }); - - return true; -} - -static std::pair getOrdinalBase(std::vector &entries) { - int ordinalBase = INT_MAX; - int maxOrdinal = -1; - for (TableEntry &e : entries) { - ordinalBase = std::min(ordinalBase, e.ordinal); - maxOrdinal = std::max(maxOrdinal, e.ordinal); - } - return std::pair(ordinalBase, maxOrdinal); -} - -edata::EdataAtom * -EdataPass::createAddressTable(const std::vector &entries, - int ordinalBase, int maxOrdinal) { - EdataAtom *addressTable = - new (_alloc) EdataAtom(_file, sizeof(export_address_table_entry) * - (maxOrdinal - ordinalBase + 1)); - - for (const TableEntry &e : entries) { - int index = e.ordinal - ordinalBase; - size_t offset = index * sizeof(export_address_table_entry); - addDir32NBReloc(addressTable, e.atom, _ctx.getMachineType(), offset); - } - return addressTable; -} - -edata::EdataAtom * -EdataPass::createNamePointerTable(const PECOFFLinkingContext &ctx, - const std::vector &entries, - SimpleFile *file) { - EdataAtom *table = - new (_alloc) EdataAtom(_file, sizeof(uint32_t) * entries.size()); - - size_t offset = 0; - for (const TableEntry &e : entries) { - auto *stringAtom = new (_alloc) COFFStringAtom( - _file, _stringOrdinal++, ".edata", e.exportName); - file->addAtom(*stringAtom); - addDir32NBReloc(table, stringAtom, _ctx.getMachineType(), offset); - offset += sizeof(uint32_t); - } - return table; -} - -edata::EdataAtom *EdataPass::createExportDirectoryTable( - const std::vector &namedEntries, int ordinalBase, - int maxOrdinal) { - EdataAtom *ret = - new (_alloc) EdataAtom(_file, sizeof(export_directory_table_entry)); - auto *data = ret->getContents(); - data->TimeDateStamp = time(nullptr); - data->OrdinalBase = ordinalBase; - data->AddressTableEntries = maxOrdinal - ordinalBase + 1; - data->NumberOfNamePointers = namedEntries.size(); - return ret; -} - -edata::EdataAtom * -EdataPass::createOrdinalTable(const std::vector &entries, - int ordinalBase) { - EdataAtom *ret = - new (_alloc) EdataAtom(_file, sizeof(uint16_t) * entries.size()); - uint16_t *data = ret->getContents(); - int i = 0; - for (const TableEntry &e : entries) - data[i++] = e.ordinal - ordinalBase; - return ret; -} - -std::error_code EdataPass::perform(SimpleFile &file) { - dedupExports(_ctx); - assignOrdinals(_ctx); - - std::vector entries; - if (!getExportedAtoms(_ctx, file, entries)) - return std::error_code(); - if (entries.empty()) - return std::error_code(); - - int ordinalBase, maxOrdinal; - std::tie(ordinalBase, maxOrdinal) = getOrdinalBase(entries); - - std::vector namedEntries; - for (TableEntry &e : entries) - if (!e.noname) - namedEntries.push_back(e); - - EdataAtom *table = - createExportDirectoryTable(namedEntries, ordinalBase, maxOrdinal); - file.addAtom(*table); - - COFFStringAtom *dllName = - new (_alloc) COFFStringAtom(_file, _stringOrdinal++, ".edata", - llvm::sys::path::filename(_ctx.outputPath())); - file.addAtom(*dllName); - addDir32NBReloc(table, dllName, _ctx.getMachineType(), - offsetof(export_directory_table_entry, NameRVA)); - - EdataAtom *addressTable = - createAddressTable(entries, ordinalBase, maxOrdinal); - file.addAtom(*addressTable); - addDir32NBReloc( - table, addressTable, _ctx.getMachineType(), - offsetof(export_directory_table_entry, ExportAddressTableRVA)); - - EdataAtom *namePointerTable = - createNamePointerTable(_ctx, namedEntries, &file); - file.addAtom(*namePointerTable); - addDir32NBReloc(table, namePointerTable, _ctx.getMachineType(), - offsetof(export_directory_table_entry, NamePointerRVA)); - - EdataAtom *ordinalTable = createOrdinalTable(namedEntries, ordinalBase); - file.addAtom(*ordinalTable); - addDir32NBReloc(table, ordinalTable, _ctx.getMachineType(), - offsetof(export_directory_table_entry, OrdinalTableRVA)); - - return std::error_code(); -} - -} // namespace pecoff -} // namespace lld Index: lib/ReaderWriter/PECOFF/IdataPass.h =================================================================== --- lib/ReaderWriter/PECOFF/IdataPass.h +++ /dev/null @@ -1,218 +0,0 @@ -//===- lib/ReaderWriter/PECOFF/IdataPass.h---------------------------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file \brief This linker pass creates atoms for the DLL import -/// information. The defined atoms constructed in this pass will go into .idata -/// section, unless .idata section is merged with other section such as .data. -/// -/// For the details of the .idata section format, see Microsoft PE/COFF -/// Specification section 5.4, The .idata Section. -/// -//===----------------------------------------------------------------------===// - -#ifndef LLD_READER_WRITER_PE_COFF_IDATA_PASS_H -#define LLD_READER_WRITER_PE_COFF_IDATA_PASS_H - -#include "Atoms.h" -#include "lld/Core/File.h" -#include "lld/Core/Pass.h" -#include "lld/Core/Simple.h" -#include "lld/ReaderWriter/PECOFFLinkingContext.h" -#include "llvm/Support/COFF.h" -#include -#include - -using llvm::COFF::ImportDirectoryTableEntry; - -namespace lld { -namespace pecoff { -namespace idata { - -class DLLNameAtom; -class HintNameAtom; -class ImportTableEntryAtom; - -// A state object of this pass. -struct IdataContext { - IdataContext(SimpleFile &f, VirtualFile &g, const PECOFFLinkingContext &c) - : file(f), dummyFile(g), ctx(c) {} - SimpleFile &file; - VirtualFile &dummyFile; - const PECOFFLinkingContext &ctx; -}; - -/// The root class of all idata atoms. -class IdataAtom : public COFFLinkerInternalAtom { -public: - SectionChoice sectionChoice() const override { return sectionCustomRequired; } - StringRef customSectionName() const override { return ".idata"; } - ContentType contentType() const override { return typeData; } - ContentPermissions permissions() const override { return permR__; } - -protected: - IdataAtom(IdataContext &context, std::vector data); -}; - -/// A HintNameAtom represents a symbol that will be imported from a DLL at -/// runtime. It consists with an optional hint, which is a small integer, and a -/// symbol name. -/// -/// A hint is an index of the export pointer table in a DLL. If the import -/// library and DLL is in sync (i.e., ".lib" and ".dll" is for the same version -/// or the symbol ordinal is maintained by hand with ".exp" file), the PE/COFF -/// loader can find the symbol quickly. -class HintNameAtom : public IdataAtom { -public: - HintNameAtom(IdataContext &context, uint16_t hint, StringRef importName); - - StringRef getContentString() { return _importName; } - -private: - std::vector assembleRawContent(uint16_t hint, StringRef importName); - StringRef _importName; -}; - -class ImportTableEntryAtom : public IdataAtom { -public: - ImportTableEntryAtom(IdataContext &ctx, uint64_t contents, - StringRef sectionName) - : IdataAtom(ctx, assembleRawContent(contents, ctx.ctx.is64Bit())), - _sectionName(sectionName) {} - - StringRef customSectionName() const override { - return _sectionName; - } - -private: - std::vector assembleRawContent(uint64_t contents, bool is64); - StringRef _sectionName; -}; - -/// An ImportDirectoryAtom includes information to load a DLL, including a DLL -/// name, symbols that will be resolved from the DLL, and the import address -/// table that are overwritten by the loader with the pointers to the referenced -/// items. The executable has one ImportDirectoryAtom per one imported DLL. -class ImportDirectoryAtom : public IdataAtom { -public: - ImportDirectoryAtom(IdataContext &context, StringRef loadName, - const std::vector &sharedAtoms) - : IdataAtom(context, std::vector(20, 0)) { - addRelocations(context, loadName, sharedAtoms); - } - - StringRef customSectionName() const override { return ".idata.d"; } - -private: - void addRelocations(IdataContext &context, StringRef loadName, - const std::vector &sharedAtoms); - - mutable llvm::BumpPtrAllocator _alloc; -}; - -/// The last NULL entry in the import directory. -class NullImportDirectoryAtom : public IdataAtom { -public: - explicit NullImportDirectoryAtom(IdataContext &context) - : IdataAtom(context, std::vector(20, 0)) {} - - StringRef customSectionName() const override { return ".idata.d"; } -}; - -/// The class for the the delay-load import table. -class DelayImportDirectoryAtom : public IdataAtom { -public: - DelayImportDirectoryAtom( - IdataContext &context, StringRef loadName, - const std::vector &sharedAtoms) - : IdataAtom(context, createContent()) { - addRelocations(context, loadName, sharedAtoms); - } - - StringRef customSectionName() const override { return ".didat.d"; } - -private: - std::vector createContent(); - void addRelocations(IdataContext &context, StringRef loadName, - const std::vector &sharedAtoms); - - mutable llvm::BumpPtrAllocator _alloc; -}; - -/// Terminator of the delay-load import table. The content of this atom is all -/// zero. -class DelayNullImportDirectoryAtom : public IdataAtom { -public: - explicit DelayNullImportDirectoryAtom(IdataContext &context) - : IdataAtom(context, createContent()) {} - StringRef customSectionName() const override { return ".didat.d"; } - -private: - std::vector createContent() const { - return std::vector( - sizeof(llvm::object::delay_import_directory_table_entry), 0); - } -}; - -class DelayImportAddressAtom : public IdataAtom { -public: - explicit DelayImportAddressAtom(IdataContext &context) - : IdataAtom(context, createContent(context.ctx)), - _align(context.ctx.is64Bit() ? 8 : 4) {} - StringRef customSectionName() const override { return ".data"; } - ContentPermissions permissions() const override { return permRW_; } - Alignment alignment() const override { return _align; } - -private: - std::vector createContent(const PECOFFLinkingContext &ctx) const { - return std::vector(ctx.is64Bit() ? 8 : 4, 0); - } - - Alignment _align; -}; - -// DelayLoaderAtom contains a wrapper function for __delayLoadHelper2. -class DelayLoaderAtom : public IdataAtom { -public: - DelayLoaderAtom(IdataContext &context, const Atom *impAtom, - const Atom *descAtom, const Atom *delayLoadHelperAtom); - StringRef customSectionName() const override { return ".text"; } - ContentPermissions permissions() const override { return permR_X; } - Alignment alignment() const override { return 1; } - -private: - std::vector createContent(MachineTypes machine) const; -}; - -} // namespace idata - -class IdataPass : public lld::Pass { -public: - IdataPass(const PECOFFLinkingContext &ctx) : _dummyFile(ctx), _ctx(ctx) {} - - std::error_code perform(SimpleFile &file) override; - -private: - std::map> - groupByLoadName(SimpleFile &file); - - void replaceSharedLibraryAtoms(SimpleFile *file); - - // A dummy file with which all the atoms created in the pass will be - // associated. Atoms need to be associated to an input file even if it's not - // read from a file, so we use this object. - VirtualFile _dummyFile; - - const PECOFFLinkingContext &_ctx; - llvm::BumpPtrAllocator _alloc; -}; - -} // namespace pecoff -} // namespace lld - -#endif Index: lib/ReaderWriter/PECOFF/IdataPass.cpp =================================================================== --- lib/ReaderWriter/PECOFF/IdataPass.cpp +++ /dev/null @@ -1,360 +0,0 @@ -//===- lib/ReaderWriter/PECOFF/IdataPass.cpp ------------------------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "IdataPass.h" -#include "Pass.h" -#include "lld/Core/File.h" -#include "lld/Core/Pass.h" -#include "lld/Core/Simple.h" -#include "llvm/Support/COFF.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/Endian.h" -#include -#include -#include -#include -#include - -using namespace llvm::support::endian; -using llvm::object::delay_import_directory_table_entry; - -namespace lld { -namespace pecoff { -namespace idata { - -IdataAtom::IdataAtom(IdataContext &context, std::vector data) - : COFFLinkerInternalAtom(context.dummyFile, - context.dummyFile.getNextOrdinal(), data) { - context.file.addAtom(*this); -} - -HintNameAtom::HintNameAtom(IdataContext &context, uint16_t hint, - StringRef importName) - : IdataAtom(context, assembleRawContent(hint, importName)), - _importName(importName) {} - -std::vector HintNameAtom::assembleRawContent(uint16_t hint, - StringRef importName) { - size_t size = - llvm::RoundUpToAlignment(sizeof(hint) + importName.size() + 1, 2); - std::vector ret(size); - ret[importName.size()] = 0; - ret[importName.size() - 1] = 0; - write16le(&ret[0], hint); - std::memcpy(&ret[2], importName.data(), importName.size()); - return ret; -} - -std::vector -ImportTableEntryAtom::assembleRawContent(uint64_t rva, bool is64) { - // The element size of the import table is 32 bit in PE and 64 bit - // in PE+. In PE+, bits 62-31 are filled with zero. - if (is64) { - std::vector ret(8); - write64le(&ret[0], rva); - return ret; - } - std::vector ret(4); - write32le(&ret[0], rva); - return ret; -} - -static std::vector -createImportTableAtoms(IdataContext &context, - const std::vector &sharedAtoms, - bool shouldAddReference, StringRef sectionName, - std::map &hintNameCache, - llvm::BumpPtrAllocator &alloc) { - std::vector ret; - for (COFFSharedLibraryAtom *atom : sharedAtoms) { - ImportTableEntryAtom *entry = nullptr; - if (atom->importName().empty()) { - // Import by ordinal - uint64_t hint = atom->hint(); - hint |= context.ctx.is64Bit() ? (uint64_t(1) << 63) : (uint64_t(1) << 31); - entry = new (alloc) ImportTableEntryAtom(context, hint, sectionName); - } else { - // Import by name - entry = new (alloc) ImportTableEntryAtom(context, 0, sectionName); - HintNameAtom *hintNameAtom; - auto it = hintNameCache.find(atom->importName()); - if (it == hintNameCache.end()) { - hintNameAtom = new (alloc) HintNameAtom( - context, atom->hint(), atom->importName()); - hintNameCache[atom->importName()] = hintNameAtom; - } else { - hintNameAtom = it->second; - } - addDir32NBReloc(entry, hintNameAtom, context.ctx.getMachineType(), 0); - } - ret.push_back(entry); - if (shouldAddReference) - atom->setImportTableEntry(entry); - } - // Add the NULL entry. - ret.push_back(new (alloc) ImportTableEntryAtom(context, 0, sectionName)); - return ret; -} - -// Creates atoms for an import lookup table. The import lookup table is an -// array of pointers to hint/name atoms. The array needs to be terminated with -// the NULL entry. -void ImportDirectoryAtom::addRelocations( - IdataContext &context, StringRef loadName, - const std::vector &sharedAtoms) { - // Create parallel arrays. The contents of the two are initially the - // same. The PE/COFF loader overwrites the import address tables with the - // pointers to the referenced items after loading the executable into - // memory. - std::map hintNameCache; - std::vector importLookupTables = - createImportTableAtoms(context, sharedAtoms, false, ".idata.t", - hintNameCache, _alloc); - std::vector importAddressTables = - createImportTableAtoms(context, sharedAtoms, true, ".idata.a", - hintNameCache, _alloc); - - addDir32NBReloc(this, importLookupTables[0], context.ctx.getMachineType(), - offsetof(ImportDirectoryTableEntry, ImportLookupTableRVA)); - addDir32NBReloc(this, importAddressTables[0], context.ctx.getMachineType(), - offsetof(ImportDirectoryTableEntry, ImportAddressTableRVA)); - auto *atom = new (_alloc) - COFFStringAtom(context.dummyFile, context.dummyFile.getNextOrdinal(), - ".idata", loadName); - context.file.addAtom(*atom); - addDir32NBReloc(this, atom, context.ctx.getMachineType(), - offsetof(ImportDirectoryTableEntry, NameRVA)); -} - -// Create the contents for the delay-import table. -std::vector DelayImportDirectoryAtom::createContent() { - std::vector r(sizeof(delay_import_directory_table_entry), 0); - auto entry = reinterpret_cast(&r[0]); - // link.exe seems to set 1 to Attributes field, so do we. - entry->Attributes = 1; - return r; -} - -// Find "___delayLoadHelper2@8" (or "__delayLoadHelper2" on x64). -// This is not efficient but should be OK for now. -static const Atom *findDelayLoadHelper(SimpleFile &file, - const PECOFFLinkingContext &ctx) { - StringRef sym = ctx.getDelayLoadHelperName(); - for (const DefinedAtom *atom : file.defined()) - if (atom->name() == sym) - return atom; - std::string msg = (sym + " was not found").str(); - llvm_unreachable(msg.c_str()); -} - -// Create the data referred by the delay-import table. -void DelayImportDirectoryAtom::addRelocations( - IdataContext &context, StringRef loadName, - const std::vector &sharedAtoms) { - // "ModuleHandle" field. This points to an array of pointer-size data - // in ".data" section. Initially the array is initialized with zero. - // The delay-load import helper will set DLL base address at runtime. - auto *hmodule = new (_alloc) DelayImportAddressAtom(context); - addDir32NBReloc(this, hmodule, context.ctx.getMachineType(), - offsetof(delay_import_directory_table_entry, ModuleHandle)); - - // "NameTable" field. The data structure of this field is the same - // as (non-delay) import table's Import Lookup Table. Contains - // imported function names. This is a parallel array of AddressTable - // field. - std::map hintNameCache; - std::vector nameTable = - createImportTableAtoms( - context, sharedAtoms, false, ".didat", hintNameCache, _alloc); - addDir32NBReloc( - this, nameTable[0], context.ctx.getMachineType(), - offsetof(delay_import_directory_table_entry, DelayImportNameTable)); - - // "Name" field. This points to the NUL-terminated DLL name string. - auto *name = new (_alloc) - COFFStringAtom(context.dummyFile, context.dummyFile.getNextOrdinal(), - ".didat", loadName); - context.file.addAtom(*name); - addDir32NBReloc(this, name, context.ctx.getMachineType(), - offsetof(delay_import_directory_table_entry, Name)); - - // "AddressTable" field. This points to an array of pointers, which - // in turn pointing to delay-load functions. - std::vector addrTable; - for (int i = 0, e = sharedAtoms.size() + 1; i < e; ++i) - addrTable.push_back(new (_alloc) DelayImportAddressAtom(context)); - for (int i = 0, e = sharedAtoms.size(); i < e; ++i) - sharedAtoms[i]->setImportTableEntry(addrTable[i]); - addDir32NBReloc( - this, addrTable[0], context.ctx.getMachineType(), - offsetof(delay_import_directory_table_entry, DelayImportAddressTable)); - - const Atom *delayLoadHelper = findDelayLoadHelper(context.file, context.ctx); - for (int i = 0, e = sharedAtoms.size(); i < e; ++i) { - const DefinedAtom *loader = new (_alloc) DelayLoaderAtom( - context, addrTable[i], this, delayLoadHelper); - if (context.ctx.is64Bit()) - addDir64Reloc(addrTable[i], loader, context.ctx.getMachineType(), 0); - else - addDir32Reloc(addrTable[i], loader, context.ctx.getMachineType(), 0); - } -} - -DelayLoaderAtom::DelayLoaderAtom(IdataContext &context, const Atom *impAtom, - const Atom *descAtom, const Atom *delayLoadHelperAtom) - : IdataAtom(context, createContent(context.ctx.getMachineType())) { - MachineTypes machine = context.ctx.getMachineType(); - switch (machine) { - case llvm::COFF::IMAGE_FILE_MACHINE_I386: - addDir32Reloc(this, impAtom, machine, 3); - addDir32Reloc(this, descAtom, machine, 8); - addRel32Reloc(this, delayLoadHelperAtom, machine, 13); - break; - case llvm::COFF::IMAGE_FILE_MACHINE_AMD64: - addRel32Reloc(this, impAtom, machine, 36); - addRel32Reloc(this, descAtom, machine, 43); - addRel32Reloc(this, delayLoadHelperAtom, machine, 48); - break; - default: - llvm::report_fatal_error("unsupported machine type"); - } -} - -// DelayLoaderAtom contains a wrapper function for __delayLoadHelper2. -// -// __delayLoadHelper2 takes two pointers: a pointer to the delay-load -// table descripter and a pointer to _imp_ symbol for the function -// to be resolved. -// -// __delayLoadHelper2 looks at the table descriptor to know the DLL -// name, calls dlopen()-like function to load it, resolves all -// imported symbols, and then writes the resolved addresses to the -// import address table. It returns a pointer to the resolved -// function. -// -// __delayLoadHelper2 is defined in delayimp.lib. -std::vector -DelayLoaderAtom::createContent(MachineTypes machine) const { - static const uint8_t x86[] = { - 0x51, // push ecx - 0x52, // push edx - 0x68, 0, 0, 0, 0, // push offset ___imp__ - 0x68, 0, 0, 0, 0, // push offset ___DELAY_IMPORT_DESCRIPTOR__dll - 0xE8, 0, 0, 0, 0, // call ___delayLoadHelper2@8 - 0x5A, // pop edx - 0x59, // pop ecx - 0xFF, 0xE0, // jmp eax - }; - static const uint8_t x64[] = { - 0x51, // push rcx - 0x52, // push rdx - 0x41, 0x50, // push r8 - 0x41, 0x51, // push r9 - 0x48, 0x83, 0xEC, 0x48, // sub rsp, 48h - 0x66, 0x0F, 0x7F, 0x04, 0x24, // movdqa xmmword ptr [rsp], xmm0 - 0x66, 0x0F, 0x7F, 0x4C, 0x24, 0x10, // movdqa xmmword ptr [rsp+10h], xmm1 - 0x66, 0x0F, 0x7F, 0x54, 0x24, 0x20, // movdqa xmmword ptr [rsp+20h], xmm2 - 0x66, 0x0F, 0x7F, 0x5C, 0x24, 0x30, // movdqa xmmword ptr [rsp+30h], xmm3 - 0x48, 0x8D, 0x15, 0, 0, 0, 0, // lea rdx, [__imp_] - 0x48, 0x8D, 0x0D, 0, 0, 0, 0, // lea rcx, [___DELAY_IMPORT_...] - 0xE8, 0, 0, 0, 0, // call __delayLoadHelper2 - 0x66, 0x0F, 0x6F, 0x04, 0x24, // movdqa xmm0, xmmword ptr [rsp] - 0x66, 0x0F, 0x6F, 0x4C, 0x24, 0x10, // movdqa xmm1, xmmword ptr [rsp+10h] - 0x66, 0x0F, 0x6F, 0x54, 0x24, 0x20, // movdqa xmm2, xmmword ptr [rsp+20h] - 0x66, 0x0F, 0x6F, 0x5C, 0x24, 0x30, // movdqa xmm3, xmmword ptr [rsp+30h] - 0x48, 0x83, 0xC4, 0x48, // add rsp, 48h - 0x41, 0x59, // pop r9 - 0x41, 0x58, // pop r8 - 0x5A, // pop rdx - 0x59, // pop rcx - 0xFF, 0xE0, // jmp rax - }; - switch (machine) { - case llvm::COFF::IMAGE_FILE_MACHINE_I386: - return std::vector(x86, x86 + sizeof(x86)); - case llvm::COFF::IMAGE_FILE_MACHINE_AMD64: - return std::vector(x64, x64 + sizeof(x64)); - default: - llvm::report_fatal_error("unsupported machine type"); - } -} - -} // namespace idata - -std::error_code IdataPass::perform(SimpleFile &file) { - if (file.sharedLibrary().empty()) - return std::error_code(); - - idata::IdataContext context(file, _dummyFile, _ctx); - std::map> sharedAtoms = - groupByLoadName(file); - bool hasImports = false; - bool hasDelayImports = false; - - // Create the import table and terminate it with the null entry. - for (auto i : sharedAtoms) { - StringRef loadName = i.first; - if (_ctx.isDelayLoadDLL(loadName)) - continue; - hasImports = true; - std::vector &atoms = i.second; - new (_alloc) idata::ImportDirectoryAtom(context, loadName, atoms); - } - if (hasImports) - new (_alloc) idata::NullImportDirectoryAtom(context); - - // Create the delay import table and terminate it with the null entry. - for (auto i : sharedAtoms) { - StringRef loadName = i.first; - if (!_ctx.isDelayLoadDLL(loadName)) - continue; - hasDelayImports = true; - std::vector &atoms = i.second; - new (_alloc) idata::DelayImportDirectoryAtom(context, loadName, atoms); - } - if (hasDelayImports) - new (_alloc) idata::DelayNullImportDirectoryAtom(context); - - replaceSharedLibraryAtoms(&file); - - return std::error_code(); -} - -std::map> -IdataPass::groupByLoadName(SimpleFile &file) { - std::map uniqueAtoms; - for (const SharedLibraryAtom *atom : file.sharedLibrary()) - uniqueAtoms[atom->name()] = - (COFFSharedLibraryAtom *)const_cast(atom); - - std::map > ret; - for (auto i : uniqueAtoms) { - COFFSharedLibraryAtom *atom = i.second; - ret[atom->loadName()].push_back(atom); - } - return ret; -} - -/// Transforms a reference to a COFFSharedLibraryAtom to a real reference. -void IdataPass::replaceSharedLibraryAtoms(SimpleFile *file) { - for (const DefinedAtom *atom : file->defined()) { - for (const Reference *ref : *atom) { - const Atom *target = ref->target(); - auto *sharedAtom = dyn_cast(target); - if (!sharedAtom) - continue; - const auto *coffSharedAtom = (const COFFSharedLibraryAtom *)sharedAtom; - const DefinedAtom *entry = coffSharedAtom->getImportTableEntry(); - const_cast(ref)->setTarget(entry); - } - } -} - -} // namespace pecoff -} // namespace lld Index: lib/ReaderWriter/PECOFF/InferSubsystemPass.h =================================================================== --- lib/ReaderWriter/PECOFF/InferSubsystemPass.h +++ /dev/null @@ -1,68 +0,0 @@ -//===- lib/ReaderWriter/PECOFF/InferSubsystemPass.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_PE_COFF_INFER_SUBSYSTEM_PASS_H -#define LLD_READER_WRITER_PE_COFF_INFER_SUBSYSTEM_PASS_H - -#include "Atoms.h" -#include "lld/Core/Pass.h" -#include - -namespace lld { -namespace pecoff { - -// Infers subsystem from entry point function name. -class InferSubsystemPass : public lld::Pass { -public: - InferSubsystemPass(PECOFFLinkingContext &ctx) : _ctx(ctx) {} - - std::error_code perform(SimpleFile &file) override { - if (_ctx.getSubsystem() != WindowsSubsystem::IMAGE_SUBSYSTEM_UNKNOWN) - return std::error_code(); - - if (_ctx.isDll()) { - _ctx.setSubsystem(WindowsSubsystem::IMAGE_SUBSYSTEM_WINDOWS_GUI); - return std::error_code(); - } - - // Scan the resolved symbols to infer the subsystem. - const std::string wWinMain = _ctx.decorateSymbol("wWinMainCRTStartup"); - const std::string wWinMainAt = _ctx.decorateSymbol("wWinMainCRTStartup@"); - const std::string winMain = _ctx.decorateSymbol("WinMainCRTStartup"); - const std::string winMainAt = _ctx.decorateSymbol("WinMainCRTStartup@"); - const std::string wmain = _ctx.decorateSymbol("wmainCRTStartup"); - const std::string wmainAt = _ctx.decorateSymbol("wmainCRTStartup@"); - const std::string main = _ctx.decorateSymbol("mainCRTStartup"); - const std::string mainAt = _ctx.decorateSymbol("mainCRTStartup@"); - - for (const DefinedAtom *atom : file.definedAtoms()) { - if (atom->name() == wWinMain || atom->name().startswith(wWinMainAt) || - atom->name() == winMain || atom->name().startswith(winMainAt)) { - _ctx.setSubsystem(WindowsSubsystem::IMAGE_SUBSYSTEM_WINDOWS_GUI); - return std::error_code(); - } - if (atom->name() == wmain || atom->name().startswith(wmainAt) || - atom->name() == main || atom->name().startswith(mainAt)) { - _ctx.setSubsystem(WindowsSubsystem::IMAGE_SUBSYSTEM_WINDOWS_CUI); - return std::error_code(); - } - } - llvm::report_fatal_error("Failed to infer subsystem"); - - return std::error_code(); - } - -private: - PECOFFLinkingContext &_ctx; -}; - -} // namespace pecoff -} // namespace lld - -#endif Index: lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h =================================================================== --- lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h +++ /dev/null @@ -1,309 +0,0 @@ -//===- lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h ----------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "Atoms.h" -#include "lld/Core/Simple.h" -#include "lld/ReaderWriter/PECOFFLinkingContext.h" -#include "llvm/Support/Allocator.h" -#include -#include - -using llvm::COFF::WindowsSubsystem; - -namespace lld { -namespace pecoff { - -bool findDecoratedSymbol(PECOFFLinkingContext *ctx, - std::string sym, std::string &res); - -namespace impl { - -/// The defined atom for dllexported symbols with __imp_ prefix. -class ImpPointerAtom : public COFFLinkerInternalAtom { -public: - ImpPointerAtom(const File &file, StringRef symbolName, uint64_t ordinal) - : COFFLinkerInternalAtom(file, /*oridnal*/ 0, std::vector(4), - symbolName), - _ordinal(ordinal) {} - - uint64_t ordinal() const override { return _ordinal; } - Scope scope() const override { return scopeGlobal; } - ContentType contentType() const override { return typeData; } - Alignment alignment() const override { return 16; } - ContentPermissions permissions() const override { return permR__; } - -private: - uint64_t _ordinal; -}; - -class ImpSymbolFile : public SimpleFile { -public: - ImpSymbolFile(StringRef defsym, StringRef undefsym, uint64_t ordinal, - bool is64) - : SimpleFile(defsym), _undefined(*this, undefsym), - _defined(*this, defsym, ordinal) { - SimpleReference *ref; - if (is64) { - ref = new SimpleReference(Reference::KindNamespace::COFF, - Reference::KindArch::x86_64, - llvm::COFF::IMAGE_REL_AMD64_ADDR32, - 0, &_undefined, 0); - } else { - ref = new SimpleReference(Reference::KindNamespace::COFF, - Reference::KindArch::x86, - llvm::COFF::IMAGE_REL_I386_DIR32, - 0, &_undefined, 0); - } - _defined.addReference(std::unique_ptr(ref)); - addAtom(_defined); - addAtom(_undefined); - } - -private: - SimpleUndefinedAtom _undefined; - ImpPointerAtom _defined; -}; - -// A file to make Resolver to resolve a symbol TO instead of a symbol FROM, -// using fallback mechanism for an undefined symbol. One can virtually rename an -// undefined symbol using this file. -class SymbolRenameFile : public SimpleFile { -public: - SymbolRenameFile(StringRef from, StringRef to) - : SimpleFile(""), _fromSym(from), _toSym(to), - _from(*this, _fromSym, &_to), _to(*this, _toSym) { - addAtom(_from); - } - -private: - std::string _fromSym; - std::string _toSym; - COFFUndefinedAtom _from; - COFFUndefinedAtom _to; -}; - -} // namespace impl - -// A virtual file containing absolute symbol __ImageBase. __ImageBase (or -// ___ImageBase on x86) is a linker-generated symbol whose address is the same -// as the image base address. -class LinkerGeneratedSymbolFile : public SimpleFile { -public: - LinkerGeneratedSymbolFile(const PECOFFLinkingContext &ctx) - : SimpleFile(""), - _imageBaseAtom(*this, ctx.decorateSymbol("__ImageBase"), - Atom::scopeGlobal, ctx.getBaseAddress()) { - addAtom(_imageBaseAtom); - } - -private: - SimpleAbsoluteAtom _imageBaseAtom; -}; - -// A LocallyImporteSymbolFile is an archive file containing __imp_ -// symbols for local use. -// -// For each defined symbol, linker creates an implicit defined symbol -// by appending "__imp_" prefix to the original name. The content of -// the implicit symbol is a pointer to the original symbol -// content. This feature allows one to compile and link the following -// code without error, although _imp__hello is not defined in the -// code. (the leading "_" in this example is automatically appended, -// assuming it's x86.) -// -// void hello() { printf("Hello\n"); } -// extern void (*_imp__hello)(); -// int main() { -// _imp__hello(); -// return 0; -// } -// -// This odd feature is for the compatibility with MSVC link.exe. -class LocallyImportedSymbolFile : public SimpleArchiveLibraryFile { -public: - LocallyImportedSymbolFile(const PECOFFLinkingContext &ctx) - : SimpleArchiveLibraryFile("__imp_"), _is64(ctx.is64Bit()), - _ordinal(0) {} - - File *find(StringRef sym, bool dataSymbolOnly) override { - std::string prefix = "__imp_"; - if (!sym.startswith(prefix)) - return nullptr; - StringRef undef = sym.substr(prefix.size()); - return new (_alloc) impl::ImpSymbolFile(sym, undef, _ordinal++, _is64); - } - -private: - bool _is64; - uint64_t _ordinal; - llvm::BumpPtrAllocator _alloc; -}; - -// A ExportedSymbolRenameFile is a virtual archive file for dllexported symbols. -// -// One usually has to specify the exact symbol name to resolve it. That's true -// in most cases for PE/COFF, except the one described below. -// -// DLLExported symbols can be specified using a module definition file. In a -// file, one can write an EXPORT directive followed by symbol names. Such -// symbols may not be fully decorated. -// -// If a symbol FOO is specified to be dllexported by a module definition file, -// linker has to search not only for /FOO/ but also for /FOO@[0-9]+/ for stdcall -// and for /\?FOO@@.+/ for C++. This ambiguous matching semantics does not fit -// well with Resolver. -// -// We could probably modify Resolver to resolve ambiguous symbols, but I think -// we don't want to do that because it'd be rarely used, and only this Windows -// specific feature would use it. It's probably not a good idea to make the core -// linker to be able to deal with it. -// -// So, instead of tweaking Resolver, we chose to do some hack here. An -// ExportedSymbolRenameFile maintains a set containing all possibly defined -// symbol names. That set would be a union of (1) all the defined symbols that -// are already parsed and read and (2) all the defined symbols in archive files -// that are not yet be parsed. -// -// If Resolver asks this file to return an atom for a dllexported symbol, find() -// looks up the set, doing ambiguous matching. If there's a symbol with @ -// prefix, it returns an atom to rename the dllexported symbol, hoping that -// Resolver will find the new symbol with atsign from an archive file at the -// next visit. -class ExportedSymbolRenameFile : public SimpleArchiveLibraryFile { -public: - ExportedSymbolRenameFile(const PECOFFLinkingContext &ctx) - : SimpleArchiveLibraryFile(""), - _ctx(const_cast(&ctx)) { - for (PECOFFLinkingContext::ExportDesc &desc : _ctx->getDllExports()) - _exportedSyms.insert(desc.name); - } - - File *find(StringRef sym, bool dataSymbolOnly) override { - typedef PECOFFLinkingContext::ExportDesc ExportDesc; - if (_exportedSyms.count(sym) == 0) - return nullptr; - std::string replace; - if (!findDecoratedSymbol(_ctx, sym.str(), replace)) - return nullptr; - - for (ExportDesc &exp : _ctx->getDllExports()) - if (exp.name == sym) - exp.mangledName = replace; - if (_ctx->deadStrip()) - _ctx->addDeadStripRoot(_ctx->allocate(replace)); - return new (_alloc) impl::SymbolRenameFile(sym, replace); - } - -private: - std::set _exportedSyms; - llvm::BumpPtrAllocator _alloc; - PECOFFLinkingContext *_ctx; -}; - -// Windows has not only one but many entry point functions. The -// appropriate one is automatically selected based on the subsystem -// setting and the user-supplied entry point function. -// -// http://msdn.microsoft.com/en-us/library/f9t8842e.aspx -class EntryPointFile : public SimpleFile { -public: - EntryPointFile(const PECOFFLinkingContext &ctx) - : SimpleFile(""), _ctx(const_cast(&ctx)), - _firstTime(true) {} - - const AtomVector &undefined() const override { - return const_cast(this)->getUndefinedAtoms(); - } - -private: - const AtomVector &getUndefinedAtoms() { - std::lock_guard lock(_mutex); - if (!_firstTime) - return _undefinedAtoms; - _firstTime = false; - - if (_ctx->hasEntry()) { - StringRef entrySym = _ctx->allocate(getEntry()); - _undefinedAtoms.push_back( - new (_alloc) SimpleUndefinedAtom(*this, entrySym)); - _ctx->setHasEntry(true); - _ctx->setEntrySymbolName(entrySym); - if (_ctx->deadStrip()) - _ctx->addDeadStripRoot(entrySym); - } - return _undefinedAtoms; - } - - // Returns the entry point function name. - std::string getEntry() const { - StringRef opt = _ctx->getEntrySymbolName(); - if (!opt.empty()) { - std::string mangled; - if (findDecoratedSymbol(_ctx, opt, mangled)) - return mangled; - return _ctx->decorateSymbol(opt); - } - return _ctx->decorateSymbol(getDefaultEntry()); - } - - std::string getDefaultEntry() const { - const std::string wWinMainCRTStartup = "wWinMainCRTStartup"; - const std::string WinMainCRTStartup = "WinMainCRTStartup"; - const std::string wmainCRTStartup = "wmainCRTStartup"; - const std::string mainCRTStartup = "mainCRTStartup"; - - if (_ctx->isDll()) { - if (_ctx->getMachineType() == llvm::COFF::IMAGE_FILE_MACHINE_I386) - return "_DllMainCRTStartup@12"; - return "_DllMainCRTStartup"; - } - - // Returns true if a given name exists in an input object file. - auto defined = [&](StringRef name) -> bool { - StringRef sym = _ctx->decorateSymbol(name); - if (_ctx->definedSymbols().count(sym)) - return true; - std::string ignore; - return findDecoratedSymbol(_ctx, sym, ignore); - }; - - switch (_ctx->getSubsystem()) { - case WindowsSubsystem::IMAGE_SUBSYSTEM_UNKNOWN: { - if (defined("wWinMain")) - return wWinMainCRTStartup; - if (defined("WinMain")) - return WinMainCRTStartup; - if (defined("wmain")) - return wmainCRTStartup; - if (!defined("main")) - llvm::errs() << "Cannot infer subsystem; assuming /subsystem:console\n"; - return mainCRTStartup; - } - case WindowsSubsystem::IMAGE_SUBSYSTEM_WINDOWS_GUI: - if (defined("WinMain")) - return WinMainCRTStartup; - return wWinMainCRTStartup; - case WindowsSubsystem::IMAGE_SUBSYSTEM_WINDOWS_CUI: - if (defined("wmain")) - return wmainCRTStartup; - return mainCRTStartup; - default: - return mainCRTStartup; - } - } - - PECOFFLinkingContext *_ctx; - AtomVector _undefinedAtoms; - std::mutex _mutex; - llvm::BumpPtrAllocator _alloc; - bool _firstTime; -}; - -} // end namespace pecoff -} // end namespace lld Index: lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.cpp =================================================================== --- lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.cpp +++ /dev/null @@ -1,48 +0,0 @@ -//===- lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.cpp --------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "LinkerGeneratedSymbolFile.h" - -namespace lld { -namespace pecoff { - -// Find decorated symbol, namely /sym@[0-9]+/ or /\?sym@@.+/. -bool findDecoratedSymbol(PECOFFLinkingContext *ctx, - std::string sym, std::string &res) { - const std::set &defined = ctx->definedSymbols(); - // Search for /sym@[0-9]+/ - { - std::string s = sym + '@'; - auto it = defined.lower_bound(s); - for (auto e = defined.end(); it != e; ++it) { - if (!StringRef(*it).startswith(s)) - break; - if (it->size() == s.size()) - continue; - StringRef suffix = StringRef(*it).substr(s.size()); - if (suffix.find_first_not_of("0123456789") != StringRef::npos) - continue; - res = *it; - return true; - } - } - // Search for /\?sym@@.+/ - { - std::string s = "?" + ctx->undecorateSymbol(sym).str() + "@@"; - auto it = defined.lower_bound(s); - if (it != defined.end() && StringRef(*it).startswith(s)) { - res = *it; - return true; - } - } - return false; -} - -} // namespace pecoff -} // namespace lld Index: lib/ReaderWriter/PECOFF/LoadConfigPass.h =================================================================== --- lib/ReaderWriter/PECOFF/LoadConfigPass.h +++ /dev/null @@ -1,63 +0,0 @@ -//===- lib/ReaderWriter/PECOFF/LoadConfigPass.h ---------------------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file \brief This linker pass creates an atom for Load Configuration -/// structure. -/// -/// For the details of the Load Configuration structure, see Microsoft PE/COFF -/// Specification section 5.8. The Load Configuration Structure (Image Only). -/// -//===----------------------------------------------------------------------===// - -#ifndef LLD_READER_WRITER_PE_COFF_LOAD_CONFIG_PASS_H -#define LLD_READER_WRITER_PE_COFF_LOAD_CONFIG_PASS_H - -#include "Atoms.h" -#include "lld/Core/File.h" -#include "lld/Core/Pass.h" -#include "lld/Core/Simple.h" -#include "lld/ReaderWriter/PECOFFLinkingContext.h" -#include - -namespace lld { -namespace pecoff { -namespace loadcfg { - -class LoadConfigAtom : public COFFLinkerInternalAtom { -public: - LoadConfigAtom(VirtualFile &file, const DefinedAtom *sxdata, int count); - - SectionChoice sectionChoice() const override { return sectionCustomRequired; } - StringRef customSectionName() const override { return ".loadcfg"; } - ContentType contentType() const override { return typeData; } - ContentPermissions permissions() const override { return permR__; } - - template T *getContents() const { - return (T *)const_cast(rawContent().data()); - } -}; - -} // namespace loadcfg - -class LoadConfigPass : public lld::Pass { -public: - LoadConfigPass(PECOFFLinkingContext &ctx) : _ctx(ctx), _file(ctx) {} - - std::error_code perform(SimpleFile &file) override; - -private: - PECOFFLinkingContext &_ctx; - VirtualFile _file; - mutable llvm::BumpPtrAllocator _alloc; -}; - -} // namespace pecoff -} // namespace lld - -#endif Index: lib/ReaderWriter/PECOFF/LoadConfigPass.cpp =================================================================== --- lib/ReaderWriter/PECOFF/LoadConfigPass.cpp +++ /dev/null @@ -1,77 +0,0 @@ -//===- lib/ReaderWriter/PECOFF/LoadConfigPass.cpp -------------------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// A Load Configuration is a data structure for x86 containing an address of the -// SEH handler table. The Data Directory in the file header points to a load -// configuration. Technically that indirection is not needed but exists for -// historical reasons. -// -// If the file being handled has .sxdata section containing SEH handler table, -// this pass will create a Load Configuration atom. -// -//===----------------------------------------------------------------------===// - -#include "Pass.h" -#include "LoadConfigPass.h" -#include "lld/Core/File.h" -#include "lld/Core/Pass.h" -#include "lld/Core/Simple.h" -#include "llvm/Object/COFF.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/Path.h" -#include -#include -#include - -using llvm::object::coff_load_configuration32; - -namespace lld { -namespace pecoff { -namespace loadcfg { - -LoadConfigAtom::LoadConfigAtom(VirtualFile &file, const DefinedAtom *sxdata, - int count) - : COFFLinkerInternalAtom( - file, file.getNextOrdinal(), - std::vector(sizeof(coff_load_configuration32))) { - addDir32Reloc( - this, sxdata, llvm::COFF::IMAGE_FILE_MACHINE_I386, - offsetof(llvm::object::coff_load_configuration32, SEHandlerTable)); - auto *data = getContents(); - data->SEHandlerCount = count; -} - -} // namespace loadcfg - -std::error_code LoadConfigPass::perform(SimpleFile &file) { - if (_ctx.noSEH()) - return std::error_code(); - - // Find the first atom in .sxdata section. - const DefinedAtom *sxdata = nullptr; - int sectionSize = 0; - for (const DefinedAtom *atom : file.defined()) { - if (atom->customSectionName() == ".sxdata") { - if (!sxdata) - sxdata = atom; - sectionSize += sxdata->size(); - } - } - if (!sxdata) - return std::error_code(); - - auto *loadcfg = new (_alloc) - loadcfg::LoadConfigAtom(_file, sxdata, sectionSize / sizeof(uint32_t)); - file.addAtom(*loadcfg); - - return std::error_code(); -} - -} // namespace pecoff -} // namespace lld Index: lib/ReaderWriter/PECOFF/OrderPass.h =================================================================== --- lib/ReaderWriter/PECOFF/OrderPass.h +++ /dev/null @@ -1,68 +0,0 @@ -//===- lib/ReaderWriter/PECOFF/OrderPass.h -------------------------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file \brief This pass sorts atoms by section name, so that they will appear -/// in the correct order in the output. -/// -/// In COFF, sections will be merged into one section by the linker if their -/// names are the same after discarding the "$" character and all characters -/// follow it from their names. The characters following the "$" character -/// determines the merge order. Assume there's an object file containing four -/// data sections in the following order. -/// -/// - .data$2 -/// - .data$3 -/// - .data$1 -/// - .data -/// -/// In this case, the resulting binary should have ".data" section with the -/// contents of ".data", ".data$1", ".data$2" and ".data$3" in that order. -/// -//===----------------------------------------------------------------------===// - -#ifndef LLD_READER_WRITER_PE_COFF_ORDER_PASS_H -#define LLD_READER_WRITER_PE_COFF_ORDER_PASS_H - -#include "Atoms.h" -#include "lld/Core/Parallel.h" -#include "lld/Core/Pass.h" -#include - -namespace lld { -namespace pecoff { - -static bool compare(const DefinedAtom *lhs, const DefinedAtom *rhs) { - bool lhsCustom = (lhs->sectionChoice() == DefinedAtom::sectionCustomRequired); - bool rhsCustom = (rhs->sectionChoice() == DefinedAtom::sectionCustomRequired); - if (lhsCustom && rhsCustom) { - int cmp = lhs->customSectionName().compare(rhs->customSectionName()); - if (cmp != 0) - return cmp < 0; - return DefinedAtom::compareByPosition(lhs, rhs); - } - if (lhsCustom && !rhsCustom) - return true; - if (!lhsCustom && rhsCustom) - return false; - return DefinedAtom::compareByPosition(lhs, rhs); -} - -class OrderPass : public lld::Pass { -public: - std::error_code perform(SimpleFile &file) override { - SimpleFile::DefinedAtomRange defined = file.definedAtoms(); - parallel_sort(defined.begin(), defined.end(), compare); - return std::error_code(); - } -}; - -} // namespace pecoff -} // namespace lld - -#endif Index: lib/ReaderWriter/PECOFF/PDBPass.h =================================================================== --- lib/ReaderWriter/PECOFF/PDBPass.h +++ /dev/null @@ -1,44 +0,0 @@ -//===- lib/ReaderWriter/PECOFF/PDBPass.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_PE_COFF_PDB_PASS_H -#define LLD_READER_WRITER_PE_COFF_PDB_PASS_H - -#include "lld/Core/Pass.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Process.h" - -namespace lld { -namespace pecoff { - -class PDBPass : public lld::Pass { -public: - PDBPass(PECOFFLinkingContext &ctx) : _ctx(ctx) {} - - std::error_code perform(SimpleFile &) override { - if (_ctx.getDebug()) - touch(_ctx.getPDBFilePath()); - return std::error_code(); - } - -private: - void touch(StringRef path) { - int fd; - if (llvm::sys::fs::openFileForWrite(path, fd, llvm::sys::fs::F_Append)) - llvm::report_fatal_error("failed to create a PDB file"); - llvm::sys::Process::SafelyCloseFileDescriptor(fd); - } - - PECOFFLinkingContext &_ctx; -}; - -} // namespace pecoff -} // namespace lld - -#endif Index: lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp =================================================================== --- lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp +++ /dev/null @@ -1,350 +0,0 @@ -//===- lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp -------------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "Atoms.h" -#include "EdataPass.h" -#include "IdataPass.h" -#include "InferSubsystemPass.h" -#include "LinkerGeneratedSymbolFile.h" -#include "LoadConfigPass.h" -#include "OrderPass.h" -#include "PDBPass.h" -#include "lld/Core/PassManager.h" -#include "lld/Core/Reader.h" -#include "lld/Core/Simple.h" -#include "lld/Core/Writer.h" -#include "lld/ReaderWriter/PECOFFLinkingContext.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/Support/Allocator.h" -#include "llvm/Support/Path.h" -#include -#include -#include - -namespace lld { - -bool PECOFFLinkingContext::validateImpl(raw_ostream &diagnostics) { - if (_stackReserve < _stackCommit) { - diagnostics << "Invalid stack size: reserve size must be equal to or " - << "greater than commit size, but got " << _stackCommit - << " and " << _stackReserve << ".\n"; - return false; - } - - if (_heapReserve < _heapCommit) { - diagnostics << "Invalid heap size: reserve size must be equal to or " - << "greater than commit size, but got " << _heapCommit - << " and " << _heapReserve << ".\n"; - return false; - } - - // It's an error if the base address is not multiple of 64K. - if (getBaseAddress() & 0xffff) { - diagnostics << "Base address have to be multiple of 64K, but got " - << getBaseAddress() << "\n"; - return false; - } - - // Specifing /noentry without /dll is an error. - if (!hasEntry() && !isDll()) { - diagnostics << "/noentry must be specified with /dll\n"; - return false; - } - - // Check for duplicate export ordinals. - std::set exports; - for (const PECOFFLinkingContext::ExportDesc &desc : getDllExports()) { - if (desc.ordinal == -1) - continue; - if (exports.count(desc.ordinal) == 1) { - diagnostics << "Duplicate export ordinals: " << desc.ordinal << "\n"; - return false; - } - exports.insert(desc.ordinal); - } - - // Check for /align. - std::bitset<64> alignment(_sectionDefaultAlignment); - if (alignment.count() != 1) { - diagnostics << "Section alignment must be a power of 2, but got " - << _sectionDefaultAlignment << "\n"; - return false; - } - - _writer = createWriterPECOFF(*this); - return true; -} - -const std::set &PECOFFLinkingContext::definedSymbols() { - std::lock_guard lock(_mutex); - for (std::unique_ptr &node : getNodes()) { - if (_seen.count(node.get()) > 0) - continue; - FileNode *fnode = dyn_cast(node.get()); - if (!fnode) - continue; - File *file = fnode->getFile(); - if (file->parse()) - continue; - if (auto *archive = dyn_cast(file)) { - for (const std::string &sym : archive->getDefinedSymbols()) - _definedSyms.insert(sym); - continue; - } - for (const DefinedAtom *atom : file->defined()) - if (!atom->name().empty()) - _definedSyms.insert(atom->name()); - } - return _definedSyms; -} - -std::unique_ptr PECOFFLinkingContext::createEntrySymbolFile() const { - return LinkingContext::createEntrySymbolFile(""); -} - -std::unique_ptr PECOFFLinkingContext::createUndefinedSymbolFile() const { - return LinkingContext::createUndefinedSymbolFile( - ""); -} - -static int getGroupStartPos(std::vector> &nodes) { - for (int i = 0, e = nodes.size(); i < e; ++i) - if (GroupEnd *group = dyn_cast(nodes[i].get())) - return i - group->getSize(); - llvm::report_fatal_error("internal error"); -} - -void PECOFFLinkingContext::addLibraryFile(std::unique_ptr file) { - GroupEnd *currentGroupEnd; - int pos = -1; - std::vector> &elements = getNodes(); - for (int i = 0, e = elements.size(); i < e; ++i) { - if ((currentGroupEnd = dyn_cast(elements[i].get()))) { - pos = i; - break; - } - } - assert(pos >= 0); - elements.insert(elements.begin() + pos, std::move(file)); - elements[pos + 1] = llvm::make_unique( - currentGroupEnd->getSize() + 1); -} - -void PECOFFLinkingContext::createImplicitFiles( - std::vector> &) { - std::vector> &members = getNodes(); - - // Create a file for the entry point function. - std::unique_ptr entry(new FileNode( - llvm::make_unique(*this))); - members.insert(members.begin() + getGroupStartPos(members), std::move(entry)); - - // Create a file for __ImageBase. - std::unique_ptr fileNode(new FileNode( - llvm::make_unique(*this))); - members.push_back(std::move(fileNode)); - - // Create a file for _imp_ symbols. - std::unique_ptr impFileNode(new FileNode( - llvm::make_unique(*this))); - members.push_back(std::move(impFileNode)); - - // Create a file for dllexported symbols. - std::unique_ptr exportNode(new FileNode( - llvm::make_unique(*this))); - addLibraryFile(std::move(exportNode)); -} - -/// Returns the section name in the resulting executable. -/// -/// Sections in object files are usually output to the executable with the same -/// name, but you can rename by command line option. /merge:from=to makes the -/// linker to combine "from" section contents to "to" section in the -/// executable. We have a mapping for the renaming. This method looks up the -/// table and returns a new section name if renamed. -StringRef -PECOFFLinkingContext::getOutputSectionName(StringRef sectionName) const { - auto it = _renamedSections.find(sectionName); - if (it == _renamedSections.end()) - return sectionName; - return getOutputSectionName(it->second); -} - -/// Adds a mapping to the section renaming table. This method will be used for -/// /merge command line option. -bool PECOFFLinkingContext::addSectionRenaming(raw_ostream &diagnostics, - StringRef from, StringRef to) { - auto it = _renamedSections.find(from); - if (it != _renamedSections.end()) { - if (it->second == to) - // There's already the same mapping. - return true; - diagnostics << "Section \"" << from << "\" is already mapped to \"" - << it->second << ", so it cannot be mapped to \"" << to << "\"."; - return true; - } - - // Add a mapping, and check if there's no cycle in the renaming mapping. The - // cycle detection algorithm we use here is naive, but that's OK because the - // number of mapping is usually less than 10. - _renamedSections[from] = to; - for (auto elem : _renamedSections) { - StringRef sectionName = elem.first; - std::set visited; - visited.insert(sectionName); - for (;;) { - auto pos = _renamedSections.find(sectionName); - if (pos == _renamedSections.end()) - break; - if (visited.count(pos->second)) { - diagnostics << "/merge:" << from << "=" << to << " makes a cycle"; - return false; - } - sectionName = pos->second; - visited.insert(sectionName); - } - } - return true; -} - -/// Try to find the input library file from the search paths and append it to -/// the input file list. Returns true if the library file is found. -StringRef PECOFFLinkingContext::searchLibraryFile(StringRef filename) const { - // Current directory always takes precedence over the search paths. - if (llvm::sys::path::is_absolute(filename) || llvm::sys::fs::exists(filename)) - return filename; - // Iterate over the search paths. - for (StringRef dir : _inputSearchPaths) { - SmallString<128> path = dir; - llvm::sys::path::append(path, filename); - if (llvm::sys::fs::exists(path.str())) - return allocate(path.str()); - } - return filename; -} - -/// Returns the decorated name of the given symbol name. On 32-bit x86, it -/// adds "_" at the beginning of the string. On other architectures, the -/// return value is the same as the argument. -StringRef PECOFFLinkingContext::decorateSymbol(StringRef name) const { - if (_machineType != llvm::COFF::IMAGE_FILE_MACHINE_I386) - return name; - std::string str = "_"; - str.append(name); - return allocate(str); -} - -StringRef PECOFFLinkingContext::undecorateSymbol(StringRef name) const { - if (_machineType != llvm::COFF::IMAGE_FILE_MACHINE_I386) - return name; - if (!name.startswith("_")) - return name; - return name.substr(1); -} - -uint64_t PECOFFLinkingContext::getBaseAddress() const { - if (_baseAddress == invalidBaseAddress) - return is64Bit() ? pe32PlusDefaultBaseAddress : pe32DefaultBaseAddress; - return _baseAddress; -} - -Writer &PECOFFLinkingContext::writer() const { return *_writer; } - -void PECOFFLinkingContext::setSectionSetMask(StringRef sectionName, - uint32_t newFlags) { - _sectionSetMask[sectionName] |= newFlags; - _sectionClearMask[sectionName] &= ~newFlags; - const uint32_t rwx = (llvm::COFF::IMAGE_SCN_MEM_READ | - llvm::COFF::IMAGE_SCN_MEM_WRITE | - llvm::COFF::IMAGE_SCN_MEM_EXECUTE); - if (newFlags & rwx) - _sectionClearMask[sectionName] |= ~_sectionSetMask[sectionName] & rwx; - assert((_sectionSetMask[sectionName] & _sectionClearMask[sectionName]) == 0); -} - -void PECOFFLinkingContext::setSectionClearMask(StringRef sectionName, - uint32_t newFlags) { - _sectionClearMask[sectionName] |= newFlags; - _sectionSetMask[sectionName] &= ~newFlags; - assert((_sectionSetMask[sectionName] & _sectionClearMask[sectionName]) == 0); -} - -uint32_t PECOFFLinkingContext::getSectionAttributes(StringRef sectionName, - uint32_t flags) const { - auto si = _sectionSetMask.find(sectionName); - uint32_t setMask = (si == _sectionSetMask.end()) ? 0 : si->second; - auto ci = _sectionClearMask.find(sectionName); - uint32_t clearMask = (ci == _sectionClearMask.end()) ? 0 : ci->second; - return (flags | setMask) & ~clearMask; -} - -// Returns true if two export descriptors are the same. -static bool sameExportDesc(const PECOFFLinkingContext::ExportDesc &a, - const PECOFFLinkingContext::ExportDesc &b) { - return a.ordinal == b.ordinal && a.ordinal == b.ordinal && - a.noname == b.noname && a.isData == b.isData; -} - -void PECOFFLinkingContext::addDllExport(ExportDesc &desc) { - addInitialUndefinedSymbol(allocate(desc.name)); - - // MSVC link.exe silently drops characters after the first atsign. - // For example, /export:foo@4=bar is equivalent to /export:foo=bar. - // We do the same thing for compatibility. - if (!desc.externalName.empty()) { - StringRef s(desc.externalName); - size_t pos = s.find('@'); - if (pos != s.npos) - desc.externalName = s.substr(0, pos); - } - - // Scan the vector to look for existing entry. It's not very fast, - // but because the number of exported symbol is usually not that - // much, it should be okay. - for (ExportDesc &e : _dllExports) { - if (e.name != desc.name) - continue; - if (!sameExportDesc(e, desc)) - llvm::errs() << "Export symbol '" << desc.name - << "' specified more than once.\n"; - return; - } - _dllExports.push_back(desc); -} - -static std::string replaceExtension(StringRef path, StringRef ext) { - SmallString<128> ss = path; - llvm::sys::path::replace_extension(ss, ext); - return ss.str(); -} - -std::string PECOFFLinkingContext::getOutputImportLibraryPath() const { - if (!_implib.empty()) - return _implib; - return replaceExtension(outputPath(), ".lib"); -} - -std::string PECOFFLinkingContext::getPDBFilePath() const { - assert(_debug); - if (!_pdbFilePath.empty()) - return _pdbFilePath; - return replaceExtension(outputPath(), ".pdb"); -} - -void PECOFFLinkingContext::addPasses(PassManager &pm) { - pm.add(llvm::make_unique(*this)); - pm.add(llvm::make_unique(*this)); - pm.add(llvm::make_unique(*this)); - pm.add(llvm::make_unique()); - pm.add(llvm::make_unique(*this)); - pm.add(llvm::make_unique(*this)); -} - -} // end namespace lld Index: lib/ReaderWriter/PECOFF/Pass.h =================================================================== --- lib/ReaderWriter/PECOFF/Pass.h +++ /dev/null @@ -1,34 +0,0 @@ -//===- lib/ReaderWriter/PECOFF/Pass.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_PE_COFF_PASS_H -#define LLD_READER_WRITER_PE_COFF_PASS_H - -#include "Atoms.h" -#include "llvm/Support/COFF.h" - -namespace lld { -namespace pecoff { - -void addDir64Reloc(COFFBaseDefinedAtom *atom, const Atom *target, - llvm::COFF::MachineTypes machine, size_t offsetInAtom); - -void addDir32Reloc(COFFBaseDefinedAtom *atom, const Atom *target, - llvm::COFF::MachineTypes machine, size_t offsetInAtom); - -void addDir32NBReloc(COFFBaseDefinedAtom *atom, const Atom *target, - llvm::COFF::MachineTypes machine, size_t offsetInAtom); - -void addRel32Reloc(COFFBaseDefinedAtom *atom, const Atom *target, - llvm::COFF::MachineTypes machine, size_t offsetInAtom); - -} // namespace pecoff -} // namespace lld - -#endif Index: lib/ReaderWriter/PECOFF/Pass.cpp =================================================================== --- lib/ReaderWriter/PECOFF/Pass.cpp +++ /dev/null @@ -1,95 +0,0 @@ -//===- lib/ReaderWriter/PECOFF/Pass.cpp -----------------------------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "Atoms.h" -#include "Pass.h" -#include "lld/Core/File.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/Support/COFF.h" - -namespace lld { -namespace pecoff { - -static void addReloc(COFFBaseDefinedAtom *atom, const Atom *target, - size_t offsetInAtom, Reference::KindArch arch, - Reference::KindValue relType) { - atom->addReference(llvm::make_unique( - Reference::KindNamespace::COFF, arch, relType, offsetInAtom, target, 0)); -} - -void addDir64Reloc(COFFBaseDefinedAtom *atom, const Atom *target, - llvm::COFF::MachineTypes machine, size_t offsetInAtom) { - switch (machine) { - case llvm::COFF::IMAGE_FILE_MACHINE_I386: - addReloc(atom, target, offsetInAtom, Reference::KindArch::x86, - llvm::COFF::IMAGE_REL_I386_DIR32); - return; - case llvm::COFF::IMAGE_FILE_MACHINE_AMD64: - addReloc(atom, target, offsetInAtom, Reference::KindArch::x86_64, - llvm::COFF::IMAGE_REL_AMD64_ADDR64); - return; - default: - llvm_unreachable("unsupported machine type"); - } -} - -void addDir32Reloc(COFFBaseDefinedAtom *atom, const Atom *target, - llvm::COFF::MachineTypes machine, size_t offsetInAtom) { - switch (machine) { - case llvm::COFF::IMAGE_FILE_MACHINE_I386: - addReloc(atom, target, offsetInAtom, Reference::KindArch::x86, - llvm::COFF::IMAGE_REL_I386_DIR32); - return; - case llvm::COFF::IMAGE_FILE_MACHINE_AMD64: - addReloc(atom, target, offsetInAtom, Reference::KindArch::x86_64, - llvm::COFF::IMAGE_REL_AMD64_ADDR32); - return; - default: - llvm_unreachable("unsupported machine type"); - } -} - -void addDir32NBReloc(COFFBaseDefinedAtom *atom, const Atom *target, - llvm::COFF::MachineTypes machine, size_t offsetInAtom) { - switch (machine) { - case llvm::COFF::IMAGE_FILE_MACHINE_I386: - addReloc(atom, target, offsetInAtom, Reference::KindArch::x86, - llvm::COFF::IMAGE_REL_I386_DIR32NB); - return; - case llvm::COFF::IMAGE_FILE_MACHINE_AMD64: - addReloc(atom, target, offsetInAtom, Reference::KindArch::x86_64, - llvm::COFF::IMAGE_REL_AMD64_ADDR32NB); - return; - case llvm::COFF::IMAGE_FILE_MACHINE_ARMNT: - addReloc(atom, target, offsetInAtom, Reference::KindArch::ARM, - llvm::COFF::IMAGE_REL_ARM_ADDR32NB); - return; - default: - llvm_unreachable("unsupported machine type"); - } -} - -void addRel32Reloc(COFFBaseDefinedAtom *atom, const Atom *target, - llvm::COFF::MachineTypes machine, size_t offsetInAtom) { - switch (machine) { - case llvm::COFF::IMAGE_FILE_MACHINE_I386: - addReloc(atom, target, offsetInAtom, Reference::KindArch::x86, - llvm::COFF::IMAGE_REL_I386_REL32); - return; - case llvm::COFF::IMAGE_FILE_MACHINE_AMD64: - addReloc(atom, target, offsetInAtom, Reference::KindArch::x86_64, - llvm::COFF::IMAGE_REL_AMD64_REL32); - return; - default: - llvm_unreachable("unsupported machine type"); - } -} - -} // end namespace pecoff -} // end namespace lld Index: lib/ReaderWriter/PECOFF/ReaderCOFF.cpp =================================================================== --- lib/ReaderWriter/PECOFF/ReaderCOFF.cpp +++ /dev/null @@ -1,1134 +0,0 @@ -//===- lib/ReaderWriter/PECOFF/ReaderCOFF.cpp -----------------------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "Atoms.h" -#include "lld/Core/Alias.h" -#include "lld/Core/File.h" -#include "lld/Core/Reader.h" -#include "lld/Driver/Driver.h" -#include "lld/ReaderWriter/PECOFFLinkingContext.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Object/COFF.h" -#include "llvm/Support/Casting.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/Endian.h" -#include "llvm/Support/Errc.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/FileOutputBuffer.h" -#include "llvm/Support/FileUtilities.h" -#include "llvm/Support/Memory.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/Program.h" -#include "llvm/Support/StringSaver.h" -#include "llvm/Support/raw_ostream.h" -#include -#include -#include -#include -#include -#include - -#define DEBUG_TYPE "ReaderCOFF" - -using lld::pecoff::COFFBSSAtom; -using lld::pecoff::COFFDefinedAtom; -using lld::pecoff::COFFDefinedFileAtom; -using lld::pecoff::COFFUndefinedAtom; -using llvm::object::coff_aux_section_definition; -using llvm::object::coff_aux_weak_external; -using llvm::object::coff_relocation; -using llvm::object::coff_section; -using llvm::object::coff_symbol; -using llvm::support::ulittle32_t; - -using namespace lld; - -namespace { - -class BumpPtrStringSaver final : public llvm::StringSaver { -public: - BumpPtrStringSaver() : llvm::StringSaver(_alloc) {} - const char *saveImpl(StringRef Str) override { - std::lock_guard lock(_allocMutex); - return llvm::StringSaver::saveImpl(Str); - } - -private: - llvm::BumpPtrAllocator _alloc; - std::mutex _allocMutex; -}; - -class FileCOFF : public File { -private: - typedef std::vector SymbolVectorT; - typedef std::map SectionToSymbolsT; - -public: - FileCOFF(std::unique_ptr mb, PECOFFLinkingContext &ctx) - : File(mb->getBufferIdentifier(), kindObject), _mb(std::move(mb)), - _compatibleWithSEH(false), _ordinal(1), - _machineType(llvm::COFF::MT_Invalid), _ctx(ctx) {} - - std::error_code doParse() override; - bool isCompatibleWithSEH() const { return _compatibleWithSEH; } - llvm::COFF::MachineTypes getMachineType() { return _machineType; } - - const AtomVector &defined() const override { - return _definedAtoms; - } - - const AtomVector &undefined() const override { - return _undefinedAtoms; - } - - const AtomVector &sharedLibrary() const override { - return _sharedLibraryAtoms; - } - - const AtomVector &absolute() const override { - return _absoluteAtoms; - } - - void beforeLink() override; - - void addUndefinedSymbol(StringRef sym) { - _undefinedAtoms.push_back(new (_alloc) COFFUndefinedAtom(*this, sym)); - } - - AliasAtom *createAlias(StringRef name, const DefinedAtom *target, int cnt); - void createAlternateNameAtoms(); - std::error_code parseDirectiveSection(StringRef directives); - - mutable llvm::BumpPtrAllocator _alloc; - -private: - std::error_code readSymbolTable(SymbolVectorT &result); - - void createAbsoluteAtoms(const SymbolVectorT &symbols, - std::vector &result); - - std::error_code - createUndefinedAtoms(const SymbolVectorT &symbols, - std::vector &result); - - std::error_code - createDefinedSymbols(const SymbolVectorT &symbols, - std::vector &result); - - std::error_code cacheSectionAttributes(); - std::error_code maybeCreateSXDataAtoms(); - - std::error_code - AtomizeDefinedSymbolsInSection(const coff_section *section, - SymbolVectorT &symbols, - std::vector &atoms); - - std::error_code - AtomizeDefinedSymbols(SectionToSymbolsT &definedSymbols, - std::vector &definedAtoms); - - std::error_code findAtomAt(const coff_section *section, - uint32_t targetAddress, - COFFDefinedFileAtom *&result, - uint32_t &offsetInAtom); - - std::error_code getAtomBySymbolIndex(uint32_t index, Atom *&ret); - - std::error_code - addRelocationReference(const coff_relocation *rel, - const coff_section *section); - - std::error_code getSectionContents(StringRef sectionName, - ArrayRef &result); - std::error_code getReferenceArch(Reference::KindArch &result); - std::error_code addRelocationReferenceToAtoms(); - std::error_code findSection(StringRef name, const coff_section *&result); - StringRef ArrayRefToString(ArrayRef array); - uint64_t getNextOrdinal(); - - std::unique_ptr _obj; - std::unique_ptr _mb; - AtomVector _definedAtoms; - AtomVector _undefinedAtoms; - AtomVector _sharedLibraryAtoms; - AtomVector _absoluteAtoms; - - // The target type of the object. - Reference::KindArch _referenceArch; - - // True if the object has "@feat.00" symbol. - bool _compatibleWithSEH; - - // A map from symbol to its name. All symbols should be in this map except - // unnamed ones. - std::map _symbolName; - - // A map from symbol to its resultant atom. - std::map _symbolAtom; - - // A map from symbol to its aux symbol. - std::map _auxSymbol; - - // A map from section to its atoms. - std::map> - _sectionAtoms; - - // A set of COMDAT sections. - std::set _comdatSections; - - // A map to get whether the section allows its contents to be merged or not. - std::map _merge; - - // COMDAT associative sections - std::multimap _association; - - // A sorted map to find an atom from a section and an offset within - // the section. - std::map> - _definedAtomLocations; - - uint64_t _ordinal; - llvm::COFF::MachineTypes _machineType; - PECOFFLinkingContext &_ctx; - mutable BumpPtrStringSaver _stringSaver; -}; - -// Converts the COFF symbol attribute to the LLD's atom attribute. -Atom::Scope getScope(llvm::object::COFFSymbolRef symbol) { - switch (symbol.getStorageClass()) { - case llvm::COFF::IMAGE_SYM_CLASS_EXTERNAL: - return Atom::scopeGlobal; - case llvm::COFF::IMAGE_SYM_CLASS_STATIC: - case llvm::COFF::IMAGE_SYM_CLASS_LABEL: - return Atom::scopeTranslationUnit; - } - llvm_unreachable("Unknown scope"); -} - -DefinedAtom::ContentType getContentType(const coff_section *section) { - if (section->Characteristics & llvm::COFF::IMAGE_SCN_CNT_CODE) - return DefinedAtom::typeCode; - if (section->Characteristics & llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) - return DefinedAtom::typeData; - if (section->Characteristics & llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) - return DefinedAtom::typeZeroFill; - return DefinedAtom::typeUnknown; -} - -DefinedAtom::ContentPermissions getPermissions(const coff_section *section) { - if (section->Characteristics & llvm::COFF::IMAGE_SCN_MEM_READ && - section->Characteristics & llvm::COFF::IMAGE_SCN_MEM_WRITE) - return DefinedAtom::permRW_; - if (section->Characteristics & llvm::COFF::IMAGE_SCN_MEM_READ && - section->Characteristics & llvm::COFF::IMAGE_SCN_MEM_EXECUTE) - return DefinedAtom::permR_X; - if (section->Characteristics & llvm::COFF::IMAGE_SCN_MEM_READ) - return DefinedAtom::permR__; - return DefinedAtom::perm___; -} - -/// Returns the alignment of the section. The contents of the section must be -/// aligned by this value in the resulting executable/DLL. -DefinedAtom::Alignment getAlignment(const coff_section *section) { - if (section->Characteristics & llvm::COFF::IMAGE_SCN_TYPE_NO_PAD) - return 1; - - // Bit [20:24] contains section alignment information. We need to decrease - // the value stored by 1 in order to get the real exponent (e.g, ALIGN_1BYTE - // is 0x00100000, but the exponent should be 0) - uint32_t characteristics = (section->Characteristics >> 20) & 0xf; - - // If all bits are off, we treat it as if ALIGN_1BYTE was on. The PE/COFF spec - // does not say anything about this case, but CVTRES.EXE does not set any bit - // in characteristics[20:24], and its output is intended to be copied to .rsrc - // section with no padding, so I think doing this is the right thing. - if (characteristics == 0) - return 1; - - uint32_t powerOf2 = characteristics - 1; - return 1 << powerOf2; -} - -DefinedAtom::Merge getMerge(const coff_aux_section_definition *auxsym) { - switch (auxsym->Selection) { - case llvm::COFF::IMAGE_COMDAT_SELECT_NODUPLICATES: - return DefinedAtom::mergeNo; - case llvm::COFF::IMAGE_COMDAT_SELECT_ANY: - return DefinedAtom::mergeAsWeakAndAddressUsed; - case llvm::COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH: - // TODO: This mapping is wrong. Fix it. - return DefinedAtom::mergeByContent; - case llvm::COFF::IMAGE_COMDAT_SELECT_SAME_SIZE: - return DefinedAtom::mergeSameNameAndSize; - case llvm::COFF::IMAGE_COMDAT_SELECT_LARGEST: - return DefinedAtom::mergeByLargestSection; - case llvm::COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE: - case llvm::COFF::IMAGE_COMDAT_SELECT_NEWEST: - // FIXME: These attributes has more complicated semantics than the regular - // weak symbol. These are mapped to mergeAsWeakAndAddressUsed for now - // because the core linker does not support them yet. We eventually have - // to implement them for full COFF support. - return DefinedAtom::mergeAsWeakAndAddressUsed; - default: - llvm_unreachable("Unknown merge type"); - } -} - -StringRef getMachineName(llvm::COFF::MachineTypes Type) { - switch (Type) { - default: llvm_unreachable("unsupported machine type"); - case llvm::COFF::IMAGE_FILE_MACHINE_ARMNT: - return "ARM"; - case llvm::COFF::IMAGE_FILE_MACHINE_I386: - return "X86"; - case llvm::COFF::IMAGE_FILE_MACHINE_AMD64: - return "X64"; - } -} - -std::error_code FileCOFF::doParse() { - auto binaryOrErr = llvm::object::createBinary(_mb->getMemBufferRef()); - if (std::error_code ec = binaryOrErr.getError()) - return ec; - std::unique_ptr bin = std::move(binaryOrErr.get()); - - _obj.reset(dyn_cast(bin.get())); - if (!_obj) - return make_error_code(llvm::object::object_error::invalid_file_type); - bin.release(); - - _machineType = static_cast(_obj->getMachine()); - - if (getMachineType() != llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN && - getMachineType() != _ctx.getMachineType()) { - return make_dynamic_error_code(Twine("module machine type '") + - getMachineName(getMachineType()) + - "' conflicts with target machine type '" + - getMachineName(_ctx.getMachineType()) + "'"); - } - - if (std::error_code ec = getReferenceArch(_referenceArch)) - return ec; - - // Read the symbol table and atomize them if possible. Defined atoms - // cannot be atomized in one pass, so they will be not be atomized but - // added to symbolToAtom. - SymbolVectorT symbols; - if (std::error_code ec = readSymbolTable(symbols)) - return ec; - - createAbsoluteAtoms(symbols, _absoluteAtoms); - if (std::error_code ec = - createUndefinedAtoms(symbols, _undefinedAtoms)) - return ec; - if (std::error_code ec = createDefinedSymbols(symbols, _definedAtoms)) - return ec; - if (std::error_code ec = addRelocationReferenceToAtoms()) - return ec; - if (std::error_code ec = maybeCreateSXDataAtoms()) - return ec; - - // Check for /SAFESEH. - if (_ctx.requireSEH() && !isCompatibleWithSEH()) { - llvm::errs() << "/SAFESEH is specified, but " - << _mb->getBufferIdentifier() - << " is not compatible with SEH.\n"; - return llvm::object::object_error::parse_failed; - } - return std::error_code(); -} - -void FileCOFF::beforeLink() { - // Acquire the mutex to mutate _ctx. - std::lock_guard lock(_ctx.getMutex()); - std::set undefSyms; - - // Interpret .drectve section if the section has contents. - ArrayRef directives; - if (getSectionContents(".drectve", directives)) - return; - if (!directives.empty()) { - std::set orig; - for (StringRef sym : _ctx.initialUndefinedSymbols()) - orig.insert(sym); - if (parseDirectiveSection(ArrayRefToString(directives))) - return; - for (StringRef sym : _ctx.initialUndefinedSymbols()) - if (orig.count(sym) == 0) - undefSyms.insert(sym); - } - - // Add /INCLUDE'ed symbols to the file as if they existed in the - // file as undefined symbols. - for (StringRef sym : undefSyms) { - addUndefinedSymbol(sym); - _ctx.addDeadStripRoot(sym); - } - - // One can define alias symbols using /alternatename:= option. - // The mapping for /alternatename is in the context object. This helper - // function iterate over defined atoms and create alias atoms if needed. - createAlternateNameAtoms(); - - // In order to emit SEH table, all input files need to be compatible with - // SEH. Disable SEH if the file being read is not compatible. - if (!isCompatibleWithSEH()) - _ctx.setSafeSEH(false); -} - -/// Iterate over the symbol table to retrieve all symbols. -std::error_code -FileCOFF::readSymbolTable(SymbolVectorT &result) { - for (uint32_t i = 0, e = _obj->getNumberOfSymbols(); i != e; ++i) { - // Retrieve the symbol. - ErrorOr sym = _obj->getSymbol(i); - StringRef name; - if (std::error_code ec = sym.getError()) - return ec; - if (sym->getSectionNumber() == llvm::COFF::IMAGE_SYM_DEBUG) - goto next; - result.push_back(*sym); - - if (std::error_code ec = _obj->getSymbolName(*sym, name)) - return ec; - - // Existence of the symbol @feat.00 indicates that object file is compatible - // with Safe Exception Handling. - if (name == "@feat.00") { - _compatibleWithSEH = true; - goto next; - } - - // Cache the name. - _symbolName[*sym] = name; - - // Symbol may be followed by auxiliary symbol table records. The aux - // record can be in any format, but the size is always the same as the - // regular symbol. The aux record supplies additional information for the - // standard symbol. We do not interpret the aux record here, but just - // store it to _auxSymbol. - if (sym->getNumberOfAuxSymbols() > 0) { - ErrorOr aux = _obj->getSymbol(i + 1); - if (std::error_code ec = aux.getError()) - return ec; - _auxSymbol[*sym] = *aux; - } - next: - i += sym->getNumberOfAuxSymbols(); - } - return std::error_code(); -} - -/// Create atoms for the absolute symbols. -void FileCOFF::createAbsoluteAtoms(const SymbolVectorT &symbols, - std::vector &result) { - for (llvm::object::COFFSymbolRef sym : symbols) { - if (sym.getSectionNumber() != llvm::COFF::IMAGE_SYM_ABSOLUTE) - continue; - auto *atom = new (_alloc) SimpleAbsoluteAtom(*this, _symbolName[sym], - getScope(sym), sym.getValue()); - result.push_back(atom); - _symbolAtom[sym] = atom; - } -} - -/// Create atoms for the undefined symbols. This code is bit complicated -/// because it supports "weak externals" mechanism of COFF. If an undefined -/// symbol (sym1) has auxiliary data, the data contains a symbol table index -/// at which the "second symbol" (sym2) for sym1 exists. If sym1 is resolved, -/// it's linked normally. If not, sym1 is resolved as if it has sym2's -/// name. This relationship between sym1 and sym2 is represented using -/// fallback mechanism of undefined symbol. -std::error_code -FileCOFF::createUndefinedAtoms(const SymbolVectorT &symbols, - std::vector &result) { - std::map - weakExternal; - std::set fallback; - for (llvm::object::COFFSymbolRef sym : symbols) { - if (sym.getSectionNumber() != llvm::COFF::IMAGE_SYM_UNDEFINED) - continue; - // Create a mapping from sym1 to sym2, if the undefined symbol has - // auxiliary data. - auto iter = _auxSymbol.find(sym); - if (iter == _auxSymbol.end()) - continue; - const coff_aux_weak_external *aux = - reinterpret_cast( - iter->second.getRawPtr()); - ErrorOr sym2 = _obj->getSymbol(aux->TagIndex); - if (std::error_code ec = sym2.getError()) - return ec; - weakExternal[sym] = *sym2; - fallback.insert(*sym2); - } - - // Create atoms for the undefined symbols. - for (llvm::object::COFFSymbolRef sym : symbols) { - if (sym.getSectionNumber() != llvm::COFF::IMAGE_SYM_UNDEFINED) - continue; - if (fallback.count(sym) > 0) - continue; - - // If the symbol has sym2, create an undefiend atom for sym2, so that we - // can pass it as a fallback atom. - UndefinedAtom *fallback = nullptr; - auto iter = weakExternal.find(sym); - if (iter != weakExternal.end()) { - llvm::object::COFFSymbolRef sym2 = iter->second; - fallback = new (_alloc) COFFUndefinedAtom(*this, _symbolName[sym2]); - _symbolAtom[sym2] = fallback; - } - - // Create an atom for the symbol. - auto *atom = - new (_alloc) COFFUndefinedAtom(*this, _symbolName[sym], fallback); - result.push_back(atom); - _symbolAtom[sym] = atom; - } - return std::error_code(); -} - -/// Create atoms for the defined symbols. This pass is a bit complicated than -/// the other two, because in order to create the atom for the defined symbol -/// we need to know the adjacent symbols. -std::error_code -FileCOFF::createDefinedSymbols(const SymbolVectorT &symbols, - std::vector &result) { - // A defined atom can be merged if its section attribute allows its contents - // to be merged. In COFF, it's not very easy to get the section attribute - // for the symbol, so scan all sections in advance and cache the attributes - // for later use. - if (std::error_code ec = cacheSectionAttributes()) - return ec; - - // Filter non-defined atoms, and group defined atoms by its section. - SectionToSymbolsT definedSymbols; - for (llvm::object::COFFSymbolRef sym : symbols) { - // A symbol with section number 0 and non-zero value represents a common - // symbol. The MS COFF spec did not give a definition of what the common - // symbol is. We should probably follow ELF's definition shown below. - // - // - If one object file has a common symbol and another has a definition, - // the common symbol is treated as an undefined reference. - // - If there is no definition for a common symbol, the program linker - // acts as though it saw a definition initialized to zero of the - // appropriate size. - // - Two object files may have common symbols of - // different sizes, in which case the program linker will use the - // largest size. - // - // FIXME: We are currently treating the common symbol as a normal - // mergeable atom. Implement the above semantcis. - if (sym.getSectionNumber() == llvm::COFF::IMAGE_SYM_UNDEFINED && - sym.getValue() > 0) { - StringRef name = _symbolName[sym]; - uint32_t size = sym.getValue(); - auto *atom = new (_alloc) - COFFBSSAtom(*this, name, getScope(sym), DefinedAtom::permRW_, - DefinedAtom::mergeAsWeakAndAddressUsed, size, getNextOrdinal()); - - // Common symbols should be aligned on natural boundaries with the maximum - // of 32 byte. It's not documented anywhere, but it's what MSVC link.exe - // seems to be doing. - atom->setAlignment(std::min((uint64_t)32, llvm::NextPowerOf2(size))); - result.push_back(atom); - continue; - } - - // Skip if it's not for defined atom. - if (sym.getSectionNumber() == llvm::COFF::IMAGE_SYM_DEBUG || - sym.getSectionNumber() == llvm::COFF::IMAGE_SYM_ABSOLUTE || - sym.getSectionNumber() == llvm::COFF::IMAGE_SYM_UNDEFINED) - continue; - - const coff_section *sec; - if (std::error_code ec = _obj->getSection(sym.getSectionNumber(), sec)) - return ec; - assert(sec && "SectionIndex > 0, Sec must be non-null!"); - - uint8_t sc = sym.getStorageClass(); - if (sc != llvm::COFF::IMAGE_SYM_CLASS_EXTERNAL && - sc != llvm::COFF::IMAGE_SYM_CLASS_STATIC && - sc != llvm::COFF::IMAGE_SYM_CLASS_FUNCTION && - sc != llvm::COFF::IMAGE_SYM_CLASS_LABEL) { - llvm::errs() << "Unable to create atom for: " << _symbolName[sym] << " (" - << static_cast(sc) << ")\n"; - return llvm::object::object_error::parse_failed; - } - - definedSymbols[sec].push_back(sym); - } - - // Atomize the defined symbols. - if (std::error_code ec = AtomizeDefinedSymbols(definedSymbols, result)) - return ec; - - return std::error_code(); -} - -// Cache the COMDAT attributes, which indicate whether the symbols in the -// section can be merged or not. -std::error_code FileCOFF::cacheSectionAttributes() { - // The COMDAT section attribute is not an attribute of coff_section, but is - // stored in the auxiliary symbol for the first symbol referring a COMDAT - // section. It feels to me that it's unnecessarily complicated, but this is - // how COFF works. - for (auto i : _auxSymbol) { - // Read a section from the file - llvm::object::COFFSymbolRef sym = i.first; - if (sym.getSectionNumber() == llvm::COFF::IMAGE_SYM_ABSOLUTE || - sym.getSectionNumber() == llvm::COFF::IMAGE_SYM_UNDEFINED) - continue; - - const coff_section *sec; - if (std::error_code ec = _obj->getSection(sym.getSectionNumber(), sec)) - return ec; - const coff_aux_section_definition *aux = - reinterpret_cast( - i.second.getRawPtr()); - - if (sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_COMDAT) { - // Read aux symbol data. - _comdatSections.insert(sec); - _merge[sec] = getMerge(aux); - } - - // Handle associative sections. - if (aux->Selection == llvm::COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) { - const coff_section *parent; - if (std::error_code ec = - _obj->getSection(aux->getNumber(sym.isBigObj()), parent)) - return ec; - _association.insert(std::make_pair(parent, sec)); - } - } - - // The sections that does not have auxiliary symbol are regular sections, in - // which symbols are not allowed to be merged. - for (const auto §ion : _obj->sections()) { - const coff_section *sec = _obj->getCOFFSection(section); - if (!_merge.count(sec)) - _merge[sec] = DefinedAtom::mergeNo; - } - return std::error_code(); -} - -/// Atomize \p symbols and append the results to \p atoms. The symbols are -/// assumed to have been defined in the \p section. -std::error_code FileCOFF::AtomizeDefinedSymbolsInSection( - const coff_section *section, SymbolVectorT &symbols, - std::vector &atoms) { - // Sort symbols by position. - std::stable_sort( - symbols.begin(), symbols.end(), - [](llvm::object::COFFSymbolRef a, llvm::object::COFFSymbolRef b) - -> bool { return a.getValue() < b.getValue(); }); - - StringRef sectionName; - if (std::error_code ec = _obj->getSectionName(section, sectionName)) - return ec; - - // BSS section does not have contents. If this is the BSS section, create - // COFFBSSAtom instead of COFFDefinedAtom. - if (section->Characteristics & llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) { - for (auto si = symbols.begin(), se = symbols.end(); si != se; ++si) { - llvm::object::COFFSymbolRef sym = *si; - uint32_t size = (si + 1 == se) ? section->SizeOfRawData - sym.getValue() - : si[1].getValue() - sym.getValue(); - auto *atom = new (_alloc) COFFBSSAtom( - *this, _symbolName[sym], getScope(sym), getPermissions(section), - DefinedAtom::mergeAsWeakAndAddressUsed, size, getNextOrdinal()); - atoms.push_back(atom); - _symbolAtom[sym] = atom; - } - return std::error_code(); - } - - ArrayRef secData; - if (std::error_code ec = _obj->getSectionContents(section, secData)) - return ec; - - // A section with IMAGE_SCN_LNK_{INFO,REMOVE} attribute will never become - // a part of the output image. That's what the COFF spec says. - if (section->Characteristics & llvm::COFF::IMAGE_SCN_LNK_INFO || - section->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE) - return std::error_code(); - - // Supporting debug info needs more work than just linking and combining - // .debug sections. We don't support it yet. Let's discard .debug sections at - // the very beginning of the process so that we don't spend time on linking - // blobs that nobody would understand. - if ((section->Characteristics & llvm::COFF::IMAGE_SCN_MEM_DISCARDABLE) && - (sectionName == ".debug" || sectionName.startswith(".debug$"))) { - return std::error_code(); - } - - DefinedAtom::ContentType type = getContentType(section); - DefinedAtom::ContentPermissions perms = getPermissions(section); - uint64_t sectionSize = section->SizeOfRawData; - bool isComdat = (_comdatSections.count(section) == 1); - - // Create an atom for the entire section. - if (symbols.empty()) { - ArrayRef data(secData.data(), secData.size()); - auto *atom = new (_alloc) COFFDefinedAtom( - *this, "", sectionName, sectionSize, Atom::scopeTranslationUnit, - type, isComdat, perms, _merge[section], data, getNextOrdinal()); - atoms.push_back(atom); - _definedAtomLocations[section].insert(std::make_pair(0, atom)); - return std::error_code(); - } - - // Create an unnamed atom if the first atom isn't at the start of the - // section. - if (symbols[0].getValue() != 0) { - uint64_t size = symbols[0].getValue(); - ArrayRef data(secData.data(), size); - auto *atom = new (_alloc) COFFDefinedAtom( - *this, "", sectionName, sectionSize, Atom::scopeTranslationUnit, - type, isComdat, perms, _merge[section], data, getNextOrdinal()); - atoms.push_back(atom); - _definedAtomLocations[section].insert(std::make_pair(0, atom)); - } - - for (auto si = symbols.begin(), se = symbols.end(); si != se; ++si) { - const uint8_t *start = secData.data() + si->getValue(); - // if this is the last symbol, take up the remaining data. - const uint8_t *end = (si + 1 == se) ? secData.data() + secData.size() - : secData.data() + (si + 1)->getValue(); - ArrayRef data(start, end); - auto *atom = new (_alloc) COFFDefinedAtom( - *this, _symbolName[*si], sectionName, sectionSize, getScope(*si), - type, isComdat, perms, _merge[section], data, getNextOrdinal()); - atoms.push_back(atom); - _symbolAtom[*si] = atom; - _definedAtomLocations[section].insert(std::make_pair(si->getValue(), atom)); - } - return std::error_code(); -} - -std::error_code FileCOFF::AtomizeDefinedSymbols( - SectionToSymbolsT &definedSymbols, - std::vector &definedAtoms) { - // For each section, make atoms for all the symbols defined in the - // section, and append the atoms to the result objects. - for (auto &i : definedSymbols) { - const coff_section *section = i.first; - SymbolVectorT &symbols = i.second; - std::vector atoms; - if (std::error_code ec = - AtomizeDefinedSymbolsInSection(section, symbols, atoms)) - return ec; - - // Set alignment to the first atom so that the section contents - // will be aligned as specified by the object section header. - if (atoms.size() > 0) - atoms[0]->setAlignment(getAlignment(section)); - - // Connect atoms with layout-after edges. It prevents atoms - // from being GC'ed if there is a reference to one of the atoms - // in the same layout-after chain. In such case we want to emit - // all the atoms appeared in the same chain, because the "live" - // atom may reference other atoms in the same chain. - if (atoms.size() >= 2) - for (auto it = atoms.begin(), e = atoms.end(); it + 1 != e; ++it) - addLayoutEdge(*it, *(it + 1), lld::Reference::kindLayoutAfter); - - for (COFFDefinedFileAtom *atom : atoms) { - _sectionAtoms[section].push_back(atom); - definedAtoms.push_back(atom); - } - } - - // A COMDAT section with SELECT_ASSOCIATIVE attribute refer to other - // section. If the referred section is linked to a binary, the - // referring section needs to be linked too. A typical use case of - // this attribute is a static initializer; a parent is a comdat BSS - // section, and a child is a static initializer code for the data. - // - // We add referring section contents to the referred section's - // associate list, so that Resolver takes care of them. - for (auto i : _association) { - const coff_section *parent = i.first; - const coff_section *child = i.second; - if (_sectionAtoms.count(child)) { - COFFDefinedFileAtom *p = _sectionAtoms[parent][0]; - p->addAssociate(_sectionAtoms[child][0]); - } - } - - return std::error_code(); -} - -/// Find the atom that is at \p targetAddress in \p section. -std::error_code FileCOFF::findAtomAt(const coff_section *section, - uint32_t targetAddress, - COFFDefinedFileAtom *&result, - uint32_t &offsetInAtom) { - auto loc = _definedAtomLocations.find(section); - if (loc == _definedAtomLocations.end()) - return llvm::object::object_error::parse_failed; - std::multimap &map = loc->second; - - auto it = map.upper_bound(targetAddress); - if (it == map.begin()) - return llvm::object::object_error::parse_failed; - --it; - uint32_t atomAddress = it->first; - result = it->second; - offsetInAtom = targetAddress - atomAddress; - return std::error_code(); -} - -/// Find the atom for the symbol that was at the \p index in the symbol -/// table. -std::error_code FileCOFF::getAtomBySymbolIndex(uint32_t index, Atom *&ret) { - ErrorOr symbol = _obj->getSymbol(index); - if (std::error_code ec = symbol.getError()) - return ec; - ret = _symbolAtom[*symbol]; - assert(ret); - return std::error_code(); -} - -/// Add relocation information to an atom based on \p rel. \p rel is an -/// relocation entry for the \p section, and \p atoms are all the atoms -/// defined in the \p section. -std::error_code FileCOFF::addRelocationReference( - const coff_relocation *rel, const coff_section *section) { - // The address of the item which relocation is applied. Section's - // VirtualAddress needs to be added for historical reasons, but the value - // is usually just zero, so adding it is usually no-op. - uint32_t itemAddress = rel->VirtualAddress + section->VirtualAddress; - - Atom *targetAtom = nullptr; - if (std::error_code ec = - getAtomBySymbolIndex(rel->SymbolTableIndex, targetAtom)) - return ec; - - COFFDefinedFileAtom *atom; - uint32_t offsetInAtom; - if (std::error_code ec = findAtomAt(section, itemAddress, atom, offsetInAtom)) - return ec; - atom->addReference(llvm::make_unique( - Reference::KindNamespace::COFF, _referenceArch, rel->Type, offsetInAtom, - targetAtom, 0)); - return std::error_code(); -} - -// Read section contents. -std::error_code FileCOFF::getSectionContents(StringRef sectionName, - ArrayRef &result) { - const coff_section *section = nullptr; - if (std::error_code ec = findSection(sectionName, section)) - return ec; - if (!section) - return std::error_code(); - if (std::error_code ec = _obj->getSectionContents(section, result)) - return ec; - return std::error_code(); -} - -AliasAtom * -FileCOFF::createAlias(StringRef name, const DefinedAtom *target, int cnt) { - AliasAtom *alias = new (_alloc) AliasAtom(*this, name); - alias->addReference(Reference::KindNamespace::all, Reference::KindArch::all, - Reference::kindLayoutAfter, 0, target, 0); - alias->setMerge(DefinedAtom::mergeAsWeak); - if (target->contentType() == DefinedAtom::typeCode) - alias->setDeadStrip(DefinedAtom::deadStripNever); - alias->setOrdinal(target->ordinal() - cnt); - return alias; -} - -void FileCOFF::createAlternateNameAtoms() { - std::vector aliases; - for (const DefinedAtom *atom : defined()) { - int cnt = 1; - for (StringRef alias : _ctx.getAlternateNames(atom->name())) - aliases.push_back(createAlias(alias, atom, cnt++)); - } - for (AliasAtom *alias : aliases) - _definedAtoms.push_back(alias); -} - -// Interpret the contents of .drectve section. If exists, the section contains -// a string containing command line options. The linker is expected to -// interpret the options as if they were given via the command line. -// -// The section mainly contains /defaultlib (-l in Unix), but can contain any -// options as long as they are valid. -std::error_code -FileCOFF::parseDirectiveSection(StringRef directives) { - DEBUG(llvm::dbgs() << ".drectve: " << directives << "\n"); - - // Split the string into tokens, as the shell would do for argv. - SmallVector tokens; - tokens.push_back("link"); // argv[0] is the command name. Will be ignored. - llvm::cl::TokenizeWindowsCommandLine(directives, _stringSaver, tokens); - tokens.push_back(nullptr); - - // Calls the command line parser to interpret the token string as if they - // were given via the command line. - int argc = tokens.size() - 1; - const char **argv = &tokens[0]; - std::string errorMessage; - llvm::raw_string_ostream stream(errorMessage); - PECOFFLinkingContext::ParseDirectives parseDirectives = - _ctx.getParseDirectives(); - bool parseFailed = !parseDirectives(argc, argv, _ctx, stream); - stream.flush(); - // Print error message if error. - if (parseFailed) { - return make_dynamic_error_code( - Twine("Failed to parse '") + directives + "'\n" - + "Reason: " + errorMessage); - } - if (!errorMessage.empty()) { - llvm::errs() << "lld warning: " << errorMessage << "\n"; - } - return std::error_code(); -} - -/// Returns the target machine type of the current object file. -std::error_code FileCOFF::getReferenceArch(Reference::KindArch &result) { - switch (_obj->getMachine()) { - case llvm::COFF::IMAGE_FILE_MACHINE_I386: - result = Reference::KindArch::x86; - return std::error_code(); - case llvm::COFF::IMAGE_FILE_MACHINE_AMD64: - result = Reference::KindArch::x86_64; - return std::error_code(); - case llvm::COFF::IMAGE_FILE_MACHINE_ARMNT: - result = Reference::KindArch::ARM; - return std::error_code(); - case llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN: - result = Reference::KindArch::all; - return std::error_code(); - } - llvm::errs() << "Unsupported machine type: 0x" - << llvm::utohexstr(_obj->getMachine()) << '\n'; - return llvm::object::object_error::parse_failed; -} - -/// Add relocation information to atoms. -std::error_code FileCOFF::addRelocationReferenceToAtoms() { - // Relocation entries are defined for each section. - for (const auto &sec : _obj->sections()) { - const coff_section *section = _obj->getCOFFSection(sec); - - // Skip if there's no atom for the section. Currently we do not create any - // atoms for some sections, such as "debug$S", and such sections need to - // be skipped here too. - if (_sectionAtoms.find(section) == _sectionAtoms.end()) - continue; - - for (const auto &reloc : sec.relocations()) { - const coff_relocation *rel = _obj->getCOFFRelocation(reloc); - if (auto ec = addRelocationReference(rel, section)) - return ec; - } - } - return std::error_code(); -} - -// Read .sxdata section if exists. .sxdata is a x86-only section that contains a -// vector of symbol offsets. The symbols pointed by this section are SEH handler -// functions contained in the same object file. The linker needs to construct a -// SEH table and emit it to executable. -// -// On x86, exception handler addresses are in stack, so they are vulnerable to -// stack overflow attack. In order to protect against it, Windows runtime uses -// the SEH table to check if a SEH handler address in stack is a real address of -// a handler created by compiler. -// -// What we want to emit from the linker is a vector of SEH handler VAs, but here -// we have a vector of offsets to the symbol table. So we convert the latter to -// the former. -std::error_code FileCOFF::maybeCreateSXDataAtoms() { - ArrayRef sxdata; - if (std::error_code ec = getSectionContents(".sxdata", sxdata)) - return ec; - if (sxdata.empty()) - return std::error_code(); - - auto *atom = new (_alloc) COFFDefinedAtom( - *this, "", ".sxdata", 0, Atom::scopeTranslationUnit, - DefinedAtom::typeData, false /*isComdat*/, DefinedAtom::permR__, - DefinedAtom::mergeNo, sxdata, getNextOrdinal()); - - const ulittle32_t *symbolIndex = - reinterpret_cast(sxdata.data()); - int numSymbols = sxdata.size() / sizeof(uint32_t); - - for (int i = 0; i < numSymbols; ++i) { - Atom *handlerFunc; - if (std::error_code ec = getAtomBySymbolIndex(symbolIndex[i], handlerFunc)) - return ec; - int offsetInAtom = i * sizeof(uint32_t); - - uint16_t rtype; - switch (_obj->getMachine()) { - case llvm::COFF::IMAGE_FILE_MACHINE_AMD64: - rtype = llvm::COFF::IMAGE_REL_AMD64_ADDR32; - break; - case llvm::COFF::IMAGE_FILE_MACHINE_I386: - rtype = llvm::COFF::IMAGE_REL_I386_DIR32; - break; - default: - llvm_unreachable("unsupported machine type"); - } - - atom->addReference(llvm::make_unique( - Reference::KindNamespace::COFF, _referenceArch, rtype, offsetInAtom, - handlerFunc, 0)); - } - - _definedAtoms.push_back(atom); - return std::error_code(); -} - -/// Find a section by name. -std::error_code FileCOFF::findSection(StringRef name, - const coff_section *&result) { - for (const auto &sec : _obj->sections()) { - const coff_section *section = _obj->getCOFFSection(sec); - StringRef sectionName; - if (auto ec = _obj->getSectionName(section, sectionName)) - return ec; - if (sectionName == name) { - result = section; - return std::error_code(); - } - } - // Section was not found, but it's not an error. This method returns - // an error only when there's a read error. - return std::error_code(); -} - -// Convert ArrayRef to std::string. The array contains a string which -// may not be terminated by NUL. -StringRef FileCOFF::ArrayRefToString(ArrayRef array) { - // .drectve sections are encoded in either ASCII or UTF-8 with BOM. - // The PE/COFF spec allows ANSI (Windows-1252 encoding), but seems - // it's no longer in use. - // Skip a UTF-8 byte marker if exists. - if (array.size() >= 3 && array[0] == 0xEF && array[1] == 0xBB && - array[2] == 0xBF) { - array = array.slice(3); - } - if (array.empty()) - return ""; - StringRef s(reinterpret_cast(array.data()), array.size()); - s = s.substr(0, s.find_first_of('\0')); - std::string *contents = new (_alloc) std::string(s.data(), s.size()); - return StringRef(*contents).trim(); -} - -// getNextOrdinal returns a monotonically increasaing uint64_t number -// starting from 1. There's a large gap between two numbers returned -// from this function, so that you can put other atoms between them. -uint64_t FileCOFF::getNextOrdinal() { - return _ordinal++ << 32; -} - -class COFFObjectReader : public Reader { -public: - COFFObjectReader(PECOFFLinkingContext &ctx) : _ctx(ctx) {} - - bool canParse(file_magic magic, MemoryBufferRef) const override { - return magic == llvm::sys::fs::file_magic::coff_object; - } - - ErrorOr> loadFile(std::unique_ptr mb, - const Registry &) const override { - // Parse the memory buffer as PECOFF file. - std::unique_ptr ret = - llvm::make_unique(std::move(mb), _ctx); - return std::move(ret); - } - -private: - PECOFFLinkingContext &_ctx; -}; - -using namespace llvm::COFF; - -const Registry::KindStrings kindStringsI386[] = { - LLD_KIND_STRING_ENTRY(IMAGE_REL_I386_ABSOLUTE), - LLD_KIND_STRING_ENTRY(IMAGE_REL_I386_DIR16), - LLD_KIND_STRING_ENTRY(IMAGE_REL_I386_REL16), - LLD_KIND_STRING_ENTRY(IMAGE_REL_I386_DIR32), - LLD_KIND_STRING_ENTRY(IMAGE_REL_I386_DIR32NB), - LLD_KIND_STRING_ENTRY(IMAGE_REL_I386_SEG12), - LLD_KIND_STRING_ENTRY(IMAGE_REL_I386_SECTION), - LLD_KIND_STRING_ENTRY(IMAGE_REL_I386_SECREL), - LLD_KIND_STRING_ENTRY(IMAGE_REL_I386_TOKEN), - LLD_KIND_STRING_ENTRY(IMAGE_REL_I386_SECREL7), - LLD_KIND_STRING_ENTRY(IMAGE_REL_I386_REL32), - LLD_KIND_STRING_END}; - -const Registry::KindStrings kindStringsAMD64[] = { - LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_ABSOLUTE), - LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_ADDR64), - LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_ADDR32), - LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_ADDR32NB), - LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_REL32), - LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_REL32_1), - LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_REL32_2), - LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_REL32_3), - LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_REL32_4), - LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_REL32_5), - LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_SECTION), - LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_SECREL), - LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_SECREL7), - LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_TOKEN), - LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_SREL32), - LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_PAIR), - LLD_KIND_STRING_ENTRY(IMAGE_REL_AMD64_SSPAN32), - LLD_KIND_STRING_END}; - -const Registry::KindStrings kindStringsARMNT[] = { - LLD_KIND_STRING_ENTRY(IMAGE_REL_ARM_ABSOLUTE), - LLD_KIND_STRING_ENTRY(IMAGE_REL_ARM_ADDR32), - LLD_KIND_STRING_ENTRY(IMAGE_REL_ARM_ADDR32NB), - LLD_KIND_STRING_ENTRY(IMAGE_REL_ARM_BRANCH24), - LLD_KIND_STRING_ENTRY(IMAGE_REL_ARM_BRANCH11), - LLD_KIND_STRING_ENTRY(IMAGE_REL_ARM_TOKEN), - LLD_KIND_STRING_ENTRY(IMAGE_REL_ARM_BLX24), - LLD_KIND_STRING_ENTRY(IMAGE_REL_ARM_BLX11), - LLD_KIND_STRING_ENTRY(IMAGE_REL_ARM_SECTION), - LLD_KIND_STRING_ENTRY(IMAGE_REL_ARM_SECREL), - LLD_KIND_STRING_ENTRY(IMAGE_REL_ARM_MOV32A), - LLD_KIND_STRING_ENTRY(IMAGE_REL_ARM_MOV32T), - LLD_KIND_STRING_ENTRY(IMAGE_REL_ARM_BRANCH20T), - LLD_KIND_STRING_ENTRY(IMAGE_REL_ARM_BRANCH24T), - LLD_KIND_STRING_ENTRY(IMAGE_REL_ARM_BLX23T), -}; - -} // end namespace anonymous - -namespace lld { - -void Registry::addSupportCOFFObjects(PECOFFLinkingContext &ctx) { - add(std::unique_ptr(new COFFObjectReader(ctx))); - addKindTable(Reference::KindNamespace::COFF, Reference::KindArch::x86, - kindStringsI386); - addKindTable(Reference::KindNamespace::COFF, Reference::KindArch::x86_64, - kindStringsAMD64); - addKindTable(Reference::KindNamespace::COFF, Reference::KindArch::ARM, - kindStringsARMNT); -} - -} Index: lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp =================================================================== --- lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp +++ /dev/null @@ -1,388 +0,0 @@ -//===- lib/ReaderWriter/PECOFF/ReaderImportHeader.cpp ---------------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file \brief This file provides a way to read an import library member in a -/// .lib file. -/// -/// Archive Files in Windows -/// ======================== -/// -/// In Windows, archive files with .lib file extension serve two different -/// purposes. -/// -/// - For static linking: An archive file in this use case contains multiple -/// regular .obj files and is used for static linking. This is the same -/// usage as .a file in Unix. -/// -/// - For dynamic linking: An archive file in this use case contains pseudo -/// .obj files to describe exported symbols of a DLL. Each pseudo .obj file -/// in an archive has a name of an exported symbol and a DLL filename from -/// which the symbol can be imported. When you link a DLL on Windows, you -/// pass the name of the .lib file for the DLL instead of the DLL filename -/// itself. That is the Windows way of linking against a shared library. -/// -/// This file contains a function to handle the pseudo object file. -/// -/// Windows Loader and Import Address Table -/// ======================================= -/// -/// Windows supports a GOT-like mechanism for DLLs. The executable using DLLs -/// contains a list of DLL names and list of symbols that need to be resolved by -/// the loader. Windows loader maps the executable and all the DLLs to memory, -/// resolves the symbols referencing items in DLLs, and updates the import -/// address table (IAT) in memory. The IAT is an array of pointers to all of the -/// data or functions in DLL referenced by the executable. You cannot access -/// items in DLLs directly. They have to be accessed through an extra level of -/// indirection. -/// -/// So, if you want to access an item in DLL, you have to go through a -/// pointer. How do you actually do that? You need a symbol for a pointer in the -/// IAT. For each symbol defined in a DLL, a symbol with "__imp_" prefix is -/// exported from the DLL for an IAT entry. For example, if you have a global -/// variable "foo" in a DLL, a pointer to the variable is available as -/// "_imp__foo". The IAT is an array of _imp__ symbols. -/// -/// Is this OK? That's not that complicated. Because items in a DLL are not -/// directly accessible, you need to access through a pointer, and the pointer -/// is available as a symbol with _imp__ prefix. -/// -/// Note 1: Although you can write code with _imp__ prefix, today's compiler and -/// linker let you write code as if there's no extra level of indirection. -/// That's why you haven't seen lots of _imp__ in your code. A variable or a -/// function declared with "dllimport" attribute is treated as an item in a DLL, -/// and the compiler automatically mangles its name and inserts the extra level -/// of indirection when accessing the item. Here are some examples: -/// -/// __declspec(dllimport) int var_in_dll; -/// var_in_dll = 3; // is equivalent to *_imp__var_in_dll = 3; -/// -/// __declspec(dllimport) int fn_in_dll(void); -/// fn_in_dll(); // is equivalent to (*_imp__fn_in_dll)(); -/// -/// It's just the compiler rewrites code for you so that you don't need to -/// handle the indirection yourself. -/// -/// Note 2: __declspec(dllimport) is mandatory for data but optional for -/// function. For a function, the linker creates a jump table with the original -/// symbol name, so that the function is accessible without _imp__ prefix. The -/// same function in a DLL can be called through two different symbols if it's -/// not dllimport'ed. -/// -/// (*_imp__fn)() -/// fn() -/// -/// The above functions do the same thing. fn's content is a JMP instruction to -/// branch to the address pointed by _imp__fn. The latter may be a little bit -/// slower than the former because it will execute the extra JMP instruction, -/// but that's usually negligible. -/// -/// If a function is dllimport'ed, which is usually done in a header file, -/// mangled name will be used at compile time so the jump table will not be -/// used. -/// -/// Because there's no way to hide the indirection for data access at link time, -/// data has to be accessed through dllimport'ed symbols or explicit _imp__ -/// prefix. -/// -/// Idata Sections in the Pseudo Object File -/// ======================================== -/// -/// The object file created by cl.exe has several sections whose name starts -/// with ".idata$" followed by a number. The contents of the sections seem the -/// fragments of a complete ".idata" section. These sections has relocations for -/// the data referenced from the idata secton. Generally, the linker discards -/// "$" and all characters that follow from the section name and merges their -/// contents to one section. So, it looks like if everything would work fine, -/// the idata section would naturally be constructed without having any special -/// code for doing that. -/// -/// However, the LLD linker cannot do that. An idata section constructed in that -/// way was never be in valid format. We don't know the reason yet. Our -/// assumption on the idata fragment could simply be wrong, or the LLD linker is -/// not powerful enough to do the job. Meanwhile, we construct the idata section -/// ourselves. All the "idata$" sections in the pseudo object file are currently -/// ignored. -/// -/// Creating Atoms for the Import Address Table -/// =========================================== -/// -/// The function in this file reads a pseudo object file and creates at most two -/// atoms. One is a shared library atom for _imp__ symbol. The another is a -/// defined atom for the JMP instruction if the symbol is for a function. -/// -//===----------------------------------------------------------------------===// - -#include "Atoms.h" -#include "lld/Core/Error.h" -#include "lld/Core/File.h" -#include "lld/Core/SharedLibraryAtom.h" -#include "lld/ReaderWriter/PECOFFLinkingContext.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/Object/COFF.h" -#include "llvm/Support/COFF.h" -#include "llvm/Support/Casting.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/Endian.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/Memory.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/raw_ostream.h" -#include -#include -#include -#include - -using namespace lld; -using namespace lld::pecoff; -using namespace llvm; -using namespace llvm::support::endian; - -#define DEBUG_TYPE "ReaderImportHeader" - -namespace lld { - -namespace { - -// This code is valid both in x86 and x64. -const uint8_t FuncAtomContentX86[] = { - 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // JMP *0x0 - 0xcc, 0xcc // INT 3; INT 3 -}; - -const uint8_t FuncAtomContentARMNT[] = { - 0x40, 0xf2, 0x00, 0x0c, // mov.w ip, #0 - 0xc0, 0xf2, 0x00, 0x0c, // mov.t ip, #0 - 0xdc, 0xf8, 0x00, 0xf0, // ldr.w pc, [ip] -}; - -static void setJumpInstTarget(COFFLinkerInternalAtom *src, const Atom *dst, - int off, MachineTypes machine) { - SimpleReference *ref; - - switch (machine) { - default: llvm::report_fatal_error("unsupported machine type"); - case llvm::COFF::IMAGE_FILE_MACHINE_I386: - ref = new SimpleReference(Reference::KindNamespace::COFF, - Reference::KindArch::x86, - llvm::COFF::IMAGE_REL_I386_DIR32, - off, dst, 0); - break; - case llvm::COFF::IMAGE_FILE_MACHINE_AMD64: - ref = new SimpleReference(Reference::KindNamespace::COFF, - Reference::KindArch::x86_64, - llvm::COFF::IMAGE_REL_AMD64_REL32, - off, dst, 0); - break; - case llvm::COFF::IMAGE_FILE_MACHINE_ARMNT: - ref = new SimpleReference(Reference::KindNamespace::COFF, - Reference::KindArch::ARM, - llvm::COFF::IMAGE_REL_ARM_MOV32T, - off, dst, 0); - break; - } - src->addReference(std::unique_ptr(ref)); -} - -/// The defined atom for jump table. -class FuncAtom : public COFFLinkerInternalAtom { -public: - FuncAtom(const File &file, StringRef symbolName, - const COFFSharedLibraryAtom *impAtom, MachineTypes machine) - : COFFLinkerInternalAtom(file, /*oridnal*/ 0, createContent(machine), - symbolName) { - size_t Offset; - - switch (machine) { - default: llvm::report_fatal_error("unsupported machine type"); - case llvm::COFF::IMAGE_FILE_MACHINE_I386: - case llvm::COFF::IMAGE_FILE_MACHINE_AMD64: - Offset = 2; - break; - case llvm::COFF::IMAGE_FILE_MACHINE_ARMNT: - Offset = 0; - break; - } - - setJumpInstTarget(this, impAtom, Offset, machine); - } - - uint64_t ordinal() const override { return 0; } - Scope scope() const override { return scopeGlobal; } - ContentType contentType() const override { return typeCode; } - Alignment alignment() const override { return 2; } - ContentPermissions permissions() const override { return permR_X; } - -private: - std::vector createContent(MachineTypes machine) const { - const uint8_t *Data; - size_t Size; - - switch (machine) { - default: llvm::report_fatal_error("unsupported machine type"); - case llvm::COFF::IMAGE_FILE_MACHINE_I386: - case llvm::COFF::IMAGE_FILE_MACHINE_AMD64: - Data = FuncAtomContentX86; - Size = sizeof(FuncAtomContentX86); - break; - case llvm::COFF::IMAGE_FILE_MACHINE_ARMNT: - Data = FuncAtomContentARMNT; - Size = sizeof(FuncAtomContentARMNT); - break; - } - - return std::vector(Data, Data + Size); - } -}; - -class FileImportLibrary : public File { -public: - FileImportLibrary(std::unique_ptr mb, MachineTypes machine) - : File(mb->getBufferIdentifier(), kindSharedLibrary), - _mb(std::move(mb)), _machine(machine) {} - - std::error_code doParse() override { - const char *buf = _mb->getBufferStart(); - const char *end = _mb->getBufferEnd(); - - // The size of the string that follows the header. - uint32_t dataSize - = read32le(buf + offsetof(COFF::ImportHeader, SizeOfData)); - - // Check if the total size is valid. - if (std::size_t(end - buf) != sizeof(COFF::ImportHeader) + dataSize) - return make_dynamic_error_code("Broken import library"); - - uint16_t hint = read16le(buf + offsetof(COFF::ImportHeader, OrdinalHint)); - StringRef symbolName(buf + sizeof(COFF::ImportHeader)); - StringRef dllName(buf + sizeof(COFF::ImportHeader) + symbolName.size() + 1); - - // TypeInfo is a bitfield. The least significant 2 bits are import - // type, followed by 3 bit import name type. - uint16_t typeInfo = read16le(buf + offsetof(COFF::ImportHeader, TypeInfo)); - int type = typeInfo & 0x3; - int nameType = (typeInfo >> 2) & 0x7; - - // Symbol name used by the linker may be different from the symbol name used - // by the loader. The latter may lack symbol decorations, or may not even - // have name if it's imported by ordinal. - StringRef importName = symbolNameToImportName(symbolName, nameType); - - const COFFSharedLibraryAtom *dataAtom = - addSharedLibraryAtom(hint, symbolName, importName, dllName); - if (type == llvm::COFF::IMPORT_CODE) - addFuncAtom(symbolName, dllName, dataAtom); - - return std::error_code(); - } - - const AtomVector &defined() const override { - return _definedAtoms; - } - - const AtomVector &undefined() const override { - return _noUndefinedAtoms; - } - - const AtomVector &sharedLibrary() const override { - return _sharedLibraryAtoms; - } - - const AtomVector &absolute() const override { - return _noAbsoluteAtoms; - } - -private: - const COFFSharedLibraryAtom *addSharedLibraryAtom(uint16_t hint, - StringRef symbolName, - StringRef importName, - StringRef dllName) { - auto *atom = new (_alloc) - COFFSharedLibraryAtom(*this, hint, symbolName, importName, dllName); - _sharedLibraryAtoms.push_back(atom); - return atom; - } - - void addFuncAtom(StringRef symbolName, StringRef dllName, - const COFFSharedLibraryAtom *impAtom) { - auto *atom = new (_alloc) FuncAtom(*this, symbolName, impAtom, _machine); - _definedAtoms.push_back(atom); - } - - AtomVector _definedAtoms; - AtomVector _sharedLibraryAtoms; - mutable llvm::BumpPtrAllocator _alloc; - - // Does the same thing as StringRef::ltrim() but removes at most one - // character. - StringRef ltrim1(StringRef str, const char *chars) const { - if (!str.empty() && strchr(chars, str[0])) - return str.substr(1); - return str; - } - - // Convert the given symbol name to the import symbol name exported by the - // DLL. - StringRef symbolNameToImportName(StringRef symbolName, int nameType) const { - StringRef ret; - switch (nameType) { - case llvm::COFF::IMPORT_ORDINAL: - // The import is by ordinal. No symbol name will be used to identify the - // item in the DLL. Only its ordinal will be used. - return ""; - case llvm::COFF::IMPORT_NAME: - // The import name in this case is identical to the symbol name. - return symbolName; - case llvm::COFF::IMPORT_NAME_NOPREFIX: - // The import name is the symbol name without leading ?, @ or _. - ret = ltrim1(symbolName, "?@_"); - break; - case llvm::COFF::IMPORT_NAME_UNDECORATE: - // Similar to NOPREFIX, but we also need to truncate at the first @. - ret = ltrim1(symbolName, "?@_"); - ret = ret.substr(0, ret.find('@')); - break; - } - std::string *str = new (_alloc) std::string(ret); - return *str; - } - - std::unique_ptr _mb; - MachineTypes _machine; -}; - -class COFFImportLibraryReader : public Reader { -public: - COFFImportLibraryReader(PECOFFLinkingContext &ctx) : _ctx(ctx) {} - - bool canParse(file_magic magic, MemoryBufferRef mb) const override { - if (mb.getBufferSize() < sizeof(COFF::ImportHeader)) - return false; - return magic == llvm::sys::fs::file_magic::coff_import_library; - } - - ErrorOr> - loadFile(std::unique_ptr mb, - const class Registry &) const override { - std::unique_ptr ret = llvm::make_unique( - std::move(mb), _ctx.getMachineType()); - return std::move(ret); - } - -private: - PECOFFLinkingContext &_ctx; -}; - -} // end anonymous namespace - -void Registry::addSupportCOFFImportLibraries(PECOFFLinkingContext &ctx) { - add(llvm::make_unique(ctx)); -} - -} // end namespace lld Index: lib/ReaderWriter/PECOFF/WriterImportLibrary.h =================================================================== --- lib/ReaderWriter/PECOFF/WriterImportLibrary.h +++ /dev/null @@ -1,23 +0,0 @@ -//===- lib/ReaderWriter/PECOFF/WriterImportLibrary.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_PE_COFF_WRITER_IMPORT_LIBRARY_H -#define LLD_READER_WRITER_PE_COFF_WRITER_IMPORT_LIBRARY_H - -namespace lld { -class PECOFFLinkingContext; - -namespace pecoff { - -void writeImportLibrary(const PECOFFLinkingContext &ctx); - -} // end namespace pecoff -} // end namespace lld - -#endif Index: lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp =================================================================== --- lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp +++ /dev/null @@ -1,118 +0,0 @@ -//===- lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp --------------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// This file is responsible for creating the Import Library file. -/// -//===----------------------------------------------------------------------===// - -#include "lld/ReaderWriter/PECOFFLinkingContext.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/FileUtilities.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/Program.h" -#include "llvm/Support/raw_ostream.h" - -namespace lld { -namespace pecoff { - -/// Creates a .def file containing the list of exported symbols. -static std::string -createModuleDefinitionFile(const PECOFFLinkingContext &ctx) { - std::string ret; - llvm::raw_string_ostream os(ret); - os << "LIBRARY \"" << llvm::sys::path::filename(ctx.outputPath()) << "\"\n" - << "EXPORTS\n"; - - for (const PECOFFLinkingContext::ExportDesc &desc : ctx.getDllExports()) { - // Symbol names in a module-definition file will be mangled by lib.exe, - // so we need to demangle them before writing to a .def file. - os << " "; - if (!desc.externalName.empty()) { - os << desc.externalName; - } else if (!desc.mangledName.empty()) { - os << ctx.undecorateSymbol(desc.mangledName); - } else { - os << ctx.undecorateSymbol(desc.name); - } - - if (!desc.isPrivate) - os << " @" << desc.ordinal; - if (desc.noname) - os << " NONAME"; - if (desc.isData) - os << " DATA"; - if (desc.isPrivate) - os << " PRIVATE"; - os << "\n"; - } - os.flush(); - return ret; -} - -static std::string writeToTempFile(StringRef contents) { - SmallString<128> path; - int fd; - if (llvm::sys::fs::createTemporaryFile("tmp", "def", fd, path)) { - llvm::errs() << "Failed to create temporary file\n"; - return ""; - } - llvm::raw_fd_ostream os(fd, /*shouldClose*/ true); - os << contents; - return path.str(); -} - -static void writeTo(StringRef path, StringRef contents) { - int fd; - if (llvm::sys::fs::openFileForWrite(path, fd, llvm::sys::fs::F_Text)) { - llvm::errs() << "Failed to open " << path << "\n"; - return; - } - llvm::raw_fd_ostream os(fd, /*shouldClose*/ true); - os << contents; -} - -/// Creates a .def file and runs lib.exe on it to create an import library. -void writeImportLibrary(const PECOFFLinkingContext &ctx) { - std::string fileContents = createModuleDefinitionFile(ctx); - - std::string program = "lib.exe"; - ErrorOr programPathOrErr = llvm::sys::findProgramByName(program); - if (!programPathOrErr) { - llvm::errs() << "Unable to find " << program << " in PATH\n"; - } else { - const std::string &programPath = *programPathOrErr; - - std::string defPath = writeToTempFile(fileContents); - llvm::FileRemover tmpFile(defPath); - - std::string defArg = "/def:"; - defArg.append(defPath); - std::string outputArg = "/out:"; - outputArg.append(ctx.getOutputImportLibraryPath()); - - std::vector args; - args.push_back(programPath.c_str()); - args.push_back("/nologo"); - args.push_back(ctx.is64Bit() ? "/machine:x64" : "/machine:x86"); - args.push_back(defArg.c_str()); - args.push_back(outputArg.c_str()); - args.push_back(nullptr); - - if (llvm::sys::ExecuteAndWait(programPath.c_str(), &args[0]) != 0) - llvm::errs() << program << " failed\n"; - } - - // If /lldmoduledeffile: is given, make a copy of the - // temporary module definition file. This feature is for unit tests. - if (!ctx.getModuleDefinitionFile().empty()) - writeTo(ctx.getModuleDefinitionFile(), fileContents); -} - -} // end namespace pecoff -} // end namespace lld Index: lib/ReaderWriter/PECOFF/WriterPECOFF.cpp =================================================================== --- lib/ReaderWriter/PECOFF/WriterPECOFF.cpp +++ /dev/null @@ -1,1417 +0,0 @@ -//===- lib/ReaderWriter/PECOFF/WriterPECOFF.cpp ---------------------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// -/// PE/COFF file consists of DOS Header, PE Header, COFF Header and Section -/// Tables followed by raw section data. -/// -/// This writer is responsible for writing Core Linker results to an Windows -/// executable file. -/// -/// This writer currently supports 32 bit PE/COFF for x86 processor only. -/// -//===----------------------------------------------------------------------===// - -#include "Atoms.h" -#include "WriterImportLibrary.h" -#include "lld/Core/DefinedAtom.h" -#include "lld/Core/File.h" -#include "lld/Core/Writer.h" -#include "lld/ReaderWriter/AtomLayout.h" -#include "lld/ReaderWriter/PECOFFLinkingContext.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/Object/COFF.h" -#include "llvm/Support/COFF.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/Endian.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/ErrorOr.h" -#include "llvm/Support/FileOutputBuffer.h" -#include "llvm/Support/Format.h" -#include -#include -#include -#include -#include - -#define DEBUG_TYPE "WriterPECOFF" - -using namespace llvm::support::endian; - -using llvm::COFF::DataDirectoryIndex; -using llvm::object::coff_runtime_function_x64; -using llvm::support::ulittle16_t; -using llvm::support::ulittle32_t; -using llvm::support::ulittle64_t; - -namespace lld { -namespace pecoff { - -// Disk sector size. Some data needs to be aligned at disk sector boundary in -// file. -static const int SECTOR_SIZE = 512; - -namespace { -class SectionChunk; - -/// A Chunk is an abstract contiguous range in an output file. -class Chunk { -public: - enum Kind { - kindHeader, - kindSection, - kindStringTable, - kindAtomChunk - }; - - explicit Chunk(Kind kind) : _kind(kind), _size(0) {} - virtual ~Chunk() {} - virtual void write(uint8_t *buffer) = 0; - virtual uint64_t size() const { return _size; } - virtual uint64_t onDiskSize() const { return size(); } - virtual uint64_t align() const { return 1; } - - uint64_t fileOffset() const { return _fileOffset; } - void setFileOffset(uint64_t fileOffset) { _fileOffset = fileOffset; } - Kind getKind() const { return _kind; } - -protected: - Kind _kind; - uint64_t _size; - uint64_t _fileOffset; -}; - -/// A HeaderChunk is an abstract class to represent a file header for -/// PE/COFF. The data in the header chunk is metadata about program and will -/// be consumed by the windows loader. HeaderChunks are not mapped to memory -/// when executed. -class HeaderChunk : public Chunk { -public: - HeaderChunk() : Chunk(kindHeader) {} - - static bool classof(const Chunk *c) { return c->getKind() == kindHeader; } -}; - -/// A DOSStubChunk represents the DOS compatible header at the beginning -/// of PE/COFF files. -class DOSStubChunk : public HeaderChunk { -public: - explicit DOSStubChunk(const PECOFFLinkingContext &ctx) - : HeaderChunk(), _ctx(ctx) { - // Minimum size of DOS stub is 64 bytes. The next block (PE header) needs to - // be aligned on 8 byte boundary. - size_t size = std::max(_ctx.getDosStub().size(), (size_t)64); - _size = llvm::RoundUpToAlignment(size, 8); - } - - void write(uint8_t *buffer) override { - ArrayRef array = _ctx.getDosStub(); - std::memcpy(buffer, array.data(), array.size()); - auto *header = reinterpret_cast(buffer); - header->AddressOfRelocationTable = sizeof(llvm::object::dos_header); - header->AddressOfNewExeHeader = _size; - } - -private: - const PECOFFLinkingContext &_ctx; -}; - -/// A PEHeaderChunk represents PE header including COFF header. -template -class PEHeaderChunk : public HeaderChunk { -public: - explicit PEHeaderChunk(const PECOFFLinkingContext &ctx); - - void write(uint8_t *buffer) override; - - void setSizeOfHeaders(uint64_t size) { - // Must be multiple of FileAlignment. - _peHeader.SizeOfHeaders = llvm::RoundUpToAlignment(size, SECTOR_SIZE); - } - - void setSizeOfCode(uint64_t size) { _peHeader.SizeOfCode = size; } - void setBaseOfCode(uint32_t rva) { _peHeader.BaseOfCode = rva; } - void setBaseOfData(uint32_t rva); - void setSizeOfImage(uint32_t size) { _peHeader.SizeOfImage = size; } - - void setSizeOfInitializedData(uint64_t size) { - _peHeader.SizeOfInitializedData = size; - } - - void setSizeOfUninitializedData(uint64_t size) { - _peHeader.SizeOfUninitializedData = size; - } - - void setNumberOfSections(uint32_t num) { _coffHeader.NumberOfSections = num; } - void setNumberOfSymbols(uint32_t num) { _coffHeader.NumberOfSymbols = num; } - - void setAddressOfEntryPoint(uint32_t address) { - _peHeader.AddressOfEntryPoint = address; - } - - void setPointerToSymbolTable(uint32_t rva) { - _coffHeader.PointerToSymbolTable = rva; - } - -private: - llvm::object::coff_file_header _coffHeader; - PEHeader _peHeader; -}; - -/// A SectionHeaderTableChunk represents Section Table Header of PE/COFF -/// format, which is a list of section headers. -class SectionHeaderTableChunk : public HeaderChunk { -public: - SectionHeaderTableChunk() : HeaderChunk() {} - void addSection(SectionChunk *chunk); - uint64_t size() const override; - void write(uint8_t *buffer) override; - -private: - static llvm::object::coff_section createSectionHeader(SectionChunk *chunk); - - std::vector _sections; -}; - -class StringTableChunk : public Chunk { -public: - StringTableChunk() : Chunk(kindStringTable) {} - - static bool classof(const Chunk *c) { - return c->getKind() == kindStringTable; - } - - uint32_t addSectionName(StringRef sectionName) { - if (_stringTable.empty()) { - // The string table immediately follows the symbol table. - // We don't really need a symbol table, but some tools (e.g. dumpbin) - // don't like zero-length symbol table. - // Make room for the empty symbol slot, which occupies 18 byte. - // We also need to reserve 4 bytes for the string table header. - int size = sizeof(llvm::object::coff_symbol16) + 4; - _stringTable.insert(_stringTable.begin(), size, 0); - // Set the name of the dummy symbol to the first string table entry. - // It's better than letting dumpbin print out a garabage as a symbol name. - char *off = _stringTable.data() + 4; - write32le(off, 4); - } - uint32_t offset = _stringTable.size(); - _stringTable.insert(_stringTable.end(), sectionName.begin(), - sectionName.end()); - _stringTable.push_back('\0'); - return offset - sizeof(llvm::object::coff_symbol16); - } - - uint64_t size() const override { return _stringTable.size(); } - - void write(uint8_t *buffer) override { - if (_stringTable.empty()) - return; - char *off = _stringTable.data() + sizeof(llvm::object::coff_symbol16); - write32le(off, _stringTable.size()); - std::memcpy(buffer, _stringTable.data(), _stringTable.size()); - } - -private: - std::vector _stringTable; -}; - -class SectionChunk : public Chunk { -public: - uint64_t onDiskSize() const override { - if (_characteristics & llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) - return 0; - return llvm::RoundUpToAlignment(size(), SECTOR_SIZE); - } - - uint64_t align() const override { return SECTOR_SIZE; } - uint32_t getCharacteristics() const { return _characteristics; } - StringRef getSectionName() const { return _sectionName; } - virtual uint64_t memAlign() const { return _memAlign; } - - static bool classof(const Chunk *c) { - Kind kind = c->getKind(); - return kind == kindSection || kind == kindAtomChunk; - } - - uint64_t getVirtualAddress() { return _virtualAddress; } - virtual void setVirtualAddress(uint32_t rva) { _virtualAddress = rva; } - - uint32_t getStringTableOffset() const { return _stringTableOffset; } - void setStringTableOffset(uint32_t offset) { _stringTableOffset = offset; } - -protected: - SectionChunk(Kind kind, StringRef sectionName, uint32_t characteristics, - const PECOFFLinkingContext &ctx) - : Chunk(kind), _sectionName(sectionName), - _characteristics(characteristics), _virtualAddress(0), - _stringTableOffset(0), _memAlign(ctx.getPageSize()) {} - -private: - StringRef _sectionName; - const uint32_t _characteristics; - uint64_t _virtualAddress; - uint32_t _stringTableOffset; - uint64_t _memAlign; -}; - -struct BaseReloc { - BaseReloc(uint64_t a, llvm::COFF::BaseRelocationType t) : addr(a), type(t) {} - uint64_t addr; - llvm::COFF::BaseRelocationType type; -}; - -/// An AtomChunk represents a section containing atoms. -class AtomChunk : public SectionChunk { -public: - AtomChunk(const PECOFFLinkingContext &ctx, StringRef name, - const std::vector &atoms); - - void write(uint8_t *buffer) override; - - uint64_t memAlign() const override; - void appendAtom(const DefinedAtom *atom); - void buildAtomRvaMap(std::map &atomRva) const; - - void applyRelocationsARM(uint8_t *buffer, - std::map &atomRva, - std::vector §ionRva, - uint64_t imageBaseAddress); - void applyRelocationsX86(uint8_t *buffer, - std::map &atomRva, - std::vector §ionRva, - uint64_t imageBaseAddress); - void applyRelocationsX64(uint8_t *buffer, - std::map &atomRva, - std::vector §ionRva, - uint64_t imageBaseAddress); - - void printAtomAddresses(uint64_t baseAddr) const; - void addBaseRelocations(std::vector &relocSites) const; - - void setVirtualAddress(uint32_t rva) override; - uint64_t getAtomVirtualAddress(StringRef name) const; - - static bool classof(const Chunk *c) { return c->getKind() == kindAtomChunk; } - -protected: - std::vector _atomLayouts; - uint64_t _virtualAddress; - -private: - uint32_t - computeCharacteristics(const PECOFFLinkingContext &ctx, StringRef name, - const std::vector &atoms) const { - return ctx.getSectionAttributes(name, - getDefaultCharacteristics(name, atoms)); - } - - uint32_t getDefaultCharacteristics( - StringRef name, const std::vector &atoms) const; - - mutable llvm::BumpPtrAllocator _alloc; - llvm::COFF::MachineTypes _machineType; - const PECOFFLinkingContext &_ctx; -}; - -/// A DataDirectoryChunk represents data directory entries that follows the PE -/// header in the output file. An entry consists of an 8 byte field that -/// indicates a relative virtual address (the starting address of the entry data -/// in memory) and 8 byte entry data size. -class DataDirectoryChunk : public HeaderChunk { -public: - DataDirectoryChunk() - : HeaderChunk(), _data(std::vector(16)) {} - - uint64_t size() const override { - return sizeof(llvm::object::data_directory) * _data.size(); - } - - void setField(DataDirectoryIndex index, uint32_t addr, uint32_t size); - void write(uint8_t *buffer) override; - -private: - std::vector _data; -}; - -/// A BaseRelocChunk represents ".reloc" section. -/// -/// .reloc section contains a list of addresses. If the PE/COFF loader decides -/// to load the binary at a memory address different from its preferred base -/// address, which is specified by ImageBase field in the COFF header, the -/// loader needs to relocate the binary, so that all the addresses in the binary -/// point to new locations. The loader will do that by fixing up the addresses -/// specified by .reloc section. -/// -/// The executable is almost always loaded at the preferred base address because -/// it's loaded into an empty address space. The DLL is however an subject of -/// load-time relocation because it may conflict with other DLLs or the -/// executable. -class BaseRelocChunk : public SectionChunk { - typedef std::vector > ChunkVectorT; - -public: - BaseRelocChunk(ChunkVectorT &chunks, const PECOFFLinkingContext &ctx) - : SectionChunk(kindSection, ".reloc", characteristics, ctx), - _ctx(ctx), _contents(createContents(chunks)) {} - - void write(uint8_t *buffer) override { - std::memcpy(buffer, &_contents[0], _contents.size()); - } - - uint64_t size() const override { return _contents.size(); } - -private: - // When loaded into memory, reloc section should be readable and writable. - static const uint32_t characteristics = - llvm::COFF::IMAGE_SCN_MEM_READ | - llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - llvm::COFF::IMAGE_SCN_MEM_DISCARDABLE; - - std::vector createContents(ChunkVectorT &chunks) const; - - // Returns a list of RVAs that needs to be relocated if the binary is loaded - // at an address different from its preferred one. - std::vector listRelocSites(ChunkVectorT &chunks) const; - - // Create the content of a relocation block. - std::vector - createBaseRelocBlock(uint64_t pageAddr, const BaseReloc *begin, - const BaseReloc *end) const; - - const PECOFFLinkingContext &_ctx; - std::vector _contents; -}; - -template -PEHeaderChunk::PEHeaderChunk(const PECOFFLinkingContext &ctx) - : HeaderChunk() { - // Set the size of the chunk and initialize the header with null bytes. - _size = sizeof(llvm::COFF::PEMagic) + sizeof(_coffHeader) + sizeof(_peHeader); - std::memset(&_coffHeader, 0, sizeof(_coffHeader)); - std::memset(&_peHeader, 0, sizeof(_peHeader)); - - _coffHeader.Machine = ctx.getMachineType(); - _coffHeader.TimeDateStamp = time(nullptr); - - // Attributes of the executable. - uint16_t characteristics = llvm::COFF::IMAGE_FILE_EXECUTABLE_IMAGE; - if (!ctx.is64Bit()) - characteristics |= llvm::COFF::IMAGE_FILE_32BIT_MACHINE; - if (ctx.isDll()) - characteristics |= llvm::COFF::IMAGE_FILE_DLL; - if (ctx.getLargeAddressAware() || ctx.is64Bit()) - characteristics |= llvm::COFF::IMAGE_FILE_LARGE_ADDRESS_AWARE; - if (ctx.getSwapRunFromCD()) - characteristics |= llvm::COFF::IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP; - if (ctx.getSwapRunFromNet()) - characteristics |= llvm::COFF::IMAGE_FILE_NET_RUN_FROM_SWAP; - if (!ctx.getBaseRelocationEnabled()) - characteristics |= llvm::COFF::IMAGE_FILE_RELOCS_STRIPPED; - - _coffHeader.Characteristics = characteristics; - - _peHeader.Magic = ctx.is64Bit() ? llvm::COFF::PE32Header::PE32_PLUS - : llvm::COFF::PE32Header::PE32; - - // The address of the executable when loaded into memory. The default for - // DLLs is 0x10000000. The default for executables is 0x400000. - _peHeader.ImageBase = ctx.getBaseAddress(); - - // Sections should be page-aligned when loaded into memory, which is 4KB on - // x86. - _peHeader.SectionAlignment = ctx.getSectionDefaultAlignment(); - - // Sections in an executable file on disk should be sector-aligned (512 byte). - _peHeader.FileAlignment = SECTOR_SIZE; - - // The version number of the resultant executable/DLL. The number is purely - // informative, and neither the linker nor the loader won't use it. User can - // set the value using /version command line option. Default is 0.0. - PECOFFLinkingContext::Version imageVersion = ctx.getImageVersion(); - _peHeader.MajorImageVersion = imageVersion.majorVersion; - _peHeader.MinorImageVersion = imageVersion.minorVersion; - - // The required Windows version number. This is the internal version and - // shouldn't be confused with product name. Windows 7 is version 6.1 and - // Windows 8 is 6.2, for example. - PECOFFLinkingContext::Version minOSVersion = ctx.getMinOSVersion(); - _peHeader.MajorOperatingSystemVersion = minOSVersion.majorVersion; - _peHeader.MinorOperatingSystemVersion = minOSVersion.minorVersion; - _peHeader.MajorSubsystemVersion = minOSVersion.majorVersion; - _peHeader.MinorSubsystemVersion = minOSVersion.minorVersion; - - _peHeader.Subsystem = ctx.getSubsystem(); - - // Despite its name, DLL characteristics field has meaning both for - // executables and DLLs. We are not very sure if the following bits must - // be set, but regular binaries seem to have these bits, so we follow - // them. - uint16_t dllCharacteristics = 0; - if (ctx.noSEH()) - dllCharacteristics |= llvm::COFF::IMAGE_DLL_CHARACTERISTICS_NO_SEH; - if (ctx.isTerminalServerAware()) - dllCharacteristics |= - llvm::COFF::IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE; - if (ctx.isNxCompat()) - dllCharacteristics |= llvm::COFF::IMAGE_DLL_CHARACTERISTICS_NX_COMPAT; - if (ctx.getDynamicBaseEnabled()) - dllCharacteristics |= llvm::COFF::IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE; - if (!ctx.getAllowBind()) - dllCharacteristics |= llvm::COFF::IMAGE_DLL_CHARACTERISTICS_NO_BIND; - if (!ctx.getAllowIsolation()) - dllCharacteristics |= llvm::COFF::IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION; - if (ctx.getHighEntropyVA() && ctx.is64Bit()) - dllCharacteristics |= llvm::COFF::IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA; - _peHeader.DLLCharacteristics = dllCharacteristics; - - _peHeader.SizeOfStackReserve = ctx.getStackReserve(); - _peHeader.SizeOfStackCommit = ctx.getStackCommit(); - _peHeader.SizeOfHeapReserve = ctx.getHeapReserve(); - _peHeader.SizeOfHeapCommit = ctx.getHeapCommit(); - - // The number of data directory entries. We always have 16 entries. - _peHeader.NumberOfRvaAndSize = 16; - - // The size of PE header including optional data directory. - _coffHeader.SizeOfOptionalHeader = sizeof(PEHeader) + - _peHeader.NumberOfRvaAndSize * sizeof(llvm::object::data_directory); -} - -template <> -void PEHeaderChunk::setBaseOfData(uint32_t rva) { - _peHeader.BaseOfData = rva; -} - -template <> -void PEHeaderChunk::setBaseOfData(uint32_t rva) { - // BaseOfData field does not exist in PE32+ header. -} - -template -void PEHeaderChunk::write(uint8_t *buffer) { - std::memcpy(buffer, llvm::COFF::PEMagic, sizeof(llvm::COFF::PEMagic)); - buffer += sizeof(llvm::COFF::PEMagic); - std::memcpy(buffer, &_coffHeader, sizeof(_coffHeader)); - buffer += sizeof(_coffHeader); - std::memcpy(buffer, &_peHeader, sizeof(_peHeader)); -} - -AtomChunk::AtomChunk(const PECOFFLinkingContext &ctx, StringRef sectionName, - const std::vector &atoms) - : SectionChunk(kindAtomChunk, sectionName, - computeCharacteristics(ctx, sectionName, atoms), ctx), - _virtualAddress(0), _machineType(ctx.getMachineType()), _ctx(ctx) { - for (auto *a : atoms) - appendAtom(a); -} - -void AtomChunk::write(uint8_t *buffer) { - if (_atomLayouts.empty()) - return; - if (getCharacteristics() & llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) - return; - if (getCharacteristics() & llvm::COFF::IMAGE_SCN_CNT_CODE) { - // Fill the section with INT 3 (0xCC) rather than NUL, so that the - // disassembler will not interpret a garbage between atoms as the beginning - // of multi-byte machine code. This does not change the behavior of - // resulting binary but help debugging. - uint8_t *start = buffer + _atomLayouts.front()->_fileOffset; - uint8_t *end = buffer + _atomLayouts.back()->_fileOffset; - memset(start, 0xCC, end - start); - } - - for (const auto *layout : _atomLayouts) { - const DefinedAtom *atom = cast(layout->_atom); - ArrayRef rawContent = atom->rawContent(); - std::memcpy(buffer + layout->_fileOffset, rawContent.data(), - rawContent.size()); - } -} - -// Add all atoms to the given map. This data will be used to do relocation. -void -AtomChunk::buildAtomRvaMap(std::map &atomRva) const { - for (const auto *layout : _atomLayouts) - atomRva[layout->_atom] = layout->_virtualAddr; -} - -static int getSectionIndex(uint64_t targetAddr, - const std::vector §ionRva) { - int i = 1; - for (uint64_t rva : sectionRva) { - if (targetAddr < rva) - return i; - ++i; - } - return i; -} - -static uint32_t getSectionStartAddr(uint64_t targetAddr, - const std::vector §ionRva) { - // Scan the list of section start addresses to find the section start address - // for the given RVA. - for (int i = 0, e = sectionRva.size(); i < e; ++i) - if (i == e - 1 || (sectionRva[i] <= targetAddr && targetAddr < sectionRva[i + 1])) - return sectionRva[i]; - llvm_unreachable("Section missing"); -} - -static void applyThumbMoveImmediate(ulittle16_t *mov, uint16_t imm) { - // MOVW(T3): |11110|i|10|0|1|0|0|imm4|0|imm3|Rd|imm8| - // imm32 = zext imm4:i:imm3:imm8 - // MOVT(T1): |11110|i|10|1|1|0|0|imm4|0|imm3|Rd|imm8| - // imm16 = imm4:i:imm3:imm8 - mov[0] = - mov[0] | (((imm & 0x0800) >> 11) << 10) | (((imm & 0xf000) >> 12) << 0); - mov[1] = - mov[1] | (((imm & 0x0700) >> 8) << 12) | (((imm & 0x00ff) >> 0) << 0); -} - -static void applyThumbBranchImmediate(ulittle16_t *bl, int32_t imm) { - // BL(T1): |11110|S|imm10|11|J1|1|J2|imm11| - // imm32 = sext S:I1:I2:imm10:imm11:'0' - // B.W(T4): |11110|S|imm10|10|J1|1|J2|imm11| - // imm32 = sext S:I1:I2:imm10:imm11:'0' - // - // I1 = ~(J1 ^ S), I2 = ~(J2 ^ S) - - assert((~abs(imm) & (~0ULL << 24)) && "bl/b.w out of range"); - - uint32_t S = (imm < 0 ? 1 : 0); - uint32_t J1 = ((~imm & 0x00800000) >> 23) ^ S; - uint32_t J2 = ((~imm & 0x00400000) >> 22) ^ S; - - bl[0] = bl[0] | (((imm & 0x003ff000) >> 12) << 0) | (S << 10); - bl[1] = bl[1] | (((imm & 0x00000ffe) >> 1) << 0) | (J2 << 11) | (J1 << 13); -} - -void AtomChunk::applyRelocationsARM(uint8_t *Buffer, - std::map &AtomRVA, - std::vector &SectionRVA, - uint64_t ImageBase) { - Buffer = Buffer + _fileOffset; - parallel_for_each(_atomLayouts.begin(), _atomLayouts.end(), - [&](const AtomLayout *layout) { - const DefinedAtom *Atom = cast(layout->_atom); - for (const Reference *R : *Atom) { - if (R->kindNamespace() != Reference::KindNamespace::COFF) - continue; - - bool AssumeTHUMBCode = false; - if (auto Target = dyn_cast(R->target())) - AssumeTHUMBCode = Target->permissions() == DefinedAtom::permR_X || - Target->permissions() == DefinedAtom::permRWX; - - const auto AtomOffset = R->offsetInAtom(); - const auto FileOffset = layout->_fileOffset; - const auto TargetAddr = AtomRVA[R->target()] | (AssumeTHUMBCode ? 1 : 0); - auto RelocSite16 = - reinterpret_cast(Buffer + FileOffset + AtomOffset); - auto RelocSite32 = - reinterpret_cast(Buffer + FileOffset + AtomOffset); - - switch (R->kindValue()) { - default: llvm_unreachable("unsupported relocation type"); - case llvm::COFF::IMAGE_REL_ARM_ADDR32: - *RelocSite32 = *RelocSite32 + TargetAddr + ImageBase; - break; - case llvm::COFF::IMAGE_REL_ARM_ADDR32NB: - *RelocSite32 = *RelocSite32 + TargetAddr; - break; - case llvm::COFF::IMAGE_REL_ARM_MOV32T: - applyThumbMoveImmediate(&RelocSite16[0], (TargetAddr + ImageBase) >> 0); - applyThumbMoveImmediate(&RelocSite16[2], (TargetAddr + ImageBase) >> 16); - break; - case llvm::COFF::IMAGE_REL_ARM_BRANCH24T: - // NOTE: the thumb bit will implicitly be truncated properly - applyThumbBranchImmediate(RelocSite16, - TargetAddr - AtomRVA[Atom] - AtomOffset - 4); - break; - case llvm::COFF::IMAGE_REL_ARM_BLX23T: - // NOTE: the thumb bit will implicitly be truncated properly - applyThumbBranchImmediate(RelocSite16, - TargetAddr - AtomRVA[Atom] - AtomOffset - 4); - break; - } - } - }); -} - -void AtomChunk::applyRelocationsX86(uint8_t *buffer, - std::map &atomRva, - std::vector §ionRva, - uint64_t imageBaseAddress) { - buffer += _fileOffset; - parallel_for_each(_atomLayouts.begin(), _atomLayouts.end(), - [&](const AtomLayout *layout) { - const DefinedAtom *atom = cast(layout->_atom); - for (const Reference *ref : *atom) { - // Skip if this reference is not for COFF relocation. - if (ref->kindNamespace() != Reference::KindNamespace::COFF) - continue; - auto relocSite32 = reinterpret_cast( - buffer + layout->_fileOffset + ref->offsetInAtom()); - auto relocSite16 = reinterpret_cast(relocSite32); - const Atom *target = ref->target(); - uint64_t targetAddr = atomRva[target]; - // Also account for whatever offset is already stored at the relocation - // site. - switch (ref->kindValue()) { - case llvm::COFF::IMAGE_REL_I386_ABSOLUTE: - // This relocation is no-op. - break; - case llvm::COFF::IMAGE_REL_I386_DIR32: - // Set target's 32-bit VA. - if (auto *abs = dyn_cast(target)) - *relocSite32 += abs->value(); - else - *relocSite32 += targetAddr + imageBaseAddress; - break; - case llvm::COFF::IMAGE_REL_I386_DIR32NB: - // Set target's 32-bit RVA. - *relocSite32 += targetAddr; - break; - case llvm::COFF::IMAGE_REL_I386_REL32: { - // Set 32-bit relative address of the target. This relocation is - // usually used for relative branch or call instruction. - uint32_t disp = atomRva[atom] + ref->offsetInAtom() + 4; - *relocSite32 += targetAddr - disp; - break; - } - case llvm::COFF::IMAGE_REL_I386_SECTION: - // The 16-bit section index that contains the target symbol. - *relocSite16 += getSectionIndex(targetAddr, sectionRva); - break; - case llvm::COFF::IMAGE_REL_I386_SECREL: - // The 32-bit relative address from the beginning of the section that - // contains the target symbol. - *relocSite32 += - targetAddr - getSectionStartAddr(targetAddr, sectionRva); - break; - default: - llvm::report_fatal_error("Unsupported relocation kind"); - } - } - }); -} - -void AtomChunk::applyRelocationsX64(uint8_t *buffer, - std::map &atomRva, - std::vector §ionRva, - uint64_t imageBase) { - buffer += _fileOffset; - parallel_for_each(_atomLayouts.begin(), _atomLayouts.end(), - [&](const AtomLayout *layout) { - const DefinedAtom *atom = cast(layout->_atom); - for (const Reference *ref : *atom) { - if (ref->kindNamespace() != Reference::KindNamespace::COFF) - continue; - - uint8_t *loc = buffer + layout->_fileOffset + ref->offsetInAtom(); - auto relocSite16 = reinterpret_cast(loc); - auto relocSite32 = reinterpret_cast(loc); - auto relocSite64 = reinterpret_cast(loc); - uint64_t targetAddr = atomRva[ref->target()]; - - switch (ref->kindValue()) { - case llvm::COFF::IMAGE_REL_AMD64_ADDR64: - *relocSite64 += targetAddr + imageBase; - break; - case llvm::COFF::IMAGE_REL_AMD64_ADDR32: - *relocSite32 += targetAddr + imageBase; - break; - case llvm::COFF::IMAGE_REL_AMD64_ADDR32NB: - *relocSite32 += targetAddr; - break; - case llvm::COFF::IMAGE_REL_AMD64_REL32: - *relocSite32 += targetAddr - atomRva[atom] - ref->offsetInAtom() - 4; - break; - case llvm::COFF::IMAGE_REL_AMD64_REL32_1: - *relocSite32 += targetAddr - atomRva[atom] - ref->offsetInAtom() - 5; - break; - case llvm::COFF::IMAGE_REL_AMD64_REL32_2: - *relocSite32 += targetAddr - atomRva[atom] - ref->offsetInAtom() - 6; - break; - case llvm::COFF::IMAGE_REL_AMD64_REL32_3: - *relocSite32 += targetAddr - atomRva[atom] - ref->offsetInAtom() - 7; - break; - case llvm::COFF::IMAGE_REL_AMD64_REL32_4: - *relocSite32 += targetAddr - atomRva[atom] - ref->offsetInAtom() - 8; - break; - case llvm::COFF::IMAGE_REL_AMD64_REL32_5: - *relocSite32 += targetAddr - atomRva[atom] - ref->offsetInAtom() - 9; - break; - case llvm::COFF::IMAGE_REL_AMD64_SECTION: - *relocSite16 += getSectionIndex(targetAddr, sectionRva) - 1; - break; - case llvm::COFF::IMAGE_REL_AMD64_SECREL: - *relocSite32 += - targetAddr - getSectionStartAddr(targetAddr, sectionRva); - break; - default: - llvm::errs() << "Kind: " << (int)ref->kindValue() << "\n"; - llvm::report_fatal_error("Unsupported relocation kind"); - } - } - }); -} - -/// Print atom VAs. Used only for debugging. -void AtomChunk::printAtomAddresses(uint64_t baseAddr) const { - for (const auto *layout : _atomLayouts) { - const DefinedAtom *atom = cast(layout->_atom); - uint64_t addr = layout->_virtualAddr; - llvm::dbgs() << llvm::format("0x%08llx: ", addr + baseAddr) - << (atom->name().empty() ? "(anonymous)" : atom->name()) - << "\n"; - } -} - -/// List all virtual addresses (and not relative virtual addresses) that need -/// to be fixed up if image base is relocated. The only relocation type that -/// needs to be fixed is DIR32 on i386. REL32 is not (and should not be) -/// fixed up because it's PC-relative. -void AtomChunk::addBaseRelocations(std::vector &relocSites) const { - for (const auto *layout : _atomLayouts) { - const DefinedAtom *atom = cast(layout->_atom); - for (const Reference *ref : *atom) { - if (ref->kindNamespace() != Reference::KindNamespace::COFF) - continue; - - // An absolute symbol points to a fixed location in memory. Their - // address should not be fixed at load time. One exception is ImageBase - // because that's relative to run-time image base address. - if (auto *abs = dyn_cast(ref->target())) - if (!abs->name().equals("__ImageBase") && - !abs->name().equals("___ImageBase")) - continue; - - uint64_t address = layout->_virtualAddr + ref->offsetInAtom(); - switch (_machineType) { - default: llvm_unreachable("unsupported machine type"); - case llvm::COFF::IMAGE_FILE_MACHINE_I386: - if (ref->kindValue() == llvm::COFF::IMAGE_REL_I386_DIR32) - relocSites.push_back( - BaseReloc(address, llvm::COFF::IMAGE_REL_BASED_HIGHLOW)); - break; - case llvm::COFF::IMAGE_FILE_MACHINE_AMD64: - if (ref->kindValue() == llvm::COFF::IMAGE_REL_AMD64_ADDR64) - relocSites.push_back( - BaseReloc(address, llvm::COFF::IMAGE_REL_BASED_DIR64)); - break; - case llvm::COFF::IMAGE_FILE_MACHINE_ARMNT: - if (ref->kindValue() == llvm::COFF::IMAGE_REL_ARM_ADDR32) - relocSites.push_back( - BaseReloc(address, llvm::COFF::IMAGE_REL_BASED_HIGHLOW)); - else if (ref->kindValue() == llvm::COFF::IMAGE_REL_ARM_MOV32T) - relocSites.push_back( - BaseReloc(address, llvm::COFF::IMAGE_REL_BASED_ARM_MOV32T)); - break; - } - } - } -} - -void AtomChunk::setVirtualAddress(uint32_t rva) { - SectionChunk::setVirtualAddress(rva); - for (AtomLayout *layout : _atomLayouts) - layout->_virtualAddr += rva; -} - -uint64_t AtomChunk::getAtomVirtualAddress(StringRef name) const { - for (auto atomLayout : _atomLayouts) - if (atomLayout->_atom->name() == name) - return atomLayout->_virtualAddr; - return 0; -} - -void DataDirectoryChunk::setField(DataDirectoryIndex index, uint32_t addr, - uint32_t size) { - llvm::object::data_directory &dir = _data[index]; - dir.RelativeVirtualAddress = addr; - dir.Size = size; -} - -void DataDirectoryChunk::write(uint8_t *buffer) { - std::memcpy(buffer, &_data[0], size()); -} - -uint64_t AtomChunk::memAlign() const { - // ReaderCOFF propagated the section alignment to the first atom in - // the section. We restore that here. - if (_atomLayouts.empty()) - return _ctx.getPageSize(); - unsigned align = _ctx.getPageSize(); - for (auto atomLayout : _atomLayouts) { - auto *atom = cast(atomLayout->_atom); - align = std::max(align, (unsigned)atom->alignment().value); - } - return align; -} - -void AtomChunk::appendAtom(const DefinedAtom *atom) { - // Atom may have to be at a proper alignment boundary. If so, move the - // pointer to make a room after the last atom before adding new one. - _size = llvm::RoundUpToAlignment(_size, atom->alignment().value); - - // Create an AtomLayout and move the current pointer. - auto *layout = new (_alloc) AtomLayout(atom, _size, _size); - _atomLayouts.push_back(layout); - _size += atom->size(); -} - -uint32_t AtomChunk::getDefaultCharacteristics( - StringRef name, const std::vector &atoms) const { - const uint32_t code = llvm::COFF::IMAGE_SCN_CNT_CODE; - const uint32_t execute = llvm::COFF::IMAGE_SCN_MEM_EXECUTE; - const uint32_t read = llvm::COFF::IMAGE_SCN_MEM_READ; - const uint32_t write = llvm::COFF::IMAGE_SCN_MEM_WRITE; - const uint32_t data = llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA; - const uint32_t bss = llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; - if (name == ".text") - return code | execute | read; - if (name == ".data") - return data | read | write; - if (name == ".rdata") - return data | read; - if (name == ".bss") - return bss | read | write; - assert(atoms.size() > 0); - switch (atoms[0]->permissions()) { - case DefinedAtom::permR__: - return data | read; - case DefinedAtom::permRW_: - return data | read | write; - case DefinedAtom::permR_X: - return code | execute | read; - case DefinedAtom::permRWX: - return code | execute | read | write; - default: - llvm_unreachable("Unsupported permission"); - } -} - -void SectionHeaderTableChunk::addSection(SectionChunk *chunk) { - _sections.push_back(chunk); -} - -uint64_t SectionHeaderTableChunk::size() const { - return _sections.size() * sizeof(llvm::object::coff_section); -} - -void SectionHeaderTableChunk::write(uint8_t *buffer) { - uint64_t offset = 0; - for (SectionChunk *chunk : _sections) { - llvm::object::coff_section header = createSectionHeader(chunk); - std::memcpy(buffer + offset, &header, sizeof(header)); - offset += sizeof(header); - } -} - -llvm::object::coff_section -SectionHeaderTableChunk::createSectionHeader(SectionChunk *chunk) { - llvm::object::coff_section header; - - // We have extended the COFF specification by allowing section names to be - // greater than eight characters. We achieve this by adding the section names - // to the string table. Binutils' linker, ld, performs the same trick. - StringRef sectionName = chunk->getSectionName(); - std::memset(header.Name, 0, llvm::COFF::NameSize); - if (uint32_t stringTableOffset = chunk->getStringTableOffset()) - sprintf(header.Name, "/%u", stringTableOffset); - else - std::strncpy(header.Name, sectionName.data(), sectionName.size()); - - uint32_t characteristics = chunk->getCharacteristics(); - header.VirtualSize = chunk->size(); - header.VirtualAddress = chunk->getVirtualAddress(); - header.SizeOfRawData = chunk->onDiskSize(); - header.PointerToRelocations = 0; - header.PointerToLinenumbers = 0; - header.NumberOfRelocations = 0; - header.NumberOfLinenumbers = 0; - header.Characteristics = characteristics; - - if (characteristics & llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) { - header.PointerToRawData = 0; - } else { - header.PointerToRawData = chunk->fileOffset(); - } - return header; -} - -/// Creates .reloc section content from the other sections. The content of -/// .reloc is basically a list of relocation sites. The relocation sites are -/// divided into blocks. Each block represents the base relocation for a 4K -/// page. -/// -/// By dividing 32 bit RVAs into blocks, COFF saves disk and memory space for -/// the base relocation. A block consists of a 32 bit page RVA and 16 bit -/// relocation entries which represent offsets in the page. That is a more -/// compact representation than a simple vector of 32 bit RVAs. -std::vector -BaseRelocChunk::createContents(ChunkVectorT &chunks) const { - std::vector contents; - std::vector relocSites = listRelocSites(chunks); - - uint64_t mask = _ctx.getPageSize() - 1; - parallel_sort(relocSites.begin(), relocSites.end(), - [=](const BaseReloc &a, const BaseReloc &b) { - return (a.addr & ~mask) < (b.addr & ~mask); - }); - - // Base relocations for the same memory page are grouped together - // and passed to createBaseRelocBlock. - for (auto it = relocSites.begin(), e = relocSites.end(); it != e;) { - auto beginIt = it; - uint64_t pageAddr = (beginIt->addr & ~mask); - for (++it; it != e; ++it) - if ((it->addr & ~mask) != pageAddr) - break; - const BaseReloc *begin = &*beginIt; - const BaseReloc *end = begin + (it - beginIt); - std::vector block = createBaseRelocBlock(pageAddr, begin, end); - contents.insert(contents.end(), block.begin(), block.end()); - } - return contents; -} - -// Returns a list of RVAs that needs to be relocated if the binary is loaded -// at an address different from its preferred one. -std::vector -BaseRelocChunk::listRelocSites(ChunkVectorT &chunks) const { - std::vector ret; - for (auto &cp : chunks) - if (AtomChunk *chunk = dyn_cast(&*cp)) - chunk->addBaseRelocations(ret); - return ret; -} - -// Create the content of a relocation block. -std::vector -BaseRelocChunk::createBaseRelocBlock(uint64_t pageAddr, - const BaseReloc *begin, - const BaseReloc *end) const { - // Relocation blocks should be padded with IMAGE_REL_I386_ABSOLUTE to be - // aligned to a DWORD size boundary. - uint32_t size = llvm::RoundUpToAlignment( - sizeof(ulittle32_t) * 2 + sizeof(ulittle16_t) * (end - begin), - sizeof(ulittle32_t)); - std::vector contents(size); - uint8_t *ptr = &contents[0]; - - // The first four bytes is the page RVA. - write32le(ptr, pageAddr); - ptr += sizeof(ulittle32_t); - - // The second four bytes is the size of the block, including the the page - // RVA and this size field. - write32le(ptr, size); - ptr += sizeof(ulittle32_t); - - uint64_t mask = _ctx.getPageSize() - 1; - for (const BaseReloc *i = begin; i < end; ++i) { - write16le(ptr, (i->type << 12) | (i->addr & mask)); - ptr += sizeof(ulittle16_t); - } - return contents; -} - -} // end anonymous namespace - -class PECOFFWriter : public Writer { -public: - explicit PECOFFWriter(const PECOFFLinkingContext &context) - : _ctx(context), _numSections(0), _imageSizeInMemory(_ctx.getPageSize()), - _imageSizeOnDisk(0) {} - - template void build(const File &linkedFile); - std::error_code writeFile(const File &linkedFile, StringRef path) override; - -private: - void applyAllRelocations(uint8_t *bufferStart); - void printAllAtomAddresses() const; - void reorderSEHTableEntries(uint8_t *bufferStart); - void reorderSEHTableEntriesX86(uint8_t *bufferStart); - void reorderSEHTableEntriesX64(uint8_t *bufferStart); - - void addChunk(Chunk *chunk); - void addSectionChunk(std::unique_ptr chunk, - SectionHeaderTableChunk *table, - StringTableChunk *stringTable); - void setImageSizeOnDisk(); - uint64_t - calcSectionSize(llvm::COFF::SectionCharacteristics sectionType) const; - - uint64_t calcSizeOfInitializedData() const { - return calcSectionSize(llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA); - } - - uint64_t calcSizeOfUninitializedData() const { - return calcSectionSize(llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA); - } - - uint64_t calcSizeOfCode() const { - return calcSectionSize(llvm::COFF::IMAGE_SCN_CNT_CODE); - } - - std::vector > _chunks; - const PECOFFLinkingContext &_ctx; - uint32_t _numSections; - - // The size of the image in memory. This is initialized with - // _ctx.getPageSize(), as the first page starting at ImageBase is usually left - // unmapped. IIUC there's no technical reason to do so, but we'll follow that - // convention so that we don't produce odd-looking binary. - uint32_t _imageSizeInMemory; - - // The size of the image on disk. This is basically the sum of all chunks in - // the output file with paddings between them. - uint32_t _imageSizeOnDisk; - - // The map from atom to its relative virtual address. - std::map _atomRva; -}; - -StringRef customSectionName(const DefinedAtom *atom) { - assert(atom->sectionChoice() == DefinedAtom::sectionCustomRequired); - StringRef s = atom->customSectionName(); - size_t pos = s.find('$'); - return (pos == StringRef::npos) ? s : s.substr(0, pos); -} - -StringRef chooseSectionByContent(const DefinedAtom *atom) { - switch (atom->contentType()) { - case DefinedAtom::typeCode: - return ".text"; - case DefinedAtom::typeZeroFill: - return ".bss"; - case DefinedAtom::typeData: - if (atom->permissions() == DefinedAtom::permR__) - return ".rdata"; - if (atom->permissions() == DefinedAtom::permRW_) - return ".data"; - break; - default: - break; - } - llvm::errs() << "Atom: contentType=" << atom->contentType() - << " permission=" << atom->permissions() << "\n"; - llvm::report_fatal_error("Failed to choose section based on content"); -} - -typedef std::map > AtomVectorMap; - -void groupAtoms(const PECOFFLinkingContext &ctx, const File &file, - AtomVectorMap &result) { - for (const DefinedAtom *atom : file.defined()) { - if (atom->sectionChoice() == DefinedAtom::sectionCustomRequired) { - StringRef section = customSectionName(atom); - result[ctx.getOutputSectionName(section)].push_back(atom); - continue; - } - if (atom->sectionChoice() == DefinedAtom::sectionBasedOnContent) { - StringRef section = chooseSectionByContent(atom); - result[ctx.getOutputSectionName(section)].push_back(atom); - continue; - } - llvm_unreachable("Unknown section choice"); - } -} - -static const DefinedAtom *findTLSUsedSymbol(const PECOFFLinkingContext &ctx, - const File &file) { - StringRef sym = ctx.decorateSymbol("_tls_used"); - for (const DefinedAtom *atom : file.defined()) - if (atom->name() == sym) - return atom; - return nullptr; -} - -// Create all chunks that consist of the output file. -template -void PECOFFWriter::build(const File &linkedFile) { - AtomVectorMap atoms; - groupAtoms(_ctx, linkedFile, atoms); - - // Create file chunks and add them to the list. - auto *dosStub = new DOSStubChunk(_ctx); - auto *peHeader = new PEHeaderChunk(_ctx); - auto *dataDirectory = new DataDirectoryChunk(); - auto *sectionTable = new SectionHeaderTableChunk(); - auto *stringTable = new StringTableChunk(); - addChunk(dosStub); - addChunk(peHeader); - addChunk(dataDirectory); - addChunk(sectionTable); - addChunk(stringTable); - - // Create sections and add the atoms to them. - for (auto i : atoms) { - StringRef sectionName = i.first; - std::vector &contents = i.second; - std::unique_ptr section( - new AtomChunk(_ctx, sectionName, contents)); - if (section->size() > 0) - addSectionChunk(std::move(section), sectionTable, stringTable); - } - - // Build atom to its RVA map. - for (std::unique_ptr &cp : _chunks) - if (AtomChunk *chunk = dyn_cast(&*cp)) - chunk->buildAtomRvaMap(_atomRva); - - // We know the addresses of all defined atoms that needs to be - // relocated. So we can create the ".reloc" section which contains - // all the relocation sites. - if (_ctx.getBaseRelocationEnabled()) { - std::unique_ptr baseReloc(new BaseRelocChunk(_chunks, _ctx)); - if (baseReloc->size()) { - SectionChunk &ref = *baseReloc; - addSectionChunk(std::move(baseReloc), sectionTable, stringTable); - dataDirectory->setField(DataDirectoryIndex::BASE_RELOCATION_TABLE, - ref.getVirtualAddress(), ref.size()); - } - } - - setImageSizeOnDisk(); - - if (stringTable->size()) { - peHeader->setPointerToSymbolTable(stringTable->fileOffset()); - peHeader->setNumberOfSymbols(1); - } - - for (std::unique_ptr &chunk : _chunks) { - SectionChunk *section = dyn_cast(chunk.get()); - if (!section) - continue; - if (section->getSectionName() == ".text") { - peHeader->setBaseOfCode(section->getVirtualAddress()); - - // Find the virtual address of the entry point symbol if any. PECOFF spec - // says that entry point for dll images is optional, in which case it must - // be set to 0. - if (_ctx.hasEntry()) { - AtomChunk *atom = cast(section); - uint64_t entryPointAddress = - atom->getAtomVirtualAddress(_ctx.getEntrySymbolName()); - - if (entryPointAddress) { - // NOTE: ARM NT assumes a pure THUMB execution, so adjust the entry - // point accordingly - if (_ctx.getMachineType() == llvm::COFF::IMAGE_FILE_MACHINE_ARMNT) - entryPointAddress |= 1; - peHeader->setAddressOfEntryPoint(entryPointAddress); - } - } else { - peHeader->setAddressOfEntryPoint(0); - } - } - StringRef name = section->getSectionName(); - if (name == ".data") { - peHeader->setBaseOfData(section->getVirtualAddress()); - continue; - } - DataDirectoryIndex ignore = DataDirectoryIndex(-1); - DataDirectoryIndex idx = llvm::StringSwitch(name) - .Case(".pdata", DataDirectoryIndex::EXCEPTION_TABLE) - .Case(".rsrc", DataDirectoryIndex::RESOURCE_TABLE) - .Case(".idata.a", DataDirectoryIndex::IAT) - .Case(".idata.d", DataDirectoryIndex::IMPORT_TABLE) - .Case(".edata", DataDirectoryIndex::EXPORT_TABLE) - .Case(".loadcfg", DataDirectoryIndex::LOAD_CONFIG_TABLE) - .Case(".didat.d", DataDirectoryIndex::DELAY_IMPORT_DESCRIPTOR) - .Default(ignore); - if (idx == ignore) - continue; - dataDirectory->setField(idx, section->getVirtualAddress(), section->size()); - } - - if (const DefinedAtom *atom = findTLSUsedSymbol(_ctx, linkedFile)) { - dataDirectory->setField(DataDirectoryIndex::TLS_TABLE, _atomRva[atom], - 0x18); - } - - // Now that we know the size and file offset of sections. Set the file - // header accordingly. - peHeader->setSizeOfCode(calcSizeOfCode()); - peHeader->setSizeOfInitializedData(calcSizeOfInitializedData()); - peHeader->setSizeOfUninitializedData(calcSizeOfUninitializedData()); - peHeader->setNumberOfSections(_numSections); - peHeader->setSizeOfImage(_imageSizeInMemory); - peHeader->setSizeOfHeaders(sectionTable->fileOffset() + sectionTable->size()); -} - -std::error_code PECOFFWriter::writeFile(const File &linkedFile, - StringRef path) { - if (_ctx.is64Bit()) { - this->build(linkedFile); - } else { - this->build(linkedFile); - } - - uint64_t totalSize = - _chunks.back()->fileOffset() + _chunks.back()->onDiskSize(); - std::unique_ptr buffer; - std::error_code ec = llvm::FileOutputBuffer::create( - path, totalSize, buffer, llvm::FileOutputBuffer::F_executable); - if (ec) - return ec; - - for (std::unique_ptr &chunk : _chunks) - chunk->write(buffer->getBufferStart() + chunk->fileOffset()); - applyAllRelocations(buffer->getBufferStart()); - reorderSEHTableEntries(buffer->getBufferStart()); - DEBUG(printAllAtomAddresses()); - - if (_ctx.isDll()) - writeImportLibrary(_ctx); - - return buffer->commit(); -} - -/// Apply relocations to the output file buffer. This two pass. In the first -/// pass, we visit all atoms to create a map from atom to its virtual -/// address. In the second pass, we visit all relocation references to fix -/// up addresses in the buffer. -void PECOFFWriter::applyAllRelocations(uint8_t *bufferStart) { - // Create the list of section start addresses. It's needed for - // relocations of SECREL type. - std::vector sectionRva; - for (auto &cp : _chunks) - if (SectionChunk *section = dyn_cast(&*cp)) - sectionRva.push_back(section->getVirtualAddress()); - - uint64_t base = _ctx.getBaseAddress(); - for (auto &cp : _chunks) { - if (AtomChunk *chunk = dyn_cast(&*cp)) { - switch (_ctx.getMachineType()) { - default: llvm_unreachable("unsupported machine type"); - case llvm::COFF::IMAGE_FILE_MACHINE_ARMNT: - chunk->applyRelocationsARM(bufferStart, _atomRva, sectionRva, base); - break; - case llvm::COFF::IMAGE_FILE_MACHINE_I386: - chunk->applyRelocationsX86(bufferStart, _atomRva, sectionRva, base); - break; - case llvm::COFF::IMAGE_FILE_MACHINE_AMD64: - chunk->applyRelocationsX64(bufferStart, _atomRva, sectionRva, base); - break; - } - } - } -} - -/// Print atom VAs. Used only for debugging. -void PECOFFWriter::printAllAtomAddresses() const { - for (auto &cp : _chunks) - if (AtomChunk *chunk = dyn_cast(&*cp)) - chunk->printAtomAddresses(_ctx.getBaseAddress()); -} - -void PECOFFWriter::reorderSEHTableEntries(uint8_t *bufferStart) { - auto machineType = _ctx.getMachineType(); - if (machineType == llvm::COFF::IMAGE_FILE_MACHINE_I386) - reorderSEHTableEntriesX86(bufferStart); - if (machineType == llvm::COFF::IMAGE_FILE_MACHINE_AMD64) - reorderSEHTableEntriesX64(bufferStart); -} - -/// It seems that the entries in .sxdata must be sorted. This function is called -/// after a COFF file image is created in memory and before it is written to -/// disk. It is safe to reorder entries at this stage because the contents of -/// the entries are RVAs and there's no reference to a .sxdata entry other than -/// to the beginning of the section. -void PECOFFWriter::reorderSEHTableEntriesX86(uint8_t *bufferStart) { - for (std::unique_ptr &chunk : _chunks) { - if (SectionChunk *section = dyn_cast(chunk.get())) { - if (section->getSectionName() == ".sxdata") { - int numEntries = section->size() / sizeof(ulittle32_t); - ulittle32_t *begin = reinterpret_cast(bufferStart + section->fileOffset()); - ulittle32_t *end = begin + numEntries; - std::sort(begin, end); - } - } - } -} - -/// The entries in .pdata must be sorted according to its BeginAddress field -/// value. It's safe to do it because of the same reason as .sxdata. -void PECOFFWriter::reorderSEHTableEntriesX64(uint8_t *bufferStart) { - for (std::unique_ptr &chunk : _chunks) { - if (SectionChunk *section = dyn_cast(chunk.get())) { - if (section->getSectionName() != ".pdata") - continue; - int numEntries = section->size() / sizeof(coff_runtime_function_x64); - coff_runtime_function_x64 *begin = - (coff_runtime_function_x64 *)(bufferStart + section->fileOffset()); - coff_runtime_function_x64 *end = begin + numEntries; - std::sort(begin, end, [](const coff_runtime_function_x64 &lhs, - const coff_runtime_function_x64 &rhs) { - return lhs.BeginAddress < rhs.BeginAddress; - }); - } - } -} - -void PECOFFWriter::addChunk(Chunk *chunk) { - _chunks.push_back(std::unique_ptr(chunk)); -} - -void PECOFFWriter::addSectionChunk(std::unique_ptr chunk, - SectionHeaderTableChunk *table, - StringTableChunk *stringTable) { - table->addSection(chunk.get()); - _numSections++; - - StringRef sectionName = chunk->getSectionName(); - if (sectionName.size() > llvm::COFF::NameSize) { - uint32_t stringTableOffset = stringTable->addSectionName(sectionName); - chunk->setStringTableOffset(stringTableOffset); - } - - // Compute and set the starting address of sections when loaded in - // memory. They are different from positions on disk because sections need - // to be sector-aligned on disk but page-aligned in memory. - _imageSizeInMemory = llvm::RoundUpToAlignment( - _imageSizeInMemory, chunk->memAlign()); - chunk->setVirtualAddress(_imageSizeInMemory); - _imageSizeInMemory = llvm::RoundUpToAlignment( - _imageSizeInMemory + chunk->size(), _ctx.getPageSize()); - _chunks.push_back(std::move(chunk)); -} - -void PECOFFWriter::setImageSizeOnDisk() { - for (auto &chunk : _chunks) { - // Compute and set the offset of the chunk in the output file. - _imageSizeOnDisk = - llvm::RoundUpToAlignment(_imageSizeOnDisk, chunk->align()); - chunk->setFileOffset(_imageSizeOnDisk); - _imageSizeOnDisk += chunk->onDiskSize(); - } -} - -uint64_t PECOFFWriter::calcSectionSize( - llvm::COFF::SectionCharacteristics sectionType) const { - uint64_t ret = 0; - for (auto &cp : _chunks) - if (SectionChunk *chunk = dyn_cast(&*cp)) - if (chunk->getCharacteristics() & sectionType) - ret += chunk->onDiskSize(); - return ret; -} - -} // end namespace pecoff - -std::unique_ptr createWriterPECOFF(const PECOFFLinkingContext &info) { - return std::unique_ptr(new pecoff::PECOFFWriter(info)); -} - -} // end namespace lld Index: test/COFF/alternatename.test =================================================================== --- test/COFF/alternatename.test +++ test/COFF/alternatename.test @@ -1,14 +1,14 @@ # RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj -# RUN: lld -flavor link2 /entry:foo /subsystem:console \ +# RUN: lld -flavor link /entry:foo /subsystem:console \ # RUN: /alternatename:foo=main /out:%t.exe %t.obj -# RUN: lld -flavor link2 /entry:foo /subsystem:console \ +# RUN: lld -flavor link /entry:foo /subsystem:console \ # RUN: /alternatename:foo=main \ # RUN: /alternatename:foo=main \ # RUN: /alternatename:nosuchsym1=nosuchsym2 \ # RUN: /out:%t.exe %t.obj # RUN: yaml2obj < %s > %t.obj -# RUN: lld -flavor link2 /entry:foo /subsystem:console /out:%t.exe %t.obj +# RUN: lld -flavor link /entry:foo /subsystem:console /out:%t.exe %t.obj --- header: Index: test/COFF/ar-comdat.test =================================================================== --- test/COFF/ar-comdat.test +++ test/COFF/ar-comdat.test @@ -1,7 +1,7 @@ # RUN: yaml2obj %s > %t1.obj # RUN: yaml2obj %s > %t2.obj # RUN: llvm-lib /out:%t.lib %t1.obj %t2.obj -# RUN: lld -flavor link2 /out:%t.exe /lldmap:%t.map /entry:main /subsystem:console %p/Inputs/ret42.obj %t.lib +# RUN: lld -flavor link /out:%t.exe /lldmap:%t.map /entry:main /subsystem:console %p/Inputs/ret42.obj %t.lib # RUN: FileCheck %s < %t.map # CHECK-NOT: .lib Index: test/COFF/armnt-blx23t.test =================================================================== --- test/COFF/armnt-blx23t.test +++ test/COFF/armnt-blx23t.test @@ -2,7 +2,7 @@ # RUN: yaml2obj < %s > %t.obj # RUN: llvm-objdump -d %t.obj | FileCheck %s -check-prefix BEFORE -# RUN: lld -flavor link2 /entry:function /subsystem:console /out:%t.exe %t.obj +# RUN: lld -flavor link /entry:function /subsystem:console /out:%t.exe %t.obj # RUN: llvm-objdump -d %t.exe | FileCheck %s -check-prefix AFTER # BEFORE: Disassembly of section .text: Index: test/COFF/armnt-branch24t.test =================================================================== --- test/COFF/armnt-branch24t.test +++ test/COFF/armnt-branch24t.test @@ -2,7 +2,7 @@ # RUN: yaml2obj < %s > %t.obj # RUN: llvm-objdump -d %t.obj | FileCheck %s -check-prefix BEFORE -# RUN: lld -flavor link2 /entry:function /subsystem:console /out:%t.exe %t.obj +# RUN: lld -flavor link /entry:function /subsystem:console /out:%t.exe %t.obj # RUN: llvm-objdump -d %t.exe | FileCheck %s -check-prefix AFTER # BEFORE: Disassembly of section .text: Index: test/COFF/armnt-entry-point.test =================================================================== --- test/COFF/armnt-entry-point.test +++ test/COFF/armnt-entry-point.test @@ -1,5 +1,5 @@ # RUN: yaml2obj < %p/Inputs/armnt-executable.obj.yaml > %t.obj -# RUN: lld -flavor link2 /out:%t.exe /entry:mainCRTStartup /subsystem:console %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:mainCRTStartup /subsystem:console %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck %s CHECK: AddressOfEntryPoint: 0x1001 Index: test/COFF/armnt-imports.test =================================================================== --- test/COFF/armnt-imports.test +++ test/COFF/armnt-imports.test @@ -1,5 +1,5 @@ # RUN: yaml2obj < %s > %t.obj -# RUN: lld -flavor link2 /out:%t.exe /subsystem:console %t.obj \ +# RUN: lld -flavor link /out:%t.exe /subsystem:console %t.obj \ # RUN: /entry:mainCRTStartup %p/Inputs/library.lib # RUN: llvm-readobj -coff-imports %t.exe | FileCheck %s Index: test/COFF/armnt-mov32t-exec.test =================================================================== --- test/COFF/armnt-mov32t-exec.test +++ test/COFF/armnt-mov32t-exec.test @@ -2,7 +2,7 @@ # RUN: yaml2obj < %s > %t.obj # RUN: llvm-objdump -d %t.obj | FileCheck %s -check-prefix BEFORE -# RUN: lld -flavor link2 /out:%t.exe /subsystem:console /entry:get_function %t.obj +# RUN: lld -flavor link /out:%t.exe /subsystem:console /entry:get_function %t.obj # RUN: llvm-objdump -d %t.exe | FileCheck %s -check-prefix AFTER # BEFORE: Disassembly of section .text: Index: test/COFF/armnt-movt32t.test =================================================================== --- test/COFF/armnt-movt32t.test +++ test/COFF/armnt-movt32t.test @@ -2,7 +2,7 @@ # RUN: yaml2obj < %s > %t.obj # RUN: llvm-objdump -d %t.obj | FileCheck %s -check-prefix BEFORE -# RUN: lld -flavor link2 /entry:get_buffer /subsystem:console /out:%t.exe %t.obj +# RUN: lld -flavor link /entry:get_buffer /subsystem:console /out:%t.exe %t.obj # RUN: llvm-objdump -d %t.exe | FileCheck %s -check-prefix AFTER # BEFORE: Disassembly of section .text: Index: test/COFF/base.test =================================================================== --- test/COFF/base.test +++ test/COFF/base.test @@ -1,6 +1,6 @@ # RUN: yaml2obj < %s > %t.obj -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=DEFAULT-HEADER %s # RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=DEFAULT-TEXT %s @@ -8,7 +8,7 @@ # DEFAULT-TEXT: Contents of section .text: # DEFAULT-TEXT-NEXT: 1000 00000040 01000000 -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj /base:0x280000000 +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj /base:0x280000000 # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=BASE-HEADER %s # RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=BASE-TEXT %s Index: test/COFF/baserel.test =================================================================== --- test/COFF/baserel.test +++ test/COFF/baserel.test @@ -1,9 +1,9 @@ # RUN: yaml2obj < %s > %t.obj # -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib # RUN: llvm-readobj -coff-basereloc %t.exe | FileCheck %s -check-prefix=BASEREL # -# RUN: lld -flavor link2 /out:%t.exe /entry:main /fixed %t.obj %p/Inputs/std64.lib +# RUN: lld -flavor link /out:%t.exe /entry:main /fixed %t.obj %p/Inputs/std64.lib # RUN: llvm-readobj -coff-basereloc %t.exe | FileCheck %s -check-prefix=NOBASEREL # # BASEREL: BaseReloc [ @@ -43,11 +43,11 @@ # NOBASEREL: BaseReloc [ # NOBASEREL-NEXT: ] # -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib # RUN: llvm-readobj -file-headers -sections %t.exe | FileCheck %s \ # RUN: --check-prefix=BASEREL-HEADER # -# RN: lld -flavor link2 /out:%t.exe /entry:main /fixed %t.obj %p/Inputs/std64.lib +# RN: lld -flavor link /out:%t.exe /entry:main /fixed %t.obj %p/Inputs/std64.lib # RN: llvm-readobj -file-headers %t.exe | FileCheck %s \ # RN: --check-prefix=NOBASEREL-HEADER # Index: test/COFF/common.test =================================================================== --- test/COFF/common.test +++ test/COFF/common.test @@ -1,5 +1,5 @@ # RUN: yaml2obj %s > %t.obj -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj %t.obj # RUN: llvm-objdump -d %t.exe | FileCheck %s # Operands of B8 (MOV EAX) are common symbols Index: test/COFF/conflict.test =================================================================== --- test/COFF/conflict.test +++ test/COFF/conflict.test @@ -1,11 +1,11 @@ # RUN: yaml2obj < %s > %t1.obj # RUN: yaml2obj < %s > %t2.obj -# RUN: not lld -flavor link2 /out:%t.exe %t1.obj %t2.obj >& %t.log +# RUN: not lld -flavor link /out:%t.exe %t1.obj %t2.obj >& %t.log # RUN: FileCheck %s < %t.log # RUN: llvm-as -o %t.lto1.obj %S/Inputs/conflict.ll # RUN: llvm-as -o %t.lto2.obj %S/Inputs/conflict.ll -# RUN: not lld -flavor link2 /out:%t.exe %t.lto1.obj %t.lto2.obj >& %t.log +# RUN: not lld -flavor link /out:%t.exe %t.lto1.obj %t.lto2.obj >& %t.log # RUN: FileCheck %s < %t.log # CHECK: duplicate symbol: foo {{.+}}1.obj and foo {{.+}}2.obj Index: test/COFF/debug.test =================================================================== --- test/COFF/debug.test +++ test/COFF/debug.test @@ -1,5 +1,5 @@ # RUN: yaml2obj %s > %t.obj -# RUN: lld -flavor link2 /out:%t.exe /entry:main /subsystem:console %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main /subsystem:console %t.obj --- header: Index: test/COFF/defparser.test =================================================================== --- test/COFF/defparser.test +++ test/COFF/defparser.test @@ -1,13 +1,13 @@ # RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj # RUN: echo -e "LIBRARY foo\nEXPORTS ? @" > %t.def -# RUN: not lld -flavor link2 /def:%t.def %t.obj +# RUN: not lld -flavor link /def:%t.def %t.obj # RUN: echo -e "LIBRARY foo\nHEAP abc" > %t.def -# RUN: not lld -flavor link2 /def:%t.def %t.obj +# RUN: not lld -flavor link /def:%t.def %t.obj # RUN: echo -e "LIBRARY foo\nSTACK abc" > %t.def -# RUN: not lld -flavor link2 /def:%t.def %t.obj +# RUN: not lld -flavor link /def:%t.def %t.obj # RUN: echo -e "foo" > %t.def -# RUN: not lld -flavor link2 /def:%t.def %t.obj +# RUN: not lld -flavor link /def:%t.def %t.obj Index: test/COFF/delayimports.test =================================================================== --- test/COFF/delayimports.test +++ test/COFF/delayimports.test @@ -1,4 +1,4 @@ -# RUN: lld -flavor link2 /out:%t.exe /entry:main /subsystem:console \ +# RUN: lld -flavor link /out:%t.exe /entry:main /subsystem:console \ # RUN: %p/Inputs/hello64.obj %p/Inputs/std64.lib /delayload:std64.DLL \ # RUN: /alternatename:__delayLoadHelper2=main # RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORT %s Index: test/COFF/delayimports32.test =================================================================== --- test/COFF/delayimports32.test +++ test/COFF/delayimports32.test @@ -1,5 +1,5 @@ # RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj -# RUN: lld -flavor link2 %t.obj %p/Inputs/std32.lib /subsystem:console \ +# RUN: lld -flavor link %t.obj %p/Inputs/std32.lib /subsystem:console \ # RUN: /entry:main@0 /alternatename:___delayLoadHelper2@8=_main@0 \ # RUN: /debug /delayload:std32.dll /out:%t.exe # RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORT %s Index: test/COFF/dll.test =================================================================== --- test/COFF/dll.test +++ test/COFF/dll.test @@ -2,7 +2,7 @@ # REQUIRES: winlib # RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj -# RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 \ +# RUN: lld -flavor link /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 \ # RUN: /export:mangled # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=EXPORT %s @@ -18,7 +18,7 @@ # RUN: yaml2obj < %p/Inputs/export2.yaml > %t5.obj # RUN: rm -f %t5.lib # RUN: llvm-ar cru %t5.lib %t5.obj -# RUN: lld -flavor link2 /out:%t5.dll /dll %t.obj %t5.lib /export:mangled2 +# RUN: lld -flavor link /out:%t5.dll /dll %t.obj %t5.lib /export:mangled2 # RUN: llvm-objdump -p %t5.dll | FileCheck -check-prefix=EXPORT2 %s EXPORT2: Export Table: @@ -29,7 +29,7 @@ EXPORT2-NEXT: 2 0x1010 exportfn3 # RUN: llvm-as -o %t.lto.obj %p/Inputs/export.ll -# RUN: lld -flavor link2 /out:%t.lto.dll /dll %t.lto.obj /export:exportfn1 /export:exportfn2 +# RUN: lld -flavor link /out:%t.lto.dll /dll %t.lto.obj /export:exportfn1 /export:exportfn2 # RUN: llvm-objdump -p %t.lto.dll | FileCheck -check-prefix=EXPORT-LTO %s EXPORT-LTO: Export Table: @@ -40,13 +40,13 @@ EXPORT-LTO-NEXT: 2 0x1020 exportfn2 EXPORT-LTO-NEXT: 3 0x1030 exportfn3 -# RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /implib:%t2.lib \ +# RUN: lld -flavor link /out:%t.dll /dll %t.obj /implib:%t2.lib \ # RUN: /export:exportfn1 /export:exportfn2 # RUN: yaml2obj < %p/Inputs/import.yaml > %t2.obj -# RUN: lld -flavor link2 /out:%t2.exe /entry:main %t2.obj %t2.lib +# RUN: lld -flavor link /out:%t2.exe /entry:main %t2.obj %t2.lib # RUN: llvm-readobj -coff-imports %t2.exe | FileCheck -check-prefix=IMPORT %s -# RUN: lld -flavor link2 /out:%t2.lto.exe /entry:main %t2.obj %t.lto.lib +# RUN: lld -flavor link /out:%t2.lto.exe /entry:main %t2.obj %t.lto.lib # RUN: llvm-readobj -coff-imports %t2.lto.exe | FileCheck -check-prefix=IMPORT %s IMPORT: Symbol: exportfn1 Index: test/COFF/driver.test =================================================================== --- test/COFF/driver.test +++ test/COFF/driver.test @@ -1,3 +1,3 @@ -# RUN: not lld -flavor link2 nosuchfile.obj >& %t.log +# RUN: not lld -flavor link nosuchfile.obj >& %t.log # RUN: FileCheck -check-prefix=MISSING %s < %t.log MISSING: nosuchfile.obj: {{[Nn]}}o such file or directory Index: test/COFF/entry-inference.test =================================================================== --- test/COFF/entry-inference.test +++ test/COFF/entry-inference.test @@ -1,17 +1,17 @@ # RUN: sed -e s/ENTRYNAME/main/ %s | yaml2obj > %t.obj -# RUN: not lld -flavor link2 /out:%t.exe %t.obj > %t.log 2>&1 +# RUN: not lld -flavor link /out:%t.exe %t.obj > %t.log 2>&1 # RUN: FileCheck -check-prefix=MAIN %s < %t.log # RUN: sed s/ENTRYNAME/wmain/ %s | yaml2obj > %t.obj -# RUN: not lld -flavor link2 /out:%t.exe %t.obj > %t.log 2>&1 +# RUN: not lld -flavor link /out:%t.exe %t.obj > %t.log 2>&1 # RUN: FileCheck -check-prefix=WMAIN %s < %t.log # RUN: sed s/ENTRYNAME/WinMain/ %s | yaml2obj > %t.obj -# RUN: not lld -flavor link2 /out:%t.exe %t.obj > %t.log 2>&1 +# RUN: not lld -flavor link /out:%t.exe %t.obj > %t.log 2>&1 # RUN: FileCheck -check-prefix=WINMAIN %s < %t.log # RUN: sed s/ENTRYNAME/wWinMain/ %s | yaml2obj > %t.obj -# RUN: not lld -flavor link2 /out:%t.exe %t.obj > %t.log 2>&1 +# RUN: not lld -flavor link /out:%t.exe %t.obj > %t.log 2>&1 # RUN: FileCheck -check-prefix=WWINMAIN %s < %t.log # MAIN: : undefined symbol: mainCRTStartup Index: test/COFF/entry-inference2.test =================================================================== --- test/COFF/entry-inference2.test +++ test/COFF/entry-inference2.test @@ -1,5 +1,5 @@ # RUN: yaml2obj < %s > %t.obj -# RUN: not lld -flavor link2 /out:%t.exe %t.obj /verbose > %t.log 2>&1 +# RUN: not lld -flavor link /out:%t.exe %t.obj /verbose > %t.log 2>&1 # RUN: FileCheck %s < %t.log # CHECK: Entry name inferred: WinMainCRTStartup Index: test/COFF/entry-inference32.test =================================================================== --- test/COFF/entry-inference32.test +++ test/COFF/entry-inference32.test @@ -1,5 +1,5 @@ # RUN: yaml2obj < %s > %t.obj -# RUN: not lld -flavor link2 /out:%t.exe %t.obj /verbose > %t.log 2>&1 +# RUN: not lld -flavor link /out:%t.exe %t.obj /verbose > %t.log 2>&1 # RUN: FileCheck %s < %t.log # CHECK: Entry name inferred: _WinMainCRTStartup Index: test/COFF/entry-mangled.test =================================================================== --- test/COFF/entry-mangled.test +++ test/COFF/entry-mangled.test @@ -1,7 +1,7 @@ # RUN: yaml2obj < %s > %t.obj -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj # RUN: llvm-as -o %t.lto.obj %S/Inputs/entry-mangled.ll -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.lto.obj +# RUN: lld -flavor link /out:%t.exe /entry:main %t.lto.obj --- header: Index: test/COFF/entrylib.ll =================================================================== --- test/COFF/entrylib.ll +++ test/COFF/entrylib.ll @@ -1,7 +1,7 @@ ; RUN: llvm-as -o %t.obj %s ; RUN: rm -f %t.lib ; RUN: llvm-ar cru %t.lib %t.obj -; RUN: lld -flavor link2 /out:%t.exe /entry:main %t.lib +; RUN: lld -flavor link /out:%t.exe /entry:main %t.lib target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-windows-msvc" Index: test/COFF/export.test =================================================================== --- test/COFF/export.test +++ test/COFF/export.test @@ -1,6 +1,6 @@ # RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj # -# RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 +# RUN: lld -flavor link /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK1 %s CHECK1: Export Table: @@ -10,7 +10,7 @@ CHECK1-NEXT: 1 0x1008 exportfn1 CHECK1-NEXT: 2 0x1010 exportfn2 -# RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /export:exportfn1,@5 /export:exportfn2 +# RUN: lld -flavor link /out:%t.dll /dll %t.obj /export:exportfn1,@5 /export:exportfn2 # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK2 %s CHECK2: Export Table: @@ -25,7 +25,7 @@ CHECK2-NEXT: 6 0x1010 exportfn2 CHECK2-NEXT: 7 0x1010 exportfn3 -# RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /export:exportfn1,@5,noname /export:exportfn2 +# RUN: lld -flavor link /out:%t.dll /dll %t.obj /export:exportfn1,@5,noname /export:exportfn2 # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK3 %s CHECK3: Export Table: @@ -39,7 +39,7 @@ CHECK3-NEXT: 5 0x1008 CHECK3-NEXT: 6 0x1010 exportfn2 -# RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /export:f1=exportfn1 /export:f2=exportfn2 +# RUN: lld -flavor link /out:%t.dll /dll %t.obj /export:f1=exportfn1 /export:f2=exportfn2 # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK4 %s CHECK4: Export Table: @@ -52,7 +52,7 @@ # RUN: echo "EXPORTS exportfn1 @3" > %t.def # RUN: echo "fn2=exportfn2 @2" >> %t.def -# RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /def:%t.def +# RUN: lld -flavor link /out:%t.dll /dll %t.obj /def:%t.def # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK5 %s CHECK5: Export Table: @@ -64,7 +64,7 @@ CHECK5-NEXT: 3 0x1008 exportfn1 CHECK5-NEXT: 4 0x1010 exportfn3 -# RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 \ +# RUN: lld -flavor link /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 \ # RUN: /export:exportfn1 /export:exportfn2,@5 >& %t.log # RUN: FileCheck -check-prefix=CHECK6 %s < %t.log Index: test/COFF/export32.test =================================================================== --- test/COFF/export32.test +++ test/COFF/export32.test @@ -1,6 +1,6 @@ # RUN: yaml2obj < %s > %t.obj # -# RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 +# RUN: lld -flavor link /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK1 %s # CHECK1: Export Table: @@ -10,7 +10,7 @@ # CHECK1-NEXT: 1 0x1008 exportfn1 # CHECK1-NEXT: 2 0x1010 exportfn2 -# RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /export:exportfn1,@5 \ +# RUN: lld -flavor link /out:%t.dll /dll %t.obj /export:exportfn1,@5 \ # RUN: /export:exportfn2 /export:mangled # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK2 %s @@ -27,7 +27,7 @@ # CHECK2-NEXT: 7 0x1010 exportfn2 # CHECK2-NEXT: 8 0x1010 exportfn3 -# RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /export:exportfn1,@5,noname /export:exportfn2 +# RUN: lld -flavor link /out:%t.dll /dll %t.obj /export:exportfn1,@5,noname /export:exportfn2 # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK3 %s # CHECK3: Export Table: @@ -41,7 +41,7 @@ # CHECK3-NEXT: 5 0x1008 # CHECK3-NEXT: 6 0x1010 exportfn2 -# RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /export:f1=exportfn1 /export:f2=exportfn2 +# RUN: lld -flavor link /out:%t.dll /dll %t.obj /export:f1=exportfn1 /export:f2=exportfn2 # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK4 %s # CHECK4: Export Table: @@ -54,7 +54,7 @@ # RUN: echo "EXPORTS exportfn1 @3" > %t.def # RUN: echo "fn2=exportfn2 @2" >> %t.def -# RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /def:%t.def +# RUN: lld -flavor link /out:%t.dll /dll %t.obj /def:%t.def # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK5 %s # CHECK5: Export Table: @@ -66,7 +66,7 @@ # CHECK5-NEXT: 3 0x1008 exportfn1 # CHECK5-NEXT: 4 0x1010 exportfn3 -# RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 \ +# RUN: lld -flavor link /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 \ # RUN: /export:exportfn1 /export:exportfn2,@5 >& %t.log # RUN: FileCheck -check-prefix=CHECK6 %s < %t.log Index: test/COFF/failifmismatch.test =================================================================== --- test/COFF/failifmismatch.test +++ test/COFF/failifmismatch.test @@ -1,11 +1,11 @@ -# RUN: lld -flavor link2 /entry:main /subsystem:console /out:%t.exe \ +# RUN: lld -flavor link /entry:main /subsystem:console /out:%t.exe \ # RUN: %p/Inputs/ret42.obj -# RUN: lld -flavor link2 /entry:main /subsystem:console /out:%t.exe \ +# RUN: lld -flavor link /entry:main /subsystem:console /out:%t.exe \ # RUN: %p/Inputs/ret42.obj /failifmismatch:k1=v1 /failifmismatch:k2=v1 -# RUN: lld -flavor link2 /entry:main /subsystem:console /out:%t.exe \ +# RUN: lld -flavor link /entry:main /subsystem:console /out:%t.exe \ # RUN: %p/Inputs/ret42.obj /failifmismatch:k1=v1 /failifmismatch:k1=v1 -# RUN: not lld -flavor link2 /entry:main /subsystem:console /out:%t.exe \ +# RUN: not lld -flavor link /entry:main /subsystem:console /out:%t.exe \ # RUN: %p/Inputs/ret42.obj /failifmismatch:k1=v1 /failifmismatch:k1=v2 Index: test/COFF/filetype.test =================================================================== --- test/COFF/filetype.test +++ test/COFF/filetype.test @@ -1,4 +1,4 @@ # Make sure input file type is detected by file magic and not by extension. # RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.lib -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.lib +# RUN: lld -flavor link /out:%t.exe /entry:main %t.lib Index: test/COFF/force.test =================================================================== --- test/COFF/force.test +++ test/COFF/force.test @@ -1,7 +1,7 @@ # RUN: yaml2obj < %s > %t.obj -# RUN: not lld -flavor link2 /out:%t.exe /entry:main %t.obj >& %t.log +# RUN: not lld -flavor link /out:%t.exe /entry:main %t.obj >& %t.log # RUN: FileCheck %s < %t.log -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj /force >& %t.log +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj /force >& %t.log # RUN: FileCheck %s < %t.log # CHECK: .obj: undefined symbol: foo Index: test/COFF/heap.test =================================================================== --- test/COFF/heap.test +++ test/COFF/heap.test @@ -1,24 +1,24 @@ # RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=DEFAULT %s DEFAULT: SizeOfHeapReserve: 1048576 DEFAULT: SizeOfHeapCommit: 4096 -# RUN: lld -flavor link2 /out:%t.exe /entry:main /heap:0x3000 %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main /heap:0x3000 %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK1 %s # RUN: echo "HEAPSIZE 12288" > %t.def -# RUN: lld -flavor link2 /out:%t.exe /entry:main /def:%t.def %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main /def:%t.def %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK1 %s CHECK1: SizeOfHeapReserve: 12288 CHECK1: SizeOfHeapCommit: 4096 -# RUN: lld -flavor link2 /out:%t.exe /entry:main /heap:0x5000,0x3000 %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main /heap:0x5000,0x3000 %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK2 %s # RUN: echo "HEAPSIZE 20480,12288" > %t.def -# RUN: lld -flavor link2 /out:%t.exe /entry:main /def:%t.def %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main /def:%t.def %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK2 %s CHECK2: SizeOfHeapReserve: 20480 Index: test/COFF/hello32.test =================================================================== --- test/COFF/hello32.test +++ test/COFF/hello32.test @@ -1,5 +1,5 @@ # RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj -# RUN: lld -flavor link2 %t.obj %p/Inputs/std32.lib /subsystem:console \ +# RUN: lld -flavor link %t.obj %p/Inputs/std32.lib /subsystem:console \ # RUN: /entry:main@0 /out:%t.exe # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=HEADER %s # RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORTS %s Index: test/COFF/help.test =================================================================== --- test/COFF/help.test +++ test/COFF/help.test @@ -1,3 +1,3 @@ -# RUN: lld -flavor link2 /help | FileCheck %s +# RUN: lld -flavor link /help | FileCheck %s CHECK: OVERVIEW: LLVM Linker Index: test/COFF/icf.test =================================================================== --- test/COFF/icf.test +++ test/COFF/icf.test @@ -4,7 +4,7 @@ # RUN: yaml2obj < %p/Inputs/icf4.yaml > %t4.obj # RUN: yaml2obj < %p/Inputs/icf5.yaml > %t5.obj # -# RUN: lld -flavor link2 /out:%t.exe /entry:main \ +# RUN: lld -flavor link /out:%t.exe /entry:main \ # RUN: %t1.obj %t2.obj %t3.obj %t4.obj %t5.obj \ # RUN: /opt:lldicf /include:icf2 /include:icf3 /include:icf4 /include:icf5 \ # RUN: /verbose >& %t.log Index: test/COFF/imports-mangle.test =================================================================== --- test/COFF/imports-mangle.test +++ test/COFF/imports-mangle.test @@ -1,5 +1,5 @@ # RUN: yaml2obj < %s > %t.obj -# RUN: lld -flavor link2 /out:%t.exe /opt:noref /entry:main \ +# RUN: lld -flavor link /out:%t.exe /opt:noref /entry:main \ # RUN: %t.obj %p/Inputs/imports-mangle.lib # RUN: llvm-readobj -coff-imports %t.exe | FileCheck %s Index: test/COFF/imports.test =================================================================== --- test/COFF/imports.test +++ test/COFF/imports.test @@ -1,11 +1,11 @@ # Verify that the lld can handle .lib files and emit .idata sections. # -# RUN: lld -flavor link2 /out:%t.exe /entry:main /subsystem:console \ +# RUN: lld -flavor link /out:%t.exe /entry:main /subsystem:console \ # RUN: %p/Inputs/hello64.obj %p/Inputs/std64.lib # RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=TEXT %s # RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORT %s -# RUN: lld -flavor link2 /out:%t.exe /entry:main /subsystem:console \ +# RUN: lld -flavor link /out:%t.exe /entry:main /subsystem:console \ # RUN: %p/Inputs/hello64.obj %p/Inputs/std64.lib /include:ExitProcess # RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=TEXT %s # RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORT %s Index: test/COFF/include.test =================================================================== --- test/COFF/include.test +++ test/COFF/include.test @@ -1,11 +1,11 @@ # RUN: yaml2obj < %s > %t.obj -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj /verbose >& %t.log +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj /verbose >& %t.log ### FileCheck doesn't like empty input, so write something. # RUN: echo dummy >> %t.log # RUN: FileCheck -check-prefix=CHECK1 %s < %t.log -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj /verbose /include:unused >& %t.log +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj /verbose /include:unused >& %t.log # RUN: echo dummy >> %t.log # RUN: FileCheck -check-prefix=CHECK2 %s < %t.log Index: test/COFF/include2.test =================================================================== --- test/COFF/include2.test +++ test/COFF/include2.test @@ -4,7 +4,7 @@ # RUN: rm -f %t2.lib %t3.lib # RUN: llvm-ar cru %t2.lib %t2.obj # RUN: llvm-ar cru %t3.lib %t3.obj -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t1.obj %t2.lib %t3.lib /verbose >& %t.log +# RUN: lld -flavor link /out:%t.exe /entry:main %t1.obj %t2.lib %t3.lib /verbose >& %t.log # RUN: FileCheck %s < %t.log CHECK: include2.test.tmp1.obj Index: test/COFF/internal.test =================================================================== --- test/COFF/internal.test +++ test/COFF/internal.test @@ -3,7 +3,7 @@ # RUN: yaml2obj < %s > %t1.obj # RUN: yaml2obj < %s > %t2.obj # RUN: yaml2obj < %p/Inputs/ret42.yaml > %t3.obj -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t1.obj %t2.obj %t3.obj +# RUN: lld -flavor link /out:%t.exe /entry:main %t1.obj %t2.obj %t3.obj --- header: Index: test/COFF/largeaddressaware.test =================================================================== --- test/COFF/largeaddressaware.test +++ test/COFF/largeaddressaware.test @@ -1,5 +1,5 @@ # RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj -# RUN: lld -flavor link2 %t.obj %p/Inputs/std32.lib /subsystem:console \ +# RUN: lld -flavor link %t.obj %p/Inputs/std32.lib /subsystem:console \ # RUN: /entry:main@0 /out:%t.exe /largeaddressaware # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=HEADER %s Index: test/COFF/libpath.test =================================================================== --- test/COFF/libpath.test +++ test/COFF/libpath.test @@ -3,14 +3,14 @@ # RUN: cp %p/Inputs/std64.lib %t/b/ # RUN: cp %p/Inputs/std64.lib %t/c/ -# RUN: env LIB=%t/a lld -flavor link2 /out:%t.exe /entry:main /verbose \ +# RUN: env LIB=%t/a lld -flavor link /out:%t.exe /entry:main /verbose \ # RUN: std64.lib /subsystem:console %p/Inputs/hello64.obj \ # RUN: /libpath:%t/b /libpath:%t/c > %t.log # RUN: FileCheck -check-prefix=CHECK1 %s < %t.log CHECK1: b{{[/\\]}}std64.lib -# RUN: lld -flavor link2 /out:%t.exe /entry:main /verbose \ +# RUN: lld -flavor link /out:%t.exe /entry:main /verbose \ # RUN: std64.lib /subsystem:console %p/Inputs/hello64.obj \ # RUN: /libpath:%t/a /libpath:%t/b /libpath:%t/c > %t.log # RUN: FileCheck -check-prefix=CHECK2 %s < %t.log Index: test/COFF/linkenv.test =================================================================== --- test/COFF/linkenv.test +++ test/COFF/linkenv.test @@ -1,4 +1,4 @@ -# RUN: env LINK=-help lld -flavor link2 > %t.log +# RUN: env LINK=-help lld -flavor link > %t.log # RUN: FileCheck %s < %t.log CHECK: OVERVIEW: LLVM Linker Index: test/COFF/lldmap.test =================================================================== --- test/COFF/lldmap.test +++ test/COFF/lldmap.test @@ -1,5 +1,5 @@ # RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj -# RUN: lld -flavor link2 /out:%t.exe /entry:main /lldmap:%t.map %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main /lldmap:%t.map %t.obj # RUN: FileCheck %s < %t.map # CHECK: .obj: Index: test/COFF/loadcfg.test =================================================================== --- test/COFF/loadcfg.test +++ test/COFF/loadcfg.test @@ -1,5 +1,5 @@ # RUN: yaml2obj < %s > %t.obj -# RUN: lld -flavor link2 /out:%t.exe %t.obj /entry:main /subsystem:console +# RUN: lld -flavor link /out:%t.exe %t.obj /entry:main /subsystem:console # RUN: llvm-readobj -file-headers %t.exe | FileCheck %s # CHECK: LoadConfigTableRVA: 0x1000 Index: test/COFF/loadcfg32.test =================================================================== --- test/COFF/loadcfg32.test +++ test/COFF/loadcfg32.test @@ -1,5 +1,5 @@ # RUN: yaml2obj < %s > %t.obj -# RUN: lld -flavor link2 /out:%t.exe %t.obj /entry:main /subsystem:console +# RUN: lld -flavor link /out:%t.exe %t.obj /entry:main /subsystem:console # RUN: llvm-readobj -file-headers %t.exe | FileCheck %s # CHECK: LoadConfigTableRVA: 0x1000 Index: test/COFF/locally-imported.test =================================================================== --- test/COFF/locally-imported.test +++ test/COFF/locally-imported.test @@ -1,5 +1,5 @@ # RUN: yaml2obj < %s > %t.obj -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj # RUN: llvm-objdump -s %t.exe | FileCheck %s # RUN: llvm-readobj -coff-basereloc %t.exe | FileCheck -check-prefix=BASEREL %s Index: test/COFF/locally-imported32.test =================================================================== --- test/COFF/locally-imported32.test +++ test/COFF/locally-imported32.test @@ -1,5 +1,5 @@ # RUN: yaml2obj < %s > %t.obj -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj # RUN: llvm-objdump -s %t.exe | FileCheck %s # CHECK: Contents of section .text: Index: test/COFF/long-section-name.test =================================================================== --- test/COFF/long-section-name.test +++ test/COFF/long-section-name.test @@ -1,5 +1,5 @@ # RUN: yaml2obj < %s > %t.obj -# RUN: lld -flavor link2 /debug /out:%t.exe /entry:main %t.obj +# RUN: lld -flavor link /debug /out:%t.exe /entry:main %t.obj # RUN: llvm-readobj -sections %t.exe | FileCheck %s # CHECK: Name: .data_long_section_name Index: test/COFF/lto-chkstk.ll =================================================================== --- test/COFF/lto-chkstk.ll +++ test/COFF/lto-chkstk.ll @@ -2,7 +2,7 @@ ; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %T/lto-chkstk-foo.obj %S/Inputs/lto-chkstk-foo.s ; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %T/lto-chkstk-chkstk.obj %S/Inputs/lto-chkstk-chkstk.s ; RUN: llvm-ar cru %t.lib %T/lto-chkstk-chkstk.obj -; RUN: lld -flavor link2 /out:%t.exe /entry:main /subsystem:console %t.obj %T/lto-chkstk-foo.obj %t.lib +; RUN: lld -flavor link /out:%t.exe /entry:main /subsystem:console %t.obj %T/lto-chkstk-foo.obj %t.lib target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-windows-msvc" Index: test/COFF/lto-comdat.ll =================================================================== --- test/COFF/lto-comdat.ll +++ test/COFF/lto-comdat.ll @@ -10,24 +10,24 @@ ; RUN: rm -f %T/comdat.lib ; RUN: llvm-ar cru %T/comdat.lib %T/comdat1.obj %T/comdat2.obj -; RUN: lld -flavor link2 /out:%T/comdat-main.exe /entry:main /subsystem:console %T/comdat-main.lto.obj %T/comdat1.lto.obj %T/comdat2.lto.obj +; RUN: lld -flavor link /out:%T/comdat-main.exe /entry:main /subsystem:console %T/comdat-main.lto.obj %T/comdat1.lto.obj %T/comdat2.lto.obj ; RUN: llvm-readobj -file-headers %T/comdat-main.exe | FileCheck -check-prefix=HEADERS-11 %s ; RUN: llvm-objdump -d %T/comdat-main.exe | FileCheck -check-prefix=TEXT-11 %s -; RUN: lld -flavor link2 /out:%T/comdat-main.exe /entry:main /subsystem:console %T/comdat-main.lto.obj %T/comdat.lto.lib +; RUN: lld -flavor link /out:%T/comdat-main.exe /entry:main /subsystem:console %T/comdat-main.lto.obj %T/comdat.lto.lib ; RUN: llvm-readobj -file-headers %T/comdat-main.exe | FileCheck -check-prefix=HEADERS-11 %s ; RUN: llvm-objdump -d %T/comdat-main.exe | FileCheck -check-prefix=TEXT-11 %s -; RUN: lld -flavor link2 /out:%T/comdat-main.exe /entry:main /subsystem:console %T/comdat-main.obj %T/comdat1.lto.obj %T/comdat2.lto.obj +; RUN: lld -flavor link /out:%T/comdat-main.exe /entry:main /subsystem:console %T/comdat-main.obj %T/comdat1.lto.obj %T/comdat2.lto.obj ; RUN: llvm-readobj -file-headers %T/comdat-main.exe | FileCheck -check-prefix=HEADERS-01 %s ; RUN: llvm-objdump -d %T/comdat-main.exe | FileCheck -check-prefix=TEXT-01 %s -; RUN: lld -flavor link2 /out:%T/comdat-main.exe /entry:main /subsystem:console %T/comdat-main.obj %T/comdat.lto.lib +; RUN: lld -flavor link /out:%T/comdat-main.exe /entry:main /subsystem:console %T/comdat-main.obj %T/comdat.lto.lib ; RUN: llvm-readobj -file-headers %T/comdat-main.exe | FileCheck -check-prefix=HEADERS-01 %s ; RUN: llvm-objdump -d %T/comdat-main.exe | FileCheck -check-prefix=TEXT-01 %s -; RUN: lld -flavor link2 /out:%T/comdat-main.exe /entry:main /subsystem:console %T/comdat-main.lto.obj %T/comdat1.obj %T/comdat2.obj +; RUN: lld -flavor link /out:%T/comdat-main.exe /entry:main /subsystem:console %T/comdat-main.lto.obj %T/comdat1.obj %T/comdat2.obj ; RUN: llvm-readobj -file-headers %T/comdat-main.exe | FileCheck -check-prefix=HEADERS-10 %s ; RUN: llvm-objdump -d %T/comdat-main.exe | FileCheck -check-prefix=TEXT-10 %s -; RUN: lld -flavor link2 /out:%T/comdat-main.exe /entry:main /subsystem:console %T/comdat-main.lto.obj %T/comdat.lib +; RUN: lld -flavor link /out:%T/comdat-main.exe /entry:main /subsystem:console %T/comdat-main.lto.obj %T/comdat.lib ; RUN: llvm-readobj -file-headers %T/comdat-main.exe | FileCheck -check-prefix=HEADERS-10 %s ; RUN: llvm-objdump -d %T/comdat-main.exe | FileCheck -check-prefix=TEXT-10 %s Index: test/COFF/lto-linker-opts.ll =================================================================== --- test/COFF/lto-linker-opts.ll +++ test/COFF/lto-linker-opts.ll @@ -1,5 +1,5 @@ ; RUN: llvm-as -o %T/lto-linker-opts.obj %s -; RUN: env LIB=%S/Inputs lld -flavor link2 /out:%T/lto-linker-opts.exe /entry:main /subsystem:console %T/lto-linker-opts.obj +; RUN: env LIB=%S/Inputs lld -flavor link /out:%T/lto-linker-opts.exe /entry:main /subsystem:console %T/lto-linker-opts.obj target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-windows-msvc" Index: test/COFF/lto-new-symbol.ll =================================================================== --- test/COFF/lto-new-symbol.ll +++ test/COFF/lto-new-symbol.ll @@ -1,5 +1,5 @@ ; RUN: llvm-as -o %t.obj %s -; RUN: lld -flavor link2 /out:%t.exe /entry:foo /subsystem:console %t.obj +; RUN: lld -flavor link /out:%t.exe /entry:foo /subsystem:console %t.obj target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-windows-msvc" Index: test/COFF/lto.ll =================================================================== --- test/COFF/lto.ll +++ test/COFF/lto.ll @@ -8,24 +8,24 @@ ; RUN: rm -f %T/foo.lib ; RUN: llvm-ar cru %T/foo.lib %T/foo.obj -; RUN: lld -flavor link2 /out:%T/main.exe /entry:main /include:f2 /subsystem:console %T/main.lto.obj %T/foo.lto.obj +; RUN: lld -flavor link /out:%T/main.exe /entry:main /include:f2 /subsystem:console %T/main.lto.obj %T/foo.lto.obj ; RUN: llvm-readobj -file-headers %T/main.exe | FileCheck -check-prefix=HEADERS-11 %s ; RUN: llvm-objdump -d %T/main.exe | FileCheck -check-prefix=TEXT-11 %s -; RUN: lld -flavor link2 /out:%T/main.exe /entry:main /include:f2 /subsystem:console %T/main.lto.obj %T/foo.lto.lib /verbose 2>&1 | FileCheck -check-prefix=VERBOSE %s +; RUN: lld -flavor link /out:%T/main.exe /entry:main /include:f2 /subsystem:console %T/main.lto.obj %T/foo.lto.lib /verbose 2>&1 | FileCheck -check-prefix=VERBOSE %s ; RUN: llvm-readobj -file-headers %T/main.exe | FileCheck -check-prefix=HEADERS-11 %s ; RUN: llvm-objdump -d %T/main.exe | FileCheck -check-prefix=TEXT-11 %s -; RUN: lld -flavor link2 /out:%T/main.exe /entry:main /subsystem:console %T/main.obj %T/foo.lto.obj +; RUN: lld -flavor link /out:%T/main.exe /entry:main /subsystem:console %T/main.obj %T/foo.lto.obj ; RUN: llvm-readobj -file-headers %T/main.exe | FileCheck -check-prefix=HEADERS-01 %s ; RUN: llvm-objdump -d %T/main.exe | FileCheck -check-prefix=TEXT-01 %s -; RUN: lld -flavor link2 /out:%T/main.exe /entry:main /subsystem:console %T/main.obj %T/foo.lto.lib +; RUN: lld -flavor link /out:%T/main.exe /entry:main /subsystem:console %T/main.obj %T/foo.lto.lib ; RUN: llvm-readobj -file-headers %T/main.exe | FileCheck -check-prefix=HEADERS-01 %s ; RUN: llvm-objdump -d %T/main.exe | FileCheck -check-prefix=TEXT-01 %s -; RUN: lld -flavor link2 /out:%T/main.exe /entry:main /subsystem:console %T/main.lto.obj %T/foo.obj +; RUN: lld -flavor link /out:%T/main.exe /entry:main /subsystem:console %T/main.lto.obj %T/foo.obj ; RUN: llvm-readobj -file-headers %T/main.exe | FileCheck -check-prefix=HEADERS-10 %s ; RUN: llvm-objdump -d %T/main.exe | FileCheck -check-prefix=TEXT-10 %s -; RUN: lld -flavor link2 /out:%T/main.exe /entry:main /subsystem:console %T/main.lto.obj %T/foo.lib +; RUN: lld -flavor link /out:%T/main.exe /entry:main /subsystem:console %T/main.lto.obj %T/foo.lib ; RUN: llvm-readobj -file-headers %T/main.exe | FileCheck -check-prefix=HEADERS-10 %s ; RUN: llvm-objdump -d %T/main.exe | FileCheck -check-prefix=TEXT-10 %s Index: test/COFF/machine.test =================================================================== --- test/COFF/machine.test +++ test/COFF/machine.test @@ -1,29 +1,29 @@ # RUN: yaml2obj %p/Inputs/machine-x64.yaml > %t.obj -# RUN: lld -flavor link2 /entry:main /subsystem:console /out:%t.exe %t.obj +# RUN: lld -flavor link /entry:main /subsystem:console /out:%t.exe %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=AMD64 %s -# RUN: lld -flavor link2 /entry:main /subsystem:console /machine:x64 \ +# RUN: lld -flavor link /entry:main /subsystem:console /machine:x64 \ # RUN: /out:%t.exe %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=AMD64 %s AMD64: Machine: IMAGE_FILE_MACHINE_AMD64 # RUN: yaml2obj %p/Inputs/machine-x86.yaml > %t.obj -# RUN: lld -flavor link2 /entry:main /subsystem:console /out:%t.exe %t.obj +# RUN: lld -flavor link /entry:main /subsystem:console /out:%t.exe %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=I386 %s -# RUN: lld -flavor link2 /entry:main /subsystem:console /machine:x86 \ +# RUN: lld -flavor link /entry:main /subsystem:console /machine:x86 \ # RUN: /out:%t.exe %t.obj /fixed # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=I386 %s I386: Machine: IMAGE_FILE_MACHINE_I386 # RUN: yaml2obj %p/Inputs/machine-x64.yaml > %t.obj -# RUN: not lld -flavor link2 /entry:main /subsystem:console /machine:x86 \ +# RUN: not lld -flavor link /entry:main /subsystem:console /machine:x86 \ # RUN: /out:%t.exe %t.obj /fixed >& %t.log # RUN: FileCheck -check-prefix=INCOMPAT %s < %t.log # RUN: yaml2obj %p/Inputs/machine-x86.yaml > %t1.obj # RUN: sed -e s/main/foo/ %p/Inputs/machine-x64.yaml | yaml2obj > %t2.obj -# RUN: not lld -flavor link2 /entry:main /subsystem:console /out:%t.exe \ +# RUN: not lld -flavor link /entry:main /subsystem:console /out:%t.exe \ # RUN: %t1.obj %t2.obj >& %t.log # RUN: FileCheck -check-prefix=INCOMPAT %s < %t.log Index: test/COFF/manifest.test =================================================================== --- test/COFF/manifest.test +++ test/COFF/manifest.test @@ -1,6 +1,6 @@ # RUN: yaml2obj %p/Inputs/ret42.yaml > %t.obj -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj # RUN: FileCheck -check-prefix=MANIFEST %s < %t.exe.manifest MANIFEST: @@ -15,7 +15,7 @@ MANIFEST: MANIFEST: -# RUN: lld -flavor link2 /out:%t.exe /entry:main \ +# RUN: lld -flavor link /out:%t.exe /entry:main \ # RUN: /manifestuac:"level='requireAdministrator' uiAccess='true'" %t.obj # RUN: FileCheck -check-prefix=UAC %s < %t.exe.manifest @@ -31,7 +31,7 @@ UAC: UAC: -# RUN: lld -flavor link2 /out:%t.exe /entry:main \ +# RUN: lld -flavor link /out:%t.exe /entry:main \ # RUN: /manifestdependency:"foo='bar'" %t.obj # RUN: FileCheck -check-prefix=DEPENDENCY %s < %t.exe.manifest @@ -52,7 +52,7 @@ DEPENDENCY: DEPENDENCY: -# RUN: lld -flavor link2 /out:%t.exe /entry:main /manifestuac:no %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main /manifestuac:no %t.obj # RUN: FileCheck -check-prefix=NOUAC %s < %t.exe.manifest NOUAC: Index: test/COFF/merge.test =================================================================== --- test/COFF/merge.test +++ test/COFF/merge.test @@ -1,5 +1,5 @@ # RUN: yaml2obj < %s > %t.obj -# RUN: lld -flavor link2 /out:%t.exe /entry:main /subsystem:console /force \ +# RUN: lld -flavor link /out:%t.exe /entry:main /subsystem:console /force \ # RUN: /merge:.foo=.abc /merge:.bar=.def %t.obj /debug # RUN: llvm-readobj -sections %t.exe | FileCheck %s Index: test/COFF/nodefaultlib.test =================================================================== --- test/COFF/nodefaultlib.test +++ test/COFF/nodefaultlib.test @@ -1,20 +1,20 @@ # RUN: cp %p/Inputs/hello64.obj %T # RUN: cp %p/Inputs/std64.lib %T -# RUN: not lld -flavor link2 /out:%t.exe /entry:main /subsystem:console \ +# RUN: not lld -flavor link /out:%t.exe /entry:main /subsystem:console \ # RUN: hello64.obj /defaultlib:std64.lib >& %t.log # RUN: FileCheck -check-prefix=CHECK1 %s < %t.log -# RUN: not lld -flavor link2 /out:%t.exe /entry:main /subsystem:console \ +# RUN: not lld -flavor link /out:%t.exe /entry:main /subsystem:console \ # RUN: hello64 /defaultlib:std64.lib >& %t.log # RUN: FileCheck -check-prefix=CHECK2 %s < %t.log -# RUN: lld -flavor link2 /libpath:%T /out:%t.exe /entry:main \ +# RUN: lld -flavor link /libpath:%T /out:%t.exe /entry:main \ # RUN: /subsystem:console hello64.obj /defaultlib:std64.lib \ # RUN: /nodefaultlib:std64.lib >& %t.log || true # RUN: FileCheck -check-prefix=CHECK3 %s < %t.log -# RUN: lld -flavor link2 /libpath:%T /out:%t.exe /entry:main \ +# RUN: lld -flavor link /libpath:%T /out:%t.exe /entry:main \ # RUN: /subsystem:console hello64.obj /defaultlib:std64 \ # RUN: /nodefaultlib:std64.lib >& %t.log || true # RUN: FileCheck -check-prefix=CHECK3 %s < %t.log @@ -23,8 +23,8 @@ CHECK2: hello64: {{[Nn]}}o such file or directory CHECK3: hello64.obj: undefined symbol: MessageBoxA -# RUN: lld -flavor link2 /libpath:%T /out:%t.exe /entry:main \ +# RUN: lld -flavor link /libpath:%T /out:%t.exe /entry:main \ # RUN: /subsystem:console hello64.obj /defaultlib:std64.lib -# RUN: env LIB=%T lld -flavor link2 /out:%t.exe /entry:main \ +# RUN: env LIB=%T lld -flavor link /out:%t.exe /entry:main \ # RUN: /subsystem:console hello64.obj /defaultlib:std64.lib Index: test/COFF/noentry.test =================================================================== --- test/COFF/noentry.test +++ test/COFF/noentry.test @@ -1,9 +1,9 @@ # REQUIRES: winres # RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj -# RUN: lld -flavor link2 /out:%t.dll /dll %t.obj +# RUN: lld -flavor link /out:%t.dll /dll %t.obj # RUN: llvm-readobj -file-headers %t.dll | FileCheck -check-prefix=ENTRY %s -# RUN: lld -flavor link2 /out:%t.dll /dll /noentry %t.obj +# RUN: lld -flavor link /out:%t.dll /dll /noentry %t.obj # RUN: llvm-readobj -file-headers %t.dll | FileCheck -check-prefix=NOENTRY %s ENTRY: AddressOfEntryPoint: 0x1000 Index: test/COFF/opt.test =================================================================== --- test/COFF/opt.test +++ test/COFF/opt.test @@ -1,12 +1,12 @@ # RUN: yaml2obj < %s > %t.obj -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj \ +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj \ # RUN: /verbose >& %t.log ### FileCheck doesn't like empty input, so write something. # RUN: echo dummy >> %t.log # RUN: FileCheck -check-prefix=CHECK1 %s < %t.log -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj \ +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj \ # RUN: /verbose /opt:noref >& %t.log # RUN: echo dummy >> %t.log # RUN: FileCheck -check-prefix=CHECK2 %s < %t.log Index: test/COFF/options.test =================================================================== --- test/COFF/options.test +++ test/COFF/options.test @@ -1,51 +1,51 @@ # RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=BIND %s -# RUN: lld -flavor link2 /allowbind /out:%t.exe /entry:main %t.obj +# RUN: lld -flavor link /allowbind /out:%t.exe /entry:main %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=BIND %s BIND-NOT: IMAGE_DLL_CHARACTERISTICS_NO_BIND -# RUN: lld -flavor link2 /allowbind:no /out:%t.exe /entry:main %t.obj +# RUN: lld -flavor link /allowbind:no /out:%t.exe /entry:main %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOBIND %s NOBIND: IMAGE_DLL_CHARACTERISTICS_NO_BIND -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=ISO %s -# RUN: lld -flavor link2 /allowisolation /out:%t.exe /entry:main %t.obj +# RUN: lld -flavor link /allowisolation /out:%t.exe /entry:main %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=ISO %s ISO-NOT: IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION -# RUN: lld -flavor link2 /allowisolation:no /out:%t.exe /entry:main %t.obj +# RUN: lld -flavor link /allowisolation:no /out:%t.exe /entry:main %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOISO %s NOISO: IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=ENT %s -# RUN: lld -flavor link2 /out:%t.exe /entry:main /highentropyva %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main /highentropyva %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=ENT %s ENT: IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA -# RUN: lld -flavor link2 /out:%t.exe /highentropyva:no /out:%t.exe /entry:main %t.obj +# RUN: lld -flavor link /out:%t.exe /highentropyva:no /out:%t.exe /entry:main %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOENT %s NOENT-NOT: IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NXCOMPAT %s -# RUN: lld -flavor link2 /out:%t.exe /entry:main /nxcompat %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main /nxcompat %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NXCOMPAT %s NXCOMPAT: IMAGE_DLL_CHARACTERISTICS_NX_COMPAT -# RUN: lld -flavor link2 /out:%t.exe /nxcompat:no /out:%t.exe /entry:main %t.obj +# RUN: lld -flavor link /out:%t.exe /nxcompat:no /out:%t.exe /entry:main %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NONXCOMPAT %s NONXCOMPAT-NOT: IMAGE_DLL_CHARACTERISTICS_NX_COMPAT -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=TSAWARE %s -# RUN: lld -flavor link2 /out:%t.exe /entry:main /tsaware %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main /tsaware %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=TSAWARE %s TSAWARE: IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE -# RUN: lld -flavor link2 /tsaware:no /out:%t.exe /entry:main %t.obj +# RUN: lld -flavor link /tsaware:no /out:%t.exe /entry:main %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOTSAWARE %s NOTSAWARE-NOT: IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE Index: test/COFF/order.test =================================================================== --- test/COFF/order.test +++ test/COFF/order.test @@ -4,7 +4,7 @@ # RUN: rm -f %t2.lib %t3.lib # RUN: llvm-ar cru %t2.lib %t2.obj # RUN: llvm-ar cru %t3.lib %t3.obj -# RUN: lld -flavor link2 /out:%t.exe /entry:main \ +# RUN: lld -flavor link /out:%t.exe /entry:main \ # RUN: %t1.obj %t2.lib %t3.obj %t3.lib /verbose >& %t.log # RUN: FileCheck %s < %t.log Index: test/COFF/out.test =================================================================== --- test/COFF/out.test +++ test/COFF/out.test @@ -5,9 +5,9 @@ # RUN: cp %t.obj %T/out/tmp/out2 # RUN: cp %t.obj %T/out/tmp/out3.xyz -# RUN: lld -flavor link2 /entry:main %T/out/out1.obj -# RUN: lld -flavor link2 /entry:main %T/out/tmp/out2 -# RUN: lld -flavor link2 /entry:main %T/out/tmp/out3.xyz +# RUN: lld -flavor link /entry:main %T/out/out1.obj +# RUN: lld -flavor link /entry:main %T/out/tmp/out2 +# RUN: lld -flavor link /entry:main %T/out/tmp/out3.xyz # RUN: llvm-readobj out1.exe | FileCheck %s # RUN: llvm-readobj out2.exe | FileCheck %s Index: test/COFF/reloc-x64.test =================================================================== --- test/COFF/reloc-x64.test +++ test/COFF/reloc-x64.test @@ -1,5 +1,5 @@ # RUN: yaml2obj < %s > %t.obj -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj # RUN: llvm-objdump -d %t.exe | FileCheck %s # CHECK: .text: Index: test/COFF/reloc-x86.test =================================================================== --- test/COFF/reloc-x86.test +++ test/COFF/reloc-x86.test @@ -1,5 +1,5 @@ # RUN: yaml2obj < %s > %t.obj -# RUN: lld -flavor link2 /out:%t.exe /entry:main /base:0x400000 %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main /base:0x400000 %t.obj # RUN: llvm-objdump -d %t.exe | FileCheck %s # CHECK: .text: Index: test/COFF/resource.test =================================================================== --- test/COFF/resource.test +++ test/COFF/resource.test @@ -1,7 +1,7 @@ # REQUIRES: winres # RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj %p/Inputs/resource.res +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj %p/Inputs/resource.res # Check if the binary contains UTF-16LE string "Hello" copied from resource.res. # RUN: FileCheck --check-prefix=EXE %s < %t.exe Index: test/COFF/responsefile.test =================================================================== --- test/COFF/responsefile.test +++ test/COFF/responsefile.test @@ -1,7 +1,7 @@ # RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj # RUN: echo /out:%t.exe /entry:main %t.obj > %t.rsp -# RUN: lld -flavor link2 @%t.rsp /heap:0x3000 +# RUN: lld -flavor link @%t.rsp /heap:0x3000 # RUN: llvm-readobj -file-headers %t.exe | FileCheck %s CHECK: SizeOfHeapReserve: 12288 Index: test/COFF/seh.test =================================================================== --- test/COFF/seh.test +++ test/COFF/seh.test @@ -1,5 +1,5 @@ # RUN: yaml2obj < %s > %t.obj -# RUN: lld -flavor link2 /out:%t.exe /subsystem:console /entry:main %t.obj +# RUN: lld -flavor link /out:%t.exe /subsystem:console /entry:main %t.obj # RUN: llvm-objdump -s %t.exe | FileCheck %s # CHECK: Contents of section .rdata: Index: test/COFF/stack.test =================================================================== --- test/COFF/stack.test +++ test/COFF/stack.test @@ -1,24 +1,24 @@ # RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=DEFAULT %s DEFAULT: SizeOfStackReserve: 1048576 DEFAULT: SizeOfStackCommit: 4096 -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj /stack:0x3000 +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj /stack:0x3000 # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK1 %s # RUN: echo "STACKSIZE 12288" > %t.def -# RUN: lld -flavor link2 /out:%t.exe /entry:main /def:%t.def %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main /def:%t.def %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK1 %s CHECK1: SizeOfStackReserve: 12288 CHECK1: SizeOfStackCommit: 4096 -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj /stack:0x5000,0x3000 +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj /stack:0x5000,0x3000 # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK2 %s # RUN: echo "STACKSIZE 20480,12288" > %t.def -# RUN: lld -flavor link2 /out:%t.exe /entry:main /def:%t.def %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main /def:%t.def %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK2 %s CHECK2: SizeOfStackReserve: 20480 Index: test/COFF/subsystem-inference.test =================================================================== --- test/COFF/subsystem-inference.test +++ test/COFF/subsystem-inference.test @@ -1,17 +1,17 @@ # RUN: sed -e s/ENTRYNAME/main/ %s | yaml2obj > %t.obj -# RUN: lld -flavor link2 /out:%t.exe %t.obj +# RUN: lld -flavor link /out:%t.exe %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=MAIN %s # RUN: sed s/ENTRYNAME/wmain/ %s | yaml2obj > %t.obj -# RUN: lld -flavor link2 /out:%t.exe %t.obj +# RUN: lld -flavor link /out:%t.exe %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=WMAIN %s # RUN: sed s/ENTRYNAME/WinMain/ %s | yaml2obj > %t.obj -# RUN: lld -flavor link2 /out:%t.exe %t.obj +# RUN: lld -flavor link /out:%t.exe %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=WINMAIN %s # RUN: sed s/ENTRYNAME/wWinMain/ %s | yaml2obj > %t.obj -# RUN: lld -flavor link2 /out:%t.exe %t.obj +# RUN: lld -flavor link /out:%t.exe %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=WWINMAIN %s # MAIN: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI Index: test/COFF/subsystem.test =================================================================== --- test/COFF/subsystem.test +++ test/COFF/subsystem.test @@ -1,4 +1,4 @@ -# RUN: lld -flavor link2 /entry:main /out:%t.exe /subsystem:windows \ +# RUN: lld -flavor link /entry:main /out:%t.exe /subsystem:windows \ # RUN: %p/Inputs/ret42.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK1 %s @@ -8,7 +8,7 @@ CHECK1: MinorSubsystemVersion: 0 CHECK1: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_GUI -# RUN: lld -flavor link2 /entry:main /out:%t.exe /subsystem:windows,8.9 \ +# RUN: lld -flavor link /entry:main /out:%t.exe /subsystem:windows,8.9 \ # RUN: %p/Inputs/ret42.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK2 %s Index: test/COFF/symtab.test =================================================================== --- test/COFF/symtab.test +++ test/COFF/symtab.test @@ -1,5 +1,5 @@ # RUN: yaml2obj < %s > %t.obj -# RUN: lld -flavor link2 /debug /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib +# RUN: lld -flavor link /debug /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib # RUN: llvm-readobj -symbols %t.exe | FileCheck %s # CHECK: Symbols [ Index: test/COFF/tls.test =================================================================== --- test/COFF/tls.test +++ test/COFF/tls.test @@ -1,5 +1,5 @@ # RUN: yaml2obj < %s > %t.obj -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck %s # CHECK: TLSTableRVA: 0x1000 Index: test/COFF/tls32.test =================================================================== --- test/COFF/tls32.test +++ test/COFF/tls32.test @@ -1,5 +1,5 @@ # RUN: yaml2obj < %s > %t.obj -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck %s # CHECK: TLSTableRVA: 0x1000 Index: test/COFF/unwind.test =================================================================== --- test/COFF/unwind.test +++ test/COFF/unwind.test @@ -1,6 +1,6 @@ # RUN: yaml2obj < %s > %t.obj # -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=HEADER %s # RUN: llvm-objdump -unwind-info %t.exe | FileCheck -check-prefix=UNWIND %s # Index: test/COFF/version.test =================================================================== --- test/COFF/version.test +++ test/COFF/version.test @@ -1,18 +1,18 @@ # RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=DEFAULT %s DEFAULT: MajorImageVersion: 0 DEFAULT: MinorImageVersion: 0 -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj /version:11 +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj /version:11 # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK1 %s CHECK1: MajorImageVersion: 11 CHECK1: MinorImageVersion: 0 -# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj /version:11.22 +# RUN: lld -flavor link /out:%t.exe /entry:main %t.obj /version:11.22 # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK2 %s CHECK2: MajorImageVersion: 11 Index: test/COFF/weak-external.test =================================================================== --- test/COFF/weak-external.test +++ test/COFF/weak-external.test @@ -1,7 +1,7 @@ # RUN: yaml2obj %s > %t.obj # RUN: llvm-as -o %t.lto.obj %S/Inputs/weak-external.ll -# RUN: lld -flavor link2 /out:%t1.exe /entry:g /subsystem:console %t.obj -# RUN: lld -flavor link2 /out:%t2.exe /entry:g /subsystem:console /lldmap:%t2.map %t.obj %t.lto.obj +# RUN: lld -flavor link /out:%t1.exe /entry:g /subsystem:console %t.obj +# RUN: lld -flavor link /out:%t2.exe /entry:g /subsystem:console /lldmap:%t2.map %t.obj %t.lto.obj # RUN: FileCheck %s < %t2.map # CHECK: lto-llvm{{.*}}: Index: test/COFF/weak-external2.test =================================================================== --- test/COFF/weak-external2.test +++ test/COFF/weak-external2.test @@ -1,6 +1,6 @@ # RUN: yaml2obj %s > %t.obj # RUN: llvm-as -o %t.lto.obj %S/Inputs/weak-external2.ll -# RUN: lld -flavor link2 /out:%t.exe /entry:g /subsystem:console %t.obj %t.lto.obj +# RUN: lld -flavor link /out:%t.exe /entry:g /subsystem:console %t.obj %t.lto.obj --- header: Index: test/COFF/weak-external3.test =================================================================== --- test/COFF/weak-external3.test +++ test/COFF/weak-external3.test @@ -1,8 +1,8 @@ # RUN: yaml2obj %s > %t.obj # RUN: llvm-as -o %t.lto.obj %S/Inputs/weak-external3.ll -# RUN: lld -flavor link2 /out:%t1.exe /entry:f /subsystem:console /lldmap:%t1.map %t.lto.obj +# RUN: lld -flavor link /out:%t1.exe /entry:f /subsystem:console /lldmap:%t1.map %t.lto.obj # RUN: FileCheck --check-prefix=CHECK1 %s < %t1.map -# RUN: lld -flavor link2 /out:%t2.exe /entry:f /subsystem:console /lldmap:%t2.map %t.obj %t.lto.obj +# RUN: lld -flavor link /out:%t2.exe /entry:f /subsystem:console /lldmap:%t2.map %t.obj %t.lto.obj # RUN: FileCheck --check-prefix=CHECK2 %s < %t2.map # CHECK1: lto-llvm{{.*}}: Index: test/pecoff/Inputs/abs.obj.yaml =================================================================== --- test/pecoff/Inputs/abs.obj.yaml +++ /dev/null @@ -1,11 +0,0 @@ -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [] -sections: -symbols: - - Name: _abs_value - Value: 0xDEADBEEF - SectionNumber: -1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL Index: test/pecoff/Inputs/alignment.obj.yaml =================================================================== --- test/pecoff/Inputs/alignment.obj.yaml +++ /dev/null @@ -1,103 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 256 - SectionData: CC - - Name: .text$1 - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4096 - SectionData: 00 - - Name: .data$1 - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 4 - SectionData: 00 - - Name: .data$2 - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 4 - SectionData: 11 - - Name: .data$3 - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 0 - SectionData: 22 - - Name: .bss$1 - Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 16 - SectionData: 0000 - - Name: .bss$2 - Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 16 - SectionData: 0000 - - Name: .yyy - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 4096 - SectionData: 0000 - - Name: .zzz - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 16384 - SectionData: 0000 -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: .text$1 - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: .data$1 - Value: 0 - SectionNumber: 3 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: .data$2 - Value: 0 - SectionNumber: 4 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: .data$3 - Value: 0 - SectionNumber: 5 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: _start - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: .bss$1 - Value: 0 - SectionNumber: 6 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: .bss$2 - Value: 0 - SectionNumber: 7 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: .foo - Value: 0 - SectionNumber: 8 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: .bar - Value: 0 - SectionNumber: 9 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC -... Index: test/pecoff/Inputs/alternatename1.obj.yaml =================================================================== --- test/pecoff/Inputs/alternatename1.obj.yaml +++ /dev/null @@ -1,23 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 1 - SectionData: 90909090 -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: _foo - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/alternatename2.obj.yaml =================================================================== --- test/pecoff/Inputs/alternatename2.obj.yaml +++ /dev/null @@ -1,23 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: CCCCCCCC -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: _main - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/alternatename3.obj.yaml =================================================================== --- test/pecoff/Inputs/alternatename3.obj.yaml +++ /dev/null @@ -1,39 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 1 - SectionData: 90909090 - - Name: .drectve - Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] - Alignment: 2147483648 - SectionData: 2F616C7465726E6174656E616D653A5F6D61696E3D5F666F6F00 -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: _foo - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: .drectve - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 13 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 -... Index: test/pecoff/Inputs/armnt-ImageBase.obj.yaml =================================================================== --- test/pecoff/Inputs/armnt-ImageBase.obj.yaml +++ /dev/null @@ -1,39 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_ARMNT - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: 7047FEDE00000000 - Relocations: - - VirtualAddress: 4 - SymbolName: __ImageBase - Type: 1 -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 8 - NumberOfRelocations: 1 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 1 - - Name: mainCRTStartup - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: __ImageBase - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/armnt-ImageBase.s =================================================================== --- test/pecoff/Inputs/armnt-ImageBase.s +++ /dev/null @@ -1,16 +0,0 @@ - - .syntax unified - .thumb - .text - - .def mainCRTStartup - .type 32 - .scl 2 - .endef - .align 2 - .thumb_func -mainCRTStartup: - bx lr - trap - .long __ImageBase - Index: test/pecoff/Inputs/armnt-addr32-exec.obj.yaml =================================================================== --- test/pecoff/Inputs/armnt-addr32-exec.obj.yaml +++ /dev/null @@ -1,55 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_ARMNT - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: '7047' - - Name: .rdata - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: '00000000' - Relocations: - - VirtualAddress: 0 - SymbolName: function - Type: 1 -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 2 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 1 - - Name: .rdata - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 4 - NumberOfRelocations: 1 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 2 - - Name: function - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: fps - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/armnt-addr32-exec.s =================================================================== --- test/pecoff/Inputs/armnt-addr32-exec.s +++ /dev/null @@ -1,24 +0,0 @@ - -# __declspec(dllexport) void function(void) { } -# const void * const fps[] = { &function, }; - - .syntax unified - .thumb - .text - - .def function - .scl 2 - .type 32 - .endef - .global function - .align 2 - .thumb_func -function: - bx lr - - .section .rdata,"rd" - .global fps - .align 2 -fps: - .long function - Index: test/pecoff/Inputs/armnt-addr32.obj.yaml =================================================================== --- test/pecoff/Inputs/armnt-addr32.obj.yaml +++ /dev/null @@ -1,39 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_ARMNT - Characteristics: [ ] -sections: - - Name: .rdata - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: '0000000000000000' - Relocations: - - VirtualAddress: 0 - SymbolName: i - Type: 1 -symbols: - - Name: .rdata - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 8 - NumberOfRelocations: 1 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 1 - - Name: i - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: is - Value: 4 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/armnt-addr32.s =================================================================== --- test/pecoff/Inputs/armnt-addr32.s +++ /dev/null @@ -1,18 +0,0 @@ - -@ static const int i = 0; -@ const int * const is[] = { &i, }; - - .syntax unified - .thumb - .text - - .section .rdata,"rd" - .align 2 # @i -i: - .long 0 # 0x0 - - .global is # @is - .align 2 -is: - .long i - Index: test/pecoff/Inputs/armnt-blx23t.obj.yaml =================================================================== --- test/pecoff/Inputs/armnt-blx23t.obj.yaml +++ /dev/null @@ -1,39 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_ARMNT - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: 704700BF2DE90048EB46202000F000F80130BDE80088 - Relocations: - - VirtualAddress: 12 - SymbolName: identity - Type: 21 -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 22 - NumberOfRelocations: 1 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 1 - - Name: identity - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: function - Value: 4 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/armnt-blx23t.s =================================================================== --- test/pecoff/Inputs/armnt-blx23t.s +++ /dev/null @@ -1,33 +0,0 @@ - -# __declspec(noinline) int identity(int i) { return i; } -# int function() { return identity(32) + 1; } - - .syntax unified - .thumb - .text - - .def identity - .scl 2 - .type 32 - .endef - .global identity - .align 2 - .thumb_func -identity: - bx lr - - .def function - .scl 2 - .type 32 - .endef - .global function - .align 2 - .thumb_func -function: - push.w {r11, lr} - mov r11, sp - movs r0, 32 - bl identity - adds r0, 1 - pop.w {r11, pc} - Index: test/pecoff/Inputs/armnt-branch24t.obj.yaml =================================================================== --- test/pecoff/Inputs/armnt-branch24t.obj.yaml +++ /dev/null @@ -1,39 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_ARMNT - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: 704700BF202000F000B8 - Relocations: - - VirtualAddress: 6 - SymbolName: identity - Type: 20 -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 10 - NumberOfRelocations: 1 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 1 - - Name: identity - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: function - Value: 4 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/armnt-branch24t.s =================================================================== --- test/pecoff/Inputs/armnt-branch24t.s +++ /dev/null @@ -1,26 +0,0 @@ - -# int ___declspec(noinline) identity(int i) { return i; } -# int function(void) { return identity(32); } - - .syntax unified - .thumb - .text - - .def identity - .scl 2 - .type 32 - .endef - .global identity - .align 2 - .thumb_func -identity: - bx lr - - .def function - .scl 2 - .type 32 - .endef -function: - movs r0, 32 - b identity - Index: test/pecoff/Inputs/armnt-exports.def =================================================================== --- test/pecoff/Inputs/armnt-exports.def +++ /dev/null @@ -1,4 +0,0 @@ -LIBRARY "armnt-exports" -EXPORTS - function - Index: test/pecoff/Inputs/armnt-exports.obj.yaml =================================================================== --- test/pecoff/Inputs/armnt-exports.obj.yaml +++ /dev/null @@ -1,35 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_ARMNT - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: 704700BF7047 -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 6 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 1 - - Name: function - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: _DllMainCRTStartup - Value: 4 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/armnt-import.obj.yaml =================================================================== --- test/pecoff/Inputs/armnt-import.obj.yaml +++ /dev/null @@ -1,39 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_ARMNT - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: 40F20000C0F2000000680047 - Relocations: - - VirtualAddress: 0 - SymbolName: __imp_function - Type: 17 -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 12 - NumberOfRelocations: 1 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 1 - - Name: mainCRTStartup - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: __imp_function - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/armnt-import.s =================================================================== --- test/pecoff/Inputs/armnt-import.s +++ /dev/null @@ -1,21 +0,0 @@ - -# void __declspec(dllimport) function(void); -# int mainCRTStartup(void) { return function(); } - - .syntax unified - .thumb - .text - - .def mainCRTStartup - .scl 2 - .type 32 - .endef - .global mainCRTStartup - .align 2 - .thumb_func -mainCRTStartup: - movw r0, :lower16:__imp_function - movt r0, :upper16:__imp_function - ldr r0, [r0] - bx r0 - Index: test/pecoff/Inputs/armnt-mov32t-exec.obj.yaml =================================================================== --- test/pecoff/Inputs/armnt-mov32t-exec.obj.yaml +++ /dev/null @@ -1,39 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_ARMNT - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: 704700BF40F20000C0F200007047 - Relocations: - - VirtualAddress: 4 - SymbolName: function - Type: 17 -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 14 - NumberOfRelocations: 1 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 1 - - Name: function - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: get_function - Value: 4 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/armnt-mov32t-exec.s =================================================================== --- test/pecoff/Inputs/armnt-mov32t-exec.s +++ /dev/null @@ -1,30 +0,0 @@ - -# void function(void) { } -# void *get_function() { return &function; } - - .syntax unified - .thumb - .text - - .def function - .scl 2 - .type 32 - .endef - .global function - .align 2 - .thumb_func -function: - bx lr - - .def get_function - .scl 2 - .type 32 - .endef - .global get_function - .align 2 - .thumb_func -get_function: - movw r0, :lower16:function - movt r0, :upper16:function - bx lr - Index: test/pecoff/Inputs/armnt-mov32t.obj.yaml =================================================================== --- test/pecoff/Inputs/armnt-mov32t.obj.yaml +++ /dev/null @@ -1,55 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_ARMNT - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: 40F20000C0F200007047 - Relocations: - - VirtualAddress: 0 - SymbolName: buffer - Type: 17 - - Name: .rdata - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] - Alignment: 1 - SectionData: '62756666657200' -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 10 - NumberOfRelocations: 1 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 1 - - Name: .rdata - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 7 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 2 - - Name: get_buffer - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: buffer - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC -... Index: test/pecoff/Inputs/armnt-mov32t.s =================================================================== --- test/pecoff/Inputs/armnt-mov32t.s +++ /dev/null @@ -1,24 +0,0 @@ - -# static const char buffer[] = "buffer"; -# const char *get_buffer() { return buffer; } - - .syntax unified - .thumb - .text - - .def get_buffer - .scl 2 - .type 32 - .endef - .global get_buffer - .align 2 - .thumb_func -get_buffer: - movw r0, :lower16:buffer - movt r0, :upper16:buffer - bx lr - - .section .rdata,"rd" -buffer: - .asciz "buffer" - Index: test/pecoff/Inputs/armnt-obj.s =================================================================== --- test/pecoff/Inputs/armnt-obj.s +++ /dev/null @@ -1,12 +0,0 @@ - - .syntax unified - .thumb - .text - - .def main - .scl 2 - .type 32 - .endef -main: - bx lr - Index: test/pecoff/Inputs/armnt-obj.yaml =================================================================== --- test/pecoff/Inputs/armnt-obj.yaml +++ /dev/null @@ -1,29 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_ARMNT - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: '7047' -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 2 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 1 - - Name: main - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/associative1.obj.yaml =================================================================== --- test/pecoff/Inputs/associative1.obj.yaml +++ /dev/null @@ -1,53 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [] -sections: - - Name: .data - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 4 - SectionData: 00000000 - - Name: '.CRT$XCU' - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: 77777777 -symbols: - - Name: .data - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 4 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - Selection: IMAGE_COMDAT_SELECT_ANY - - Name: _var - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: '.CRT$XCU' - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 4 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 1 - Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE - - Name: _init - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/associative3.obj.yaml =================================================================== --- test/pecoff/Inputs/associative3.obj.yaml +++ /dev/null @@ -1,33 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: 0000000000000000 - Relocations: - - VirtualAddress: 4 - SymbolName: _var - Type: IMAGE_REL_I386_DIR32 -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: _main - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: _var - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/basereloc.obj.yaml =================================================================== --- test/pecoff/Inputs/basereloc.obj.yaml +++ /dev/null @@ -1,164 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4096 - SectionData: B800000000506800000000680000000050E80000000050E80000000050E800000000 - Relocations: - - VirtualAddress: 0 - SymbolName: abs_symbol - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 7 - SymbolName: caption - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 12 - SymbolName: message - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 18 - SymbolName: _MessageBoxA@16 - Type: IMAGE_REL_I386_REL32 - - VirtualAddress: 24 - SymbolName: _ExitProcess@4 - Type: IMAGE_REL_I386_REL32 - - VirtualAddress: 30 - SymbolName: ___ImageBase - Type: IMAGE_REL_I386_DIR32 - - Name: .text2 - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4096 - SectionData: B800000000506800000000680000000050E80000000050E80000000050E800000000 - Relocations: - - VirtualAddress: 0 - SymbolName: abs_symbol - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 7 - SymbolName: caption - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 12 - SymbolName: message - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 18 - SymbolName: _MessageBoxA@16 - Type: IMAGE_REL_I386_REL32 - - VirtualAddress: 24 - SymbolName: _ExitProcess@4 - Type: IMAGE_REL_I386_REL32 - - VirtualAddress: 30 - SymbolName: ___ImageBase - Type: IMAGE_REL_I386_DIR32 - - Name: .data - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 4 - SectionData: 48656C6C6F0048656C6C6F20576F726C6400 - - Name: .drectve - Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] - Alignment: 2147483648 - SectionData: 2F454E5452593A6D61696E20 -symbols: - - Name: "@comp.id" - Value: 10394907 - SectionNumber: 65535 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 28 - NumberOfRelocations: 6 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: .text2 - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 28 - NumberOfRelocations: 6 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: .data - Value: 0 - SectionNumber: 3 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 18 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: _MessageBoxA@16 - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: _ExitProcess@4 - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: message - Value: 6 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: _main - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: caption - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: .drectve - Value: 0 - SectionNumber: 3 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 12 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: .file - Value: 0 - SectionNumber: 65534 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - File: "hello.c" - - Name: abs_symbol - Value: 0xDEADBEEF - SectionNumber: -1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: ___ImageBase - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/bss.asm =================================================================== --- test/pecoff/Inputs/bss.asm +++ /dev/null @@ -1,20 +0,0 @@ -.586 -.model flat, c - -extern ExitProcess@4 : PROC - -_BSS SEGMENT - _x DD 064H DUP (?) - _y DD 064H DUP (?) -_BSS ENDS - -.code -start: - mov eax, 42 - mov _x, eax - mov eax, _x - push eax - call ExitProcess@4 -end start - -end Index: test/pecoff/Inputs/comdat.obj.yaml =================================================================== --- test/pecoff/Inputs/comdat.obj.yaml +++ /dev/null @@ -1,53 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 16 - SectionData: 558BEC33C05DC3 - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 16 - SectionData: 558BEC33C05DC3 -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 7 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 2532800969 - Number: 0 - Selection: IMAGE_COMDAT_SELECT_ANY - - Name: .text - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 7 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 2532800969 - Number: 0 - Selection: IMAGE_COMDAT_SELECT_ANY - - Name: "?inlinefn1@@YAHXZ" - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: "?inlinefn2@@YAHXZ" - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/common-symbol.obj.yaml =================================================================== --- test/pecoff/Inputs/common-symbol.obj.yaml +++ /dev/null @@ -1,85 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_AMD64 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: b800000000b800000000b800000000b800000000b800000000 - Relocations: - - VirtualAddress: 1 - SymbolName: _bssdata4 - Type: IMAGE_REL_AMD64_ADDR32 - - VirtualAddress: 6 - SymbolName: _bsspad1 - Type: IMAGE_REL_AMD64_ADDR32 - - VirtualAddress: 11 - SymbolName: _bssdata64 - Type: IMAGE_REL_AMD64_ADDR32 - - VirtualAddress: 16 - SymbolName: _bsspad2 - Type: IMAGE_REL_AMD64_ADDR32 - - VirtualAddress: 21 - SymbolName: _bssdata16 - Type: IMAGE_REL_AMD64_ADDR32 - - Name: .data - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 4 - SectionData: 03000000 -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 0 - NumberOfRelocations: 5 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: .data - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 4 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: _bssdata4 - Value: 4 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: _bsspad1 - Value: 1 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: _bssdata64 - Value: 64 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: _bsspad2 - Value: 1 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: _bssdata16 - Value: 16 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/drectve.obj.yaml =================================================================== --- test/pecoff/Inputs/drectve.obj.yaml +++ /dev/null @@ -1,79 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 16 - SectionData: 558BEC56FF15000000008B0D000000008B3103F0FF150000000003C65E5DC3 - Relocations: - - VirtualAddress: 6 - SymbolName: __imp__fn - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 12 - SymbolName: __imp__var - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 22 - SymbolName: __imp___name_with_underscore - Type: IMAGE_REL_I386_DIR32 - - Name: .drectve - Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] - Alignment: 2147483648 - SectionData: 2f64656661756c746c69623a766172732e6c6962202f73756273797374656d3a636f6e736f6c652c34322e313935202d3f666f6f00 -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 31 - NumberOfRelocations: 3 - NumberOfLinenumbers: 0 - CheckSum: 3595596940 - Number: 0 - - Name: __imp__fn - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: __imp___name_with_underscore - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: _main - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: __imp__var - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: _fn - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: .drectve - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 13 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 -... Index: test/pecoff/Inputs/drectve2.obj.yaml =================================================================== --- test/pecoff/Inputs/drectve2.obj.yaml +++ /dev/null @@ -1,45 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 16 - SectionData: 558BEC56FF15000000008B0D000000008B3103F0FF150000000003C65E5DC3 - - Name: .drectve - Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] - Alignment: 2147483648 - SectionData: 2f696e636c7564653a666f6f00 -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 31 - NumberOfRelocations: 3 - NumberOfLinenumbers: 0 - CheckSum: 3595596940 - Number: 0 - - Name: _main - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: .drectve - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 13 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 -... Index: test/pecoff/Inputs/entry.obj.yaml =================================================================== --- test/pecoff/Inputs/entry.obj.yaml +++ /dev/null @@ -1,40 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] - -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: A100000000030500000000C3 - -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - - Name: _foo - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - - Name: _bar - Value: 4 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - - Name: "?baz@@YAXXZ" - Value: 4 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/executable.obj.yaml =================================================================== --- test/pecoff/Inputs/executable.obj.yaml +++ /dev/null @@ -1,29 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_ARMNT - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: '7047' -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 2 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 1 - - Name: mainCRTStartup - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/executable.s =================================================================== --- test/pecoff/Inputs/executable.s +++ /dev/null @@ -1,17 +0,0 @@ - -# void mainCRTStartup(){} - - .syntax unified - .thumb - .text - - .def mainCRTStartup - .scl 2 - .type 32 - .endef - .global mainCRTStartup - .align 2 - .thumb_func -mainCRTStartup: - bx lr - Index: test/pecoff/Inputs/export.obj.yaml =================================================================== --- test/pecoff/Inputs/export.obj.yaml +++ /dev/null @@ -1,69 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: B800000000506800000000680000000050E80000000050E800000000 - - Name: .drectve - Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] - Alignment: 2147483648 - SectionData: 2f6578706f72743a5f6578706f7274666e334032353600 # /export:_exportfn3@256 -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 28 - NumberOfRelocations: 4 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: _init - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: _exportfn1 - Value: 8 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: _exportfn2 - Value: 16 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: _exportfn3@256 - Value: 16 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: _exportfn6 - Value: 16 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: _exportfn7@8 - Value: 16 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: "?exportfn8@@YAXXZ" - Value: 16 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/exports.def =================================================================== --- test/pecoff/Inputs/exports.def +++ /dev/null @@ -1,6 +0,0 @@ -; This is a comment line - -EXPORTS - exportfn1 @5 ; foo - exportfn2 - exportfn5=exportfn6 PRIVATE Index: test/pecoff/Inputs/exports2.def =================================================================== --- test/pecoff/Inputs/exports2.def +++ /dev/null @@ -1,6 +0,0 @@ -; This is a comment line - -EXPORTS - exportfn1 @5 ; foo - exportfn7 - exportfn5=exportfn6 PRIVATE Index: test/pecoff/Inputs/grouped-sections.asm =================================================================== --- test/pecoff/Inputs/grouped-sections.asm +++ /dev/null @@ -1,18 +0,0 @@ -.386 -.model flat, c - -_data$2 SEGMENT BYTE alias(".data$2") - db "orld", 0 -_data$2 ends - -_data$1 SEGMENT BYTE alias(".data$1") - db "o, w" -_data$1 ends - -.data - db "Hell" - -.code -main: - nop -end main Index: test/pecoff/Inputs/grouped-sections.obj.yaml =================================================================== --- test/pecoff/Inputs/grouped-sections.obj.yaml +++ /dev/null @@ -1,83 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: 90 - - Name: .data - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 4 - SectionData: 48656C6C - - Name: ".data$2" - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 1 - SectionData: 6F726C6400 - - Name: ".data$1" - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 1 - SectionData: 6F2C2077 -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 1 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: .data - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 4 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: ".data$2" - Value: 0 - SectionNumber: 3 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 5 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: ".data$1" - Value: 0 - SectionNumber: 4 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 4 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: foo - Value: 2 - SectionNumber: 4 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: _main - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/hello.asm =================================================================== --- test/pecoff/Inputs/hello.asm +++ /dev/null @@ -1,24 +0,0 @@ -;;; ml hello.asm /link /subsystem:windows /defaultlib:kernel32.lib \ -;;; /defaultlib:user32.lib /out:hello.exe /entry:main - -.386 -.model flat, c - -extern MessageBoxA@16 : PROC -extern ExitProcess@4 : PROC - -.data - caption db "Hello", 0 - message db "Hello World", 0 - -.code -main: - mov eax, 0 - push eax - push offset caption - push offset message - push eax - call MessageBoxA@16 - push eax - call ExitProcess@4 -end main Index: test/pecoff/Inputs/hello.obj.yaml =================================================================== --- test/pecoff/Inputs/hello.obj.yaml +++ /dev/null @@ -1,111 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: B800000000506800000000680000000050E80000000050E800000000 - Relocations: - - VirtualAddress: 7 - SymbolName: caption - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 12 - SymbolName: message - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 18 - SymbolName: _MessageBoxA@16 - Type: IMAGE_REL_I386_REL32 - - VirtualAddress: 24 - SymbolName: _ExitProcess@4 - Type: IMAGE_REL_I386_REL32 - - Name: .data - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 4 - SectionData: 48656C6C6F0048656C6C6F20576F726C6400 - - Name: .drectve - Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] - Alignment: 2147483648 - SectionData: 2F454E5452593A6D61696E20 -symbols: - - Name: "@comp.id" - Value: 10394907 - SectionNumber: 65535 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 28 - NumberOfRelocations: 4 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: .data - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 18 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: _MessageBoxA@16 - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: _ExitProcess@4 - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: message - Value: 6 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: _main - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: caption - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: .drectve - Value: 0 - SectionNumber: 3 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 12 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: .file - Value: 0 - SectionNumber: 65534 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - File: "hello.c" -... Index: test/pecoff/Inputs/hello64.asm =================================================================== --- test/pecoff/Inputs/hello64.asm +++ /dev/null @@ -1,22 +0,0 @@ -;; ml hello64.asm /link /subsystem:windows /defaultlib:kernel32 \ -;; /defaultlib:user32 /out:hello64.exe /entry:main - -extern ExitProcess : PROC -extern MessageBoxA : PROC - -.data - caption db 'Hello', 0 - message db 'Hello World', 0 - -.code -main PROC - sub rsp,28h - mov rcx, 0 - lea rdx, message - lea r8, caption - mov r9d, 0 - call MessageBoxA - mov ecx, 0 - call ExitProcess -main ENDP -END Index: test/pecoff/Inputs/hello64.obj.yaml =================================================================== --- test/pecoff/Inputs/hello64.obj.yaml +++ /dev/null @@ -1,110 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_AMD64 - Characteristics: [ ] -sections: - - Name: '.text$mn' - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 16 - SectionData: 4883EC2848C7C100000000488D15000000004C8D050000000041B900000000E800000000B900000000E800000000 - Relocations: - - VirtualAddress: 14 - SymbolName: message - Type: IMAGE_REL_AMD64_REL32 - - VirtualAddress: 21 - SymbolName: caption - Type: IMAGE_REL_AMD64_REL32 - - VirtualAddress: 32 - SymbolName: MessageBoxA - Type: IMAGE_REL_AMD64_REL32 - - VirtualAddress: 42 - SymbolName: ExitProcess - Type: IMAGE_REL_AMD64_REL32 - - Name: .data - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 16 - SectionData: 48656C6C6F0048656C6C6F20576F726C6400 - - Name: '.debug$S' - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] - Alignment: 1 - SectionData: 04000000F1000000830000004800011100000000433A5C63796777696E5C686F6D655C727569755C6C6C766D5C746F6F6C735C6C6C645C746573745C7065636F66665C496E707574735C68656C6C6F36342E6F626A0037003C1103020000D00000000000000000000C0000000D5201004D6963726F736F667420285229204D6163726F20417373656D626C6572000000 -symbols: - - Name: '@comp.id' - Value: 14635533 - SectionNumber: 65535 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: '@feat.00' - Value: 16 - SectionNumber: 65535 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: '.text$mn' - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 46 - NumberOfRelocations: 4 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: .data - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 18 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: '.debug$S' - Value: 0 - SectionNumber: 3 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 144 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: ExitProcess - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: MessageBoxA - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: message - Value: 6 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: caption - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: main - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/hello64lib.asm =================================================================== --- test/pecoff/Inputs/hello64lib.asm +++ /dev/null @@ -1,14 +0,0 @@ -.code -ExitProcess PROC - RET -ExitProcess ENDP - -MessageBoxA PROC - RET -MessageBoxA ENDP - -_DllMainCRTStartup PROC - RET -_DllMainCRTStartup ENDP - -END Index: test/pecoff/Inputs/imagebase.obj.yaml =================================================================== --- test/pecoff/Inputs/imagebase.obj.yaml +++ /dev/null @@ -1,55 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 16 - SectionData: A100000000C3 - Relocations: - - VirtualAddress: 1 - SymbolName: ___ImageBase - Type: IMAGE_REL_I386_DIR32 - - Name: .data - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 16 - SectionData: "" -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 6 - NumberOfRelocations: 1 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: .data - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 0 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: ___ImageBase - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: __start - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/machine-type-unknown.obj.yaml =================================================================== --- test/pecoff/Inputs/machine-type-unknown.obj.yaml +++ /dev/null @@ -1,38 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_UNKNOWN - Characteristics: [] -sections: - - Name: .drectve - Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] - Alignment: 2147483648 - SectionData: '' -symbols: - - Name: '@comp.id' - Value: 1 - SectionNumber: 65535 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: '@feat.00' - Value: 1 - SectionNumber: 65535 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: __imp___close - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: __imp__close - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_WEAK_EXTERNAL - WeakExternal: - TagIndex: 2 - Characteristics: IMAGE_WEAK_EXTERN_SEARCH_ALIAS -... Index: test/pecoff/Inputs/main.obj.yaml =================================================================== --- test/pecoff/Inputs/main.obj.yaml +++ /dev/null @@ -1,70 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: A100000000030500000000C3 - Relocations: - - VirtualAddress: 1 - SymbolName: _val1 - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 7 - SymbolName: _val2 - Type: IMAGE_REL_I386_DIR32 - - Name: .data - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 4 - SectionData: "" -symbols: - - Name: "@comp.id" - Value: 10394907 - SectionNumber: 65535 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 12 - NumberOfRelocations: 2 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: .data - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 0 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: _val1 - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: _val2 - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: _main - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/merge-largest1.obj.yaml =================================================================== --- test/pecoff/Inputs/merge-largest1.obj.yaml +++ /dev/null @@ -1,30 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 16 - SectionData: 00112233 -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 7 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 2532800969 - Number: 0 - Selection: IMAGE_COMDAT_SELECT_LARGEST - - Name: "_foo" - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/merge-largest2.obj.yaml =================================================================== --- test/pecoff/Inputs/merge-largest2.obj.yaml +++ /dev/null @@ -1,30 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 16 - SectionData: 0011223344556677 -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 7 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 2532800969 - Number: 0 - Selection: IMAGE_COMDAT_SELECT_LARGEST - - Name: "_foo" - Value: 6 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/merge-same-size1.obj.yaml =================================================================== --- test/pecoff/Inputs/merge-same-size1.obj.yaml +++ /dev/null @@ -1,30 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 16 - SectionData: FFFFFFFFFFFFFF -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 7 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 2532800969 - Number: 0 - Selection: IMAGE_COMDAT_SELECT_SAME_SIZE - - Name: "_foo" - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/merge-same-size2.obj.yaml =================================================================== --- test/pecoff/Inputs/merge-same-size2.obj.yaml +++ /dev/null @@ -1,30 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 16 - SectionData: AAAAAAAAAAAAAA -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 7 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 2532800969 - Number: 0 - Selection: IMAGE_COMDAT_SELECT_SAME_SIZE - - Name: "_foo" - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/merge-same-size3.obj.yaml =================================================================== --- test/pecoff/Inputs/merge-same-size3.obj.yaml +++ /dev/null @@ -1,30 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 16 - SectionData: FFFF -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 2 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 2532800969 - Number: 0 - Selection: IMAGE_COMDAT_SELECT_SAME_SIZE - - Name: "_foo" - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/nonstandard-sections.obj.yaml =================================================================== --- test/pecoff/Inputs/nonstandard-sections.obj.yaml +++ /dev/null @@ -1,53 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: 01234678 - - Name: .data - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 4 - SectionData: 01234678 - - Name: .foo - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE, IMAGE_SCN_MEM_EXECUTE ] - Alignment: 4 - SectionData: 01234678 - - Name: .bar - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: 01234678 -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: .data - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: .foo - Value: 0 - SectionNumber: 3 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: .bar - Value: 0 - SectionNumber: 4 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: _main - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/nop.asm =================================================================== --- test/pecoff/Inputs/nop.asm +++ /dev/null @@ -1,9 +0,0 @@ -.386 -.model flat, stdcall -option casemap :none - -.code -start: - mov eax, 42 - ret -end start Index: test/pecoff/Inputs/nop.obj.yaml =================================================================== --- test/pecoff/Inputs/nop.obj.yaml +++ /dev/null @@ -1,51 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: B82A000000C3 - - Name: .data - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 4 - SectionData: "" -symbols: - - Name: "@comp.id" - Value: 10394907 - SectionNumber: 65535 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 6 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: .data - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 0 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: _start - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/nop64.obj.yaml =================================================================== --- test/pecoff/Inputs/nop64.obj.yaml +++ /dev/null @@ -1,67 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_AMD64 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 16 - SectionData: C3C3C3C3 - Relocations: - - VirtualAddress: 0 - SymbolName: __imp__fn - Type: IMAGE_REL_AMD64_REL32 - - Name: .data - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 16 - SectionData: '' -symbols: - - Name: '@comp.id' - Value: 13485607 - SectionNumber: 65535 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: '@feat.00' - Value: 16 - SectionNumber: 65535 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 1 - NumberOfRelocations: 1 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: .data - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 0 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: __imp__fn - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: start - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/reloc.obj.yaml =================================================================== --- test/pecoff/Inputs/reloc.obj.yaml +++ /dev/null @@ -1,82 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 16 - SectionData: 680000000068000000006800000000680000000068000000006800000000 - Relocations: - - VirtualAddress: 1 - SymbolName: _message - Type: IMAGE_REL_I386_SECTION - - VirtualAddress: 6 - SymbolName: _message - Type: IMAGE_REL_I386_SECREL - - VirtualAddress: 11 - SymbolName: .data - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 16 - SymbolName: .data - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 21 - SymbolName: __imp__MessageBoxA@16 - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 26 - SymbolName: _abs_value - Type: IMAGE_REL_I386_DIR32 - - Name: .data - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 4 - SectionData: 576F726C64210048656C6C6F2C00 -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 60 - NumberOfRelocations: 3 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 1 - - Name: .data - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 14 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 2 - - Name: _main - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: _message - Value: 5 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: __imp__MessageBoxA@16 - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: _abs_value - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/reloc64.obj.yaml =================================================================== --- test/pecoff/Inputs/reloc64.obj.yaml +++ /dev/null @@ -1,63 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_AMD64 - Characteristics: [] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 16 - SectionData: 48B800000000000000ffE8000000ffE8000000ffE8000000ffE8000000ffE8000000ffE8000000ffE8000000ffE8000000ffC3 - Relocations: - - VirtualAddress: 2 - SymbolName: end - Type: IMAGE_REL_AMD64_ADDR64 - - VirtualAddress: 11 - SymbolName: end - Type: IMAGE_REL_AMD64_REL32 - - VirtualAddress: 16 - SymbolName: end - Type: IMAGE_REL_AMD64_REL32_1 - - VirtualAddress: 21 - SymbolName: end - Type: IMAGE_REL_AMD64_REL32_2 - - VirtualAddress: 26 - SymbolName: end - Type: IMAGE_REL_AMD64_REL32_3 - - VirtualAddress: 31 - SymbolName: end - Type: IMAGE_REL_AMD64_REL32_4 - - VirtualAddress: 36 - SymbolName: end - Type: IMAGE_REL_AMD64_REL32_5 - - VirtualAddress: 41 - SymbolName: end - Type: IMAGE_REL_AMD64_SECTION - - VirtualAddress: 46 - SymbolName: end - Type: IMAGE_REL_AMD64_SECREL -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 41 - NumberOfRelocations: 7 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: entry - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: end - Value: 40 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/resource.rc =================================================================== --- test/pecoff/Inputs/resource.rc +++ /dev/null @@ -1,4 +0,0 @@ -STRINGTABLE -{ - 1, "Hello" -} Index: test/pecoff/Inputs/responsefile.txt =================================================================== --- test/pecoff/Inputs/responsefile.txt +++ /dev/null @@ -1 +0,0 @@ --foo -bar\baz Index: test/pecoff/Inputs/secrel1.obj.yaml =================================================================== --- test/pecoff/Inputs/secrel1.obj.yaml +++ /dev/null @@ -1,69 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 16 - SectionData: C3 - - Name: .data - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 4 - SectionData: 00000000000000000000000000000000 - Relocations: - - VirtualAddress: 0 - SymbolName: .data - Type: IMAGE_REL_I386_SECREL - - Name: .data2 - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 4 - SectionData: 00000000000000000000000000000000 - Relocations: - - VirtualAddress: 0 - SymbolName: .data2 - Type: IMAGE_REL_I386_SECREL -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 60 - NumberOfRelocations: 1 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 1 - - Name: .data - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 4 - NumberOfRelocations: 1 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 2 - - Name: .data2 - Value: 0 - SectionNumber: 3 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 4 - NumberOfRelocations: 1 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 3 - - Name: _main - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/secrel2.obj.yaml =================================================================== --- test/pecoff/Inputs/secrel2.obj.yaml +++ /dev/null @@ -1,47 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .data - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 4 - SectionData: 00000000000000000000000000000000 - Relocations: - - VirtualAddress: 0 - SymbolName: .data - Type: IMAGE_REL_I386_SECREL - - Name: .data2 - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 4 - SectionData: 00000000000000000000000000000000 - Relocations: - - VirtualAddress: 0 - SymbolName: .data2 - Type: IMAGE_REL_I386_SECREL -symbols: - - Name: .data - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 4 - NumberOfRelocations: 1 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 1 - - Name: .data2 - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 4 - NumberOfRelocations: 1 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 2 -... Index: test/pecoff/Inputs/seh.c =================================================================== --- test/pecoff/Inputs/seh.c +++ /dev/null @@ -1,13 +0,0 @@ -__declspec(noinline) void triggerSEH() { - volatile int *p = 0; - *p = 1; -} - -int main() { - __try { - triggerSEH(); - } __except(1) { - return 42; - } - return 0; -} Index: test/pecoff/Inputs/seh.obj.yaml =================================================================== --- test/pecoff/Inputs/seh.obj.yaml +++ /dev/null @@ -1,387 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .drectve - Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] - Alignment: 1 - SectionData: 2020202F44454641554C544C49423A22757569642E6C696222202F44454641554C544C49423A22757569642E6C696222202F4641494C49464D49534D415443483A225F4D53435F5645523D3138303022202F4641494C49464D49534D415443483A225F4954455241544F525F44454255475F4C4556454C3D3022202F4641494C49464D49534D415443483A2252756E74696D654C6962726172793D4D445F44796E616D696352656C6561736522202F44454641554C544C49423A226D73766370727422202F44454641554C544C49423A224D535643525422202F44454641554C544C49423A224F4C444E414D45532220 - - Name: '.debug$S' - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] - Alignment: 1 - SectionData: 04000000F1000000600000002200011100000000433A5C63796777696E5C686F6D655C727569755C7365682E6F626A003A003C11012200000700120000000D520100120000000D5201004D6963726F736F667420285229204F7074696D697A696E6720436F6D70696C657200 - - Name: .rdata - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ] - Alignment: 1 - SectionData: 00 - - Name: .rdata - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ] - Alignment: 1 - SectionData: 01 - - Name: .rdata - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: 54726967676572696E672053454820657863657074696F6E0D0A0000457865637574696E6720534548205F5F65786365707420626C6F636B20696E20666F6F0D0A000000457865637574696E6720534548205F5F65786365707420626C6F636B0D0A00 - - Name: '.text$mn' - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 16 - SectionData: 558BEC516800000000FF150000000083C404C745FC000000008B45FCC700140000008BE55DC3CCCCCCCCCCCCCCCCCCCC558BEC51E8000000008D4DFFE8000000008BE55DC3CCCCCCCCCCCCCCCCCCCCCC558BEC6AFE6800000000680000000064A1000000005083EC08535657A1000000003145F833C5508D45F064A3000000008965E8C745FC00000000E800000000C745FCFEFFFFFFEB1EB801000000C38B65E86800000000FF150000000083C404C745FCFEFFFFFF8B4DF064890D00000000595F5E5B8BE55DC3CCCCCCCCCCCCCCCC558BEC6AFE6800000000680000000064A1000000005083EC08535657A1000000003145F833C5508D45F064A3000000008965E8C745FC00000000E800000000E800000000C745FCFEFFFFFFEB1EB801000000C38B65E86800000000FF150000000083C404C745FCFEFFFFFF33C08B4DF064890D00000000595F5E5B8BE55DC3 - Relocations: - - VirtualAddress: 5 - SymbolName: '$SG73531' - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 11 - SymbolName: __imp__printf - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 53 - SymbolName: '?TestCPPEX@@YAXXZ' - Type: IMAGE_REL_I386_REL32 - - VirtualAddress: 61 - SymbolName: '??1TestClass@@QAE@XZ' - Type: IMAGE_REL_I386_REL32 - - VirtualAddress: 86 - SymbolName: '__sehtable$?foo@@YAXXZ' - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 91 - SymbolName: __except_handler4 - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 109 - SymbolName: ___security_cookie - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 139 - SymbolName: '?TestExceptions@@YAXXZ' - Type: IMAGE_REL_I386_REL32 - - VirtualAddress: 162 - SymbolName: '$SG73539' - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 168 - SymbolName: __imp__printf - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 214 - SymbolName: '__sehtable$_main' - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 219 - SymbolName: __except_handler4 - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 237 - SymbolName: ___security_cookie - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 267 - SymbolName: '?foo@@YAXXZ' - Type: IMAGE_REL_I386_REL32 - - VirtualAddress: 272 - SymbolName: '?TestExceptions@@YAXXZ' - Type: IMAGE_REL_I386_REL32 - - VirtualAddress: 295 - SymbolName: '$SG73543' - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 301 - SymbolName: __imp__printf - Type: IMAGE_REL_I386_DIR32 - - Name: '.text$mn' - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 16 - SectionData: 558BEC51894DFC6800000000FF150000000083C4048BE55DC3 - Relocations: - - VirtualAddress: 8 - SymbolName: '??_C@_0BI@BBHGNMOG@Destroying?5TestClass?$CB?$AN?6?$AA@' - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 14 - SymbolName: __imp__printf - Type: IMAGE_REL_I386_DIR32 - - Name: '.xdata$x' - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] - Alignment: 8 - SectionData: FEFFFFFF00000000D8FFFFFF00000000FEFFFFFF000000000000000000000000FEFFFFFF00000000D8FFFFFF00000000FEFFFFFF0000000000000000 - Relocations: - - VirtualAddress: 20 - SymbolName: '$LN5' - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 24 - SymbolName: '$LN6' - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 52 - SymbolName: '$LN5' - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 56 - SymbolName: '$LN6' - Type: IMAGE_REL_I386_DIR32 - - Name: .rdata - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: 44657374726F79696E672054657374436C617373210D0A00 - - Name: .sxdata - Characteristics: [ IMAGE_SCN_LNK_INFO ] - Alignment: 4 - SectionData: 1B0000001A000000 -symbols: - - Name: '@comp.id' - Value: 14766605 - SectionNumber: 65535 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: '@feat.00' - Value: 2147484049 - SectionNumber: 65535 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: .drectve - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 240 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: '.debug$S' - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 108 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: .rdata - Value: 0 - SectionNumber: 3 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 1 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - Selection: IMAGE_COMDAT_SELECT_ANY - - Name: '?value@?$integral_constant@_N$0A@@std@@2_NB' - Value: 0 - SectionNumber: 3 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: .rdata - Value: 0 - SectionNumber: 4 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 1 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 1996959894 - Number: 0 - Selection: IMAGE_COMDAT_SELECT_ANY - - Name: '?value@?$integral_constant@_N$00@std@@2_NB' - Value: 0 - SectionNumber: 4 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: .rdata - Value: 0 - SectionNumber: 5 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 99 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 2801625422 - Number: 0 - - Name: '$SG73531' - Value: 0 - SectionNumber: 5 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: '$SG73539' - Value: 28 - SectionNumber: 5 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: '$SG73543' - Value: 68 - SectionNumber: 5 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: '.text$mn' - Value: 0 - SectionNumber: 6 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 335 - NumberOfRelocations: 17 - NumberOfLinenumbers: 0 - CheckSum: 2488225337 - Number: 0 - - Name: '.text$mn' - Value: 0 - SectionNumber: 7 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 25 - NumberOfRelocations: 2 - NumberOfLinenumbers: 0 - CheckSum: 210566957 - Number: 0 - Selection: IMAGE_COMDAT_SELECT_ANY - - Name: __imp__printf - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: '??1TestClass@@QAE@XZ' - Value: 0 - SectionNumber: 7 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: '?TestCPPEX@@YAXXZ' - Value: 0 - SectionNumber: 6 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: '?TestExceptions@@YAXXZ' - Value: 48 - SectionNumber: 6 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: '?foo@@YAXXZ' - Value: 80 - SectionNumber: 6 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: _main - Value: 208 - SectionNumber: 6 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: __except_handler4 - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: '$LN5' - Value: 152 - SectionNumber: 6 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_LABEL - - Name: '$LN7' - Value: 157 - SectionNumber: 6 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_LABEL - - Name: '$LN6' - Value: 158 - SectionNumber: 6 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_LABEL - - Name: '$LN5' - Value: 285 - SectionNumber: 6 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_LABEL - - Name: '$LN7' - Value: 290 - SectionNumber: 6 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_LABEL - - Name: '$LN6' - Value: 291 - SectionNumber: 6 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_LABEL - - Name: '.xdata$x' - Value: 0 - SectionNumber: 8 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 60 - NumberOfRelocations: 4 - NumberOfLinenumbers: 0 - CheckSum: 2900129504 - Number: 0 - - Name: '__sehtable$?foo@@YAXXZ' - Value: 32 - SectionNumber: 8 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: '__sehtable$_main' - Value: 0 - SectionNumber: 8 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: .rdata - Value: 0 - SectionNumber: 9 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 24 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 1296623929 - Number: 0 - Selection: IMAGE_COMDAT_SELECT_ANY - - Name: '??_C@_0BI@BBHGNMOG@Destroying?5TestClass?$CB?$AN?6?$AA@' - Value: 0 - SectionNumber: 9 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: ___security_cookie - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: .sxdata - Value: 0 - SectionNumber: 10 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 4 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 -... Index: test/pecoff/Inputs/static-data1.obj.yaml =================================================================== --- test/pecoff/Inputs/static-data1.obj.yaml +++ /dev/null @@ -1,67 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: "" - - Name: .data - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 4 - SectionData: 03000000 - - Name: ".debug$S" - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] - Alignment: 1 - SectionData: 04000000F1000000660000002B00011100000000433A5C63796777696E5C686F6D655C727569755C7374617469635C64617461312E6F626A0037003C1103020000030000000000000000000A0000001B9D01004D6963726F736F667420285229204D6163726F20417373656D626C657200000000 -symbols: - - Name: "@comp.id" - Value: 10394907 - SectionNumber: 65535 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 0 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: .data - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 4 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: ".debug$S" - Value: 0 - SectionNumber: 3 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 116 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: _val1 - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/static-data2.obj.yaml =================================================================== --- test/pecoff/Inputs/static-data2.obj.yaml +++ /dev/null @@ -1,67 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: "" - - Name: .data - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 4 - SectionData: 04000000 - - Name: ".debug$S" - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] - Alignment: 1 - SectionData: 04000000F1000000660000002B00011100000000433A5C63796777696E5C686F6D655C727569755C7374617469635C64617461322E6F626A0037003C1103020000030000000000000000000A0000001B9D01004D6963726F736F667420285229204D6163726F20417373656D626C657200000000 -symbols: - - Name: "@comp.id" - Value: 10394907 - SectionNumber: 65535 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 0 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: .data - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 4 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: ".debug$S" - Value: 0 - SectionNumber: 3 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 116 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: _val2 - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/subsystem.main.yaml =================================================================== --- test/pecoff/Inputs/subsystem.main.yaml +++ /dev/null @@ -1,35 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: B82A000000C3 -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 6 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: _main - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: _mainCRTStartup - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/subsystem.winmain.yaml =================================================================== --- test/pecoff/Inputs/subsystem.winmain.yaml +++ /dev/null @@ -1,35 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: B82A000000C3 -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 6 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: _WinMain - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: _WinMainCRTStartup - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/tlsused.obj.yaml =================================================================== --- test/pecoff/Inputs/tlsused.obj.yaml +++ /dev/null @@ -1,29 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [] -sections: - - Name: .data - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 4 - SectionData: "0000000000000000" -symbols: - - Name: .data - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 8 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: __tls_used - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/unknown-drectve.obj.yaml =================================================================== --- test/pecoff/Inputs/unknown-drectve.obj.yaml +++ /dev/null @@ -1,42 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 16 - SectionData: 558BEC56FF15000000008B0D000000008B3103F0FF150000000003C65E5DC3 - - Name: .drectve - Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] - Alignment: 2147483648 - - # /nosuchoption:foobar - SectionData: 2f6e6f737563686f7074696f6e3a666f6f62617200 - -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 31 - NumberOfRelocations: 3 - NumberOfLinenumbers: 0 - CheckSum: 3595596940 - Number: 0 - - Name: .drectve - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 13 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 -... Index: test/pecoff/Inputs/unwind.obj.yaml =================================================================== --- test/pecoff/Inputs/unwind.obj.yaml +++ /dev/null @@ -1,129 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_AMD64 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: 4883EC184889742410440F110424534889E3488D235B4883C418C3C34881ECF0FF00004881ECF0FF80004881C4F0FF80004881C4F0FF0000C3 - - Name: .xdata - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: 0912080312030F300E880000096402000422001A000000000000000021000000000000001B000000000000000100000000000000010E06000E11F0FF80000701FE1F001A - Relocations: - - VirtualAddress: 20 - SymbolName: __C_specific_handler - Type: IMAGE_REL_AMD64_ADDR32NB - - VirtualAddress: 32 - SymbolName: func - Type: IMAGE_REL_AMD64_ADDR32NB - - VirtualAddress: 36 - SymbolName: func - Type: IMAGE_REL_AMD64_ADDR32NB - - VirtualAddress: 40 - SymbolName: .xdata - Type: IMAGE_REL_AMD64_ADDR32NB - - Name: .pdata - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: 000000001B0000000000000012000000120000001C00000000000000010000002C000000000000001D00000034000000 - Relocations: - - VirtualAddress: 0 - SymbolName: func - Type: IMAGE_REL_AMD64_ADDR32NB - - VirtualAddress: 4 - SymbolName: func - Type: IMAGE_REL_AMD64_ADDR32NB - - VirtualAddress: 8 - SymbolName: .xdata - Type: IMAGE_REL_AMD64_ADDR32NB - - VirtualAddress: 12 - SymbolName: func - Type: IMAGE_REL_AMD64_ADDR32NB - - VirtualAddress: 16 - SymbolName: func - Type: IMAGE_REL_AMD64_ADDR32NB - - VirtualAddress: 20 - SymbolName: .xdata - Type: IMAGE_REL_AMD64_ADDR32NB - - VirtualAddress: 24 - SymbolName: smallFunc - Type: IMAGE_REL_AMD64_ADDR32NB - - VirtualAddress: 28 - SymbolName: smallFunc - Type: IMAGE_REL_AMD64_ADDR32NB - - VirtualAddress: 32 - SymbolName: .xdata - Type: IMAGE_REL_AMD64_ADDR32NB - - VirtualAddress: 36 - SymbolName: allocFunc - Type: IMAGE_REL_AMD64_ADDR32NB - - VirtualAddress: 40 - SymbolName: allocFunc - Type: IMAGE_REL_AMD64_ADDR32NB - - VirtualAddress: 44 - SymbolName: .xdata - Type: IMAGE_REL_AMD64_ADDR32NB -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 57 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 1 - - Name: .xdata - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 68 - NumberOfRelocations: 4 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 2 - - Name: .pdata - Value: 0 - SectionNumber: 3 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 48 - NumberOfRelocations: 12 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 3 - - Name: func - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: __C_specific_handler - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: smallFunc - Value: 27 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: allocFunc - Value: 28 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/vars-main-x64.obj.yaml =================================================================== --- test/pecoff/Inputs/vars-main-x64.obj.yaml +++ /dev/null @@ -1,63 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_AMD64 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 16 - SectionData: 558BEC56FF15000000008B0D000000008B3103F0FF150000000003C65E5DC3 - Relocations: - - VirtualAddress: 6 - SymbolName: __imp_fn - Type: IMAGE_REL_AMD64_ADDR32 - - VirtualAddress: 12 - SymbolName: __imp_var - Type: IMAGE_REL_AMD64_ADDR32 - - VirtualAddress: 22 - SymbolName: __imp__name_with_underscore - Type: IMAGE_REL_AMD64_ADDR32 -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 31 - NumberOfRelocations: 3 - NumberOfLinenumbers: 0 - CheckSum: 3595596940 - Number: 0 - - Name: __imp_fn - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: __imp__name_with_underscore - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: main - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: "__delayLoadHelper2" - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: __imp_var - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/vars-main-x86.obj.yaml =================================================================== --- test/pecoff/Inputs/vars-main-x86.obj.yaml +++ /dev/null @@ -1,69 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 16 - SectionData: 558BEC56FF15000000008B0D000000008B3103F0FF150000000003C65E5DC3 - Relocations: - - VirtualAddress: 6 - SymbolName: __imp__fn - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 12 - SymbolName: __imp__var - Type: IMAGE_REL_I386_DIR32 - - VirtualAddress: 22 - SymbolName: __imp___name_with_underscore - Type: IMAGE_REL_I386_DIR32 -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 31 - NumberOfRelocations: 3 - NumberOfLinenumbers: 0 - CheckSum: 3595596940 - Number: 0 - - Name: __imp__fn - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: __imp___name_with_underscore - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: _main - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: "___delayLoadHelper2@8" - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: __imp__var - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: ___ImageBase - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/Inputs/vars-main.c =================================================================== --- test/pecoff/Inputs/vars-main.c +++ /dev/null @@ -1,7 +0,0 @@ -__declspec(dllimport) int var; -__declspec(dllimport) int fn(void); -__declspec(dllimport) int _name_with_underscore(void); - -int main() { - return var + fn() + _name_with_underscore(); -} Index: test/pecoff/Inputs/vars.c =================================================================== --- test/pecoff/Inputs/vars.c +++ /dev/null @@ -1,20 +0,0 @@ -// cl.exe /c vars.c -// link /dll /nodefaultlib /entry:dllmain /export:var,@1,NONAME,DATA \ -// /export:fn /export:_name_with_underscore vars.obj - -// will be exported by ordinal -int var = 3; - -// will be exported by name -int fn(void) { - return 4; -} - -// will be exported by name -int _name_with_underscore(void) { - return 5; -} - -int dllmain() { - return 1; -} Index: test/pecoff/Inputs/vars.dll.yaml =================================================================== --- test/pecoff/Inputs/vars.dll.yaml +++ /dev/null @@ -1,19 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_32BIT_MACHINE, IMAGE_FILE_DLL ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 2147483648 - SectionData: 558BECB8040000005DC3CCCCCCCCCCCC558BECB8050000005DC3CCCCCCCCCCCC558BECB8010000005DC30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - - Name: .rdata - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] - Alignment: 2147483648 - SectionData: 0000000050570852000000004020000001000000030000000200000028200000342000003C200000003000001010000000100000492000005F20000001000200766172732E646C6C005F6E616D655F776974685F756E64657273636F726500666E00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - - Name: .data - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 2147483648 - SectionData: 0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -symbols: -... Index: test/pecoff/Inputs/weak-externals.asm =================================================================== --- test/pecoff/Inputs/weak-externals.asm +++ /dev/null @@ -1,25 +0,0 @@ -.386 -.model flat - -;; val1 should be linked normally. no_such_symbol1 should be ignored. -extern _no_such_symbol1 : PROC -extern _val1 (_no_such_symbol1): PROC - -;; no_such_symbol2 should be linked as val2. -extern _val2 : PROC -extern _no_such_symbol2 (_val2) : PROC - -;; no_such_symbol3 should fail to link. -extern _no_such_symbol3 : PROC - -public _fn1 -.code -_fn1: - push ebp - mov ebp, esp - call _val1 - call _no_such_symbol2 - call _no_such_symbol3 - pop ebp - ret 0 -end _fn1 Index: test/pecoff/Inputs/weak-externals.obj.yaml =================================================================== --- test/pecoff/Inputs/weak-externals.obj.yaml +++ /dev/null @@ -1,91 +0,0 @@ ---- -header: - Machine: IMAGE_FILE_MACHINE_I386 - Characteristics: [ ] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - Alignment: 4 - SectionData: 558BECE800000000E800000000E8000000005DC3 - Relocations: - - VirtualAddress: 4 - SymbolName: _val1 - Type: IMAGE_REL_I386_REL32 - - VirtualAddress: 9 - SymbolName: _no_such_symbol2 - Type: IMAGE_REL_I386_REL32 - - VirtualAddress: 14 - SymbolName: _no_such_symbol3 - Type: IMAGE_REL_I386_REL32 - - Name: .data - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] - Alignment: 4 - SectionData: "" -symbols: - - Name: .text - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 20 - NumberOfRelocations: 3 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: .data - Value: 0 - SectionNumber: 2 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_STATIC - SectionDefinition: - Length: 0 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 - - Name: _no_such_symbol1 - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: _val2 - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: _no_such_symbol3 - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: _val1 - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_WEAK_EXTERNAL - WeakExternal: - TagIndex: 4 - Characteristics: IMAGE_WEAK_EXTERN_SEARCH_LIBRARY - - Name: _no_such_symbol2 - Value: 0 - SectionNumber: 0 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_WEAK_EXTERNAL - WeakExternal: - TagIndex: 5 - Characteristics: IMAGE_WEAK_EXTERN_SEARCH_LIBRARY - - Name: _fn1 - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_NULL - StorageClass: IMAGE_SYM_CLASS_EXTERNAL -... Index: test/pecoff/alignment.test =================================================================== --- test/pecoff/alignment.test +++ /dev/null @@ -1,22 +0,0 @@ -# RUN: yaml2obj %p/Inputs/alignment.obj.yaml > %t.obj -# -# RUN: lld -flavor link /out:%t.exe /subsystem:console /force \ -# RUN: /entry:start /opt:noref -- %t.obj -# RUN: llvm-readobj -sections %t.exe | FileCheck %s - -CHECK: Name: .bss (2E 62 73 73 00 00 00 00) -CHECK: RawDataSize: 0 - -CHECK: Name: .data (2E 64 61 74 61 00 00 00) -CHECK-NEXT: VirtualSize: 0x6 - -CHECK: Name: .text (2E 74 65 78 74 00 00 00) -CHECK-NEXT: VirtualSize: 0x1001 - -CHECK: Name: .yyy -CHECK-NEXT: VirtualSize: 0x2 -CHECK-NEXT: VirtualAddress: 0x5000 - -CHECK: Name: .zzz -CHECK-NEXT: VirtualSize: 0x2 -CHECK-NEXT: VirtualAddress: 0x8000 Index: test/pecoff/alternatename.test =================================================================== --- test/pecoff/alternatename.test +++ /dev/null @@ -1,44 +0,0 @@ -# REQUIRES: x86 - -# RUN: yaml2obj %p/Inputs/alternatename1.obj.yaml > %t1.obj -# RUN: yaml2obj %p/Inputs/alternatename2.obj.yaml > %t2.obj -# RUN: yaml2obj %p/Inputs/alternatename3.obj.yaml > %t3.obj -# -# RUN: lld -flavor link /force /out:%t1.exe /alternatename:_main=_foo \ -# RUN: /subsystem:console -- %t1.obj -# RUN: llvm-objdump -d %t1.exe | FileCheck -check-prefix=CHECK1 %s -# -# RUN: lld -flavor link /force /out:%t2.exe /alternatename:_main=_foo \ -# RUN: /subsystem:console -- %t1.obj %t2.obj -# RUN: llvm-objdump -d %t2.exe | FileCheck -check-prefix=CHECK2 %s -# -# RUN: lld -flavor link /force /out:%t3.exe /subsystem:console -- %t3.obj -# RUN: llvm-objdump -d %t3.exe | FileCheck -check-prefix=CHECK3 %s -# -# RUN: lld -flavor link /force /out:%t4.exe /alternatename:_main=_foo \ -# RUN: /alternatename:_xyz=_foo /subsystem:console -- %t1.obj -# RUN: llvm-objdump -d %t4.exe | FileCheck -check-prefix=CHECK4 %s - -CHECK1: nop -CHECK1-NEXT: nop -CHECK1-NEXT: nop -CHECK1-NEXT: nop -CHECK1-NOT: int3 - -CHECK2: int3 -CHECK2-NEXT: int3 -CHECK2-NEXT: int3 -CHECK2-NEXT: int3 -CHECK2-NOT: nop - -CHECK3: nop -CHECK3-NEXT: nop -CHECK3-NEXT: nop -CHECK3-NEXT: nop -CHECK3-NOT: int3 - -CHECK4: nop -CHECK4-NEXT: nop -CHECK4-NEXT: nop -CHECK4-NEXT: nop -CHECK4-NOT: int3 Index: test/pecoff/armnt-ImageBase.test =================================================================== --- test/pecoff/armnt-ImageBase.test +++ /dev/null @@ -1,14 +0,0 @@ -# RUN: yaml2obj -format coff -o %t.obj %p/Inputs/armnt-ImageBase.obj.yaml -# RUN: llvm-readobj -r %t.obj | FileCheck %s -check-prefix BEFORE -# RUN: lld -flavor link /out:%t.exe %t.obj /subsystem:console -# RUN: llvm-readobj -r %t.exe | FileCheck %s -check-prefix AFTER - -BEFORE: Relocations [ -BEFORE: Section {{.*}} .text { -BEFORE: 0x4 IMAGE_REL_ARM_ADDR32 __ImageBase -BEFORE: } -BEFORE: ] - -AFTER: Relocations [ -AFTER-NEXT: ] - Index: test/pecoff/armnt-addr32-exec.test =================================================================== --- test/pecoff/armnt-addr32-exec.test +++ /dev/null @@ -1,11 +0,0 @@ -# RUN: yaml2obj -format coff -o %t.obj %p/Inputs/armnt-addr32-exec.obj.yaml -# RUN: llvm-objdump -s %t.obj | FileCheck %s -check-prefix BEFORE -# RUN: lld -flavor link /out:%t.exe /entry:function /subsystem:console %t.obj -# RUN: llvm-objdump -s %t.exe | FileCheck %s -check-prefix AFTER - -BEFORE: Contents of section .rdata: -BEFORE: 0000 00000000 - -AFTER: Contents of section .rdata: -AFTER: 1000 01204000 - Index: test/pecoff/armnt-addr32.test =================================================================== --- test/pecoff/armnt-addr32.test +++ /dev/null @@ -1,11 +0,0 @@ -# RUN: yaml2obj -format coff -o %t.obj %p/Inputs/armnt-addr32.obj.yaml -# RUN: llvm-objdump -s %t.obj | FileCheck %s -check-prefix BEFORE -# RUN: lld -flavor link /entry:is /subsystem:console /out:%t.exe %t.obj -# RUN: llvm-objdump -s %t.exe | FileCheck %s -check-prefix AFTER - -BEFORE: Contents of section .rdata: -BEFORE: 0000 00000000 00000000 - -AFTER: Contents of section .rdata: -AFTER: 1000 00104000 00000000 - Index: test/pecoff/armnt-address-of-entry-point.test =================================================================== --- test/pecoff/armnt-address-of-entry-point.test +++ /dev/null @@ -1,6 +0,0 @@ -# RUN: yaml2obj -format coff -o %t.obj %p/Inputs/executable.obj.yaml -# RUN: lld -flavor link /out:%t.exe %t.obj -# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s - -# CHECK: AddressOfEntryPoint: 0x1001 - Index: test/pecoff/armnt-blx23t.test =================================================================== --- test/pecoff/armnt-blx23t.test +++ /dev/null @@ -1,27 +0,0 @@ -# REQUIRES: arm - -# RUN: yaml2obj -format coff -o %t.obj %p/Inputs/armnt-blx23t.obj.yaml -# RUN: llvm-objdump -d %t.obj | FileCheck %s -check-prefix BEFORE -# RUN: lld -flavor link /entry:function /subsystem:console /out:%t.exe %t.obj -# RUN: llvm-objdump -d %t.exe | FileCheck %s -check-prefix AFTER - -BEFORE: Disassembly of section .text: -BEFORE: 0: 70 47 bx lr -BEFORE: 2: 00 bf nop -BEFORE: 4: 2d e9 00 48 push.w {r11, lr} -BEFORE: 8: eb 46 mov r11, sp -BEFORE: a: 20 20 movs r0, #32 -BEFORE: c: 00 f0 00 f8 bl #0 -BEFORE: 10: 01 30 adds r0, #1 -BEFORE: 12: bd e8 00 88 pop.w {r11, pc} - -AFTER: Disassembly of section .text: -AFTER: 1000: 70 47 bx lr -AFTER: 1002: 00 bf nop -AFTER: 1004: 2d e9 00 48 push.w {r11, lr} -AFTER: 1008: eb 46 mov r11, sp -AFTER: 100a: 20 20 movs r0, #32 -AFTER: 100c: ff f7 f8 ff bl #-16 -AFTER: 1010: 01 30 adds r0, #1 -AFTER: 1012: bd e8 00 88 pop.w {r11, pc} - Index: test/pecoff/armnt-branch24t.test =================================================================== --- test/pecoff/armnt-branch24t.test +++ /dev/null @@ -1,20 +0,0 @@ -# REQUIRES: arm - -# RUN: yaml2obj -format coff -o %t.obj %p/Inputs/armnt-branch24t.obj.yaml -# RUN: llvm-objdump -d %t.obj | FileCheck %s -check-prefix BEFORE -# RUN: lld -flavor link /entry:function /subsystem:console /out:%t.exe %t.obj -# RUN: llvm-objdump -d %t.exe | FileCheck %s -check-prefix AFTER - -BEFORE: Disassembly of section .text: -BEFORE: 0: 70 47 bx lr -BEFORE: 2: 00 bf nop -BEFORE: 4: 20 20 movs r0, #32 -BEFORE: 6: 00 f0 00 b8 b.w #0 - -AFTER: Disassembly of section .text: -AFTER: .text: -AFTER: 1000: 70 47 bx lr -AFTER: 1002: 00 bf nop -AFTER: 1004: 20 20 movs r0, #32 -AFTER: 1006: ff f7 fb bf b.w #-10 - Index: test/pecoff/armnt-exports.s =================================================================== --- test/pecoff/armnt-exports.s +++ /dev/null @@ -1,28 +0,0 @@ - -# void __declspec(dllexport) function() {} -# void _DllMainCRTStartup() {} - - .syntax unified - .thumb - .text - - .def function - .scl 2 - .type 32 - .endef - .global function - .align 2 - .thumb_func -function: - bx lr - - .def _DllMainCRTStartup - .scl 2 - .type 32 - .endef - .global _DllMainCRTStartup - .align 2 - .thumb_func -_DllMainCRTStartup - bx lr - Index: test/pecoff/armnt-exports.test =================================================================== --- test/pecoff/armnt-exports.test +++ /dev/null @@ -1,10 +0,0 @@ -# RUN: yaml2obj -format coff -o %t.obj %p/Inputs/armnt-exports.obj.yaml -# RUN: lld -flavor link /dll /def:%p/Inputs/armnt-exports.def /out:%t.dll %t.obj -# RUN: llvm-readobj -coff-exports %t.dll | FileCheck %s - -CHECK: Export { -CHECK: Ordinal: 1 -CHECK: Name: function -CHECK: RVA: 0x2001 -CHECK: } - Index: test/pecoff/armnt-imports.test =================================================================== --- test/pecoff/armnt-imports.test +++ /dev/null @@ -1,11 +0,0 @@ -# RUN: yaml2obj -format coff -o %t.obj %p/Inputs/armnt-import.obj.yaml -# RUN: lld -flavor link /out:%t.exe /subsystem:console %t.obj %p/Inputs/library.lib -# RUN: llvm-readobj -coff-imports %t.exe | FileCheck %s - -CHECK: Import { -CHECK: Name: library.dll -CHECK: ImportLookupTableRVA: 0x4000 -CHECK: ImportAddressTableRVA: 0x2000 -CHECK: Symbol: function (0) -CHECK: } - Index: test/pecoff/armnt-mov32t-exec.test =================================================================== --- test/pecoff/armnt-mov32t-exec.test +++ /dev/null @@ -1,21 +0,0 @@ -# REQUIRES: arm - -# RUN: yaml2obj -format coff -o %t.obj %p/Inputs/armnt-mov32t-exec.obj.yaml -# RUN: llvm-objdump -d %t.obj | FileCheck %s -check-prefix BEFORE -# RUN: lld -flavor link /out:%t.exe /subsystem:console /entry:get_function %t.obj -# RUN: llvm-objdump -d %t.exe | FileCheck %s -check-prefix AFTER - -BEFORE: Disassembly of section .text: -BEFORE: 0: 70 47 bx lr -BEFORE: 2: 00 bf nop -BEFORE: 4: 40 f2 00 00 movw r0, #0 -BEFORE: 8: c0 f2 00 00 movt r0, #0 -BEFORE: c: 70 47 bx lr - -AFTER: Disassembly of section .text: -AFTER: 1000: 70 47 bx lr -AFTER: 1002: 00 bf nop -AFTER: 1004: 41 f2 01 00 movw r0, #4097 -AFTER: 1008: c0 f2 40 00 movt r0, #64 -AFTER: 100c: 70 47 bx lr - Index: test/pecoff/armnt-movt32t.test =================================================================== --- test/pecoff/armnt-movt32t.test +++ /dev/null @@ -1,17 +0,0 @@ -# REQUIRES: arm - -# RUN: yaml2obj -format coff -o %t.obj %p/Inputs/armnt-mov32t.obj.yaml -# RUN: llvm-objdump -d %t.obj | FileCheck %s -check-prefix BEFORE -# RUN: lld -flavor link /entry:get_buffer /subsystem:console /out:%t.exe %t.obj -# RUN: llvm-objdump -d %t.exe | FileCheck %s -check-prefix AFTER - -BEFORE: Disassembly of section .text: -BEFORE: 0: 40 f2 00 00 movw r0, #0 -BEFORE: 4: c0 f2 00 00 movt r0, #0 -BEFORE: 8: 70 47 bx lr - -AFTER: Disassembly of section .text: -AFTER: 0: 41 f2 00 00 movw r0, #4096 -AFTER: 4: c0 f2 40 00 movt r0, #64 -AFTER: 8: 70 47 bx lr - Index: test/pecoff/armnt.test =================================================================== --- test/pecoff/armnt.test +++ /dev/null @@ -1,6 +0,0 @@ -# RUN: yaml2obj -format coff -o %t.obj %p/Inputs/armnt-obj.yaml -# RUN: lld -flavor link /out:%t.dll /subsystem:console /entry:main %t.obj -# RUN: llvm-readobj -sections %t.dll | FileCheck %s - -CHECK: Format: COFF-ARM - Index: test/pecoff/associative.test =================================================================== --- test/pecoff/associative.test +++ /dev/null @@ -1,10 +0,0 @@ -# RUN: yaml2obj %p/Inputs/associative1.obj.yaml > %t1.obj -# RUN: yaml2obj %p/Inputs/associative1.obj.yaml > %t2.obj -# RUN: yaml2obj %p/Inputs/associative3.obj.yaml > %t3.obj -# -# RUN: lld -flavor link /machine:x86 /subsystem:console /entry:main \ -# RUN: /out:%t.exe -- %t1.obj %t2.obj %t3.obj -# RUN: obj2yaml %t.exe | FileCheck %s - -CHECK: - Name: .CRT -CHECK: SectionData: '77777777' Index: test/pecoff/base-reloc.test =================================================================== --- test/pecoff/base-reloc.test +++ /dev/null @@ -1,78 +0,0 @@ -# RUN: yaml2obj %p/Inputs/basereloc.obj.yaml > %t.obj -# -# RUN: lld -flavor link /out:%t.exe /subsystem:console /force /opt:noref \ -# RUN: -- %t.obj -# RUN: llvm-readobj -coff-basereloc %t.exe | FileCheck %s --check-prefix=BASEREL -# -# RUN: lld -flavor link /out:%t2.exe /subsystem:console /force /fixed \ -# RUN: /opt:noref -- %t.obj -# RUN: llvm-readobj -coff-basereloc %t2.exe | FileCheck %s --check-prefix=NOBASEREL - -BASEREL: BaseReloc [ -BASEREL-NEXT: Entry { -BASEREL-NEXT: Type: HIGHLOW -BASEREL-NEXT: Address: 0x2007 -BASEREL-NEXT: } -BASEREL-NEXT: Entry { -BASEREL-NEXT: Type: HIGHLOW -BASEREL-NEXT: Address: 0x200C -BASEREL-NEXT: } -BASEREL-NEXT: Entry { -BASEREL-NEXT: Type: HIGHLOW -BASEREL-NEXT: Address: 0x201E -BASEREL-NEXT: } -BASEREL-NEXT: Entry { -BASEREL-NEXT: Type: ABSOLUTE -BASEREL-NEXT: Address: 0x2000 -BASEREL-NEXT: } -BASEREL-NEXT: Entry { -BASEREL-NEXT: Type: HIGHLOW -BASEREL-NEXT: Address: 0x3007 -BASEREL-NEXT: } -BASEREL-NEXT: Entry { -BASEREL-NEXT: Type: HIGHLOW -BASEREL-NEXT: Address: 0x300C -BASEREL-NEXT: } -BASEREL-NEXT: Entry { -BASEREL-NEXT: Type: HIGHLOW -BASEREL-NEXT: Address: 0x301E -BASEREL-NEXT: } -BASEREL-NEXT: Entry { -BASEREL-NEXT: Type: ABSOLUTE -BASEREL-NEXT: Address: 0x3000 -BASEREL-NEXT: } -BASEREL-NEXT: ] - -NOBASEREL: BaseReloc [ -NOBASEREL-NEXT: ] - -# RUN: lld -flavor link /out:%t3.exe /subsystem:console /force /opt:noref \ -# RUN: -- %t.obj -# RUN: llvm-readobj -file-headers -sections %t3.exe | FileCheck %s \ -# RUN: --check-prefix=BASEREL-HEADER -# -# RUN: lld -flavor link /out:%t4.exe /subsystem:console /force /opt:noref \ -# RUN: /fixed -- %t.obj -# RUN: llvm-readobj -file-headers %t4.exe | FileCheck %s \ -# RUN: --check-prefix=NOBASEREL-HEADER - -BASEREL-HEADER-NOT: IMAGE_FILE_RELOCS_STRIPPED - -NOBASEREL-HEADER: IMAGE_FILE_RELOCS_STRIPPED - -BASEREL-HEADER: BaseRelocationTableRVA: 0x4000 -BASEREL-HEADER: BaseRelocationTableSize: 0x20 -BASEREL-HEADER: Name: .reloc (2E 72 65 6C 6F 63 00 00) -BASEREL-HEADER-NEXT: VirtualSize: 0x20 -BASEREL-HEADER-NEXT: VirtualAddress: 0x4000 -BASEREL-HEADER-NEXT: RawDataSize: 512 -BASEREL-HEADER-NEXT: PointerToRawData: 0xA00 -BASEREL-HEADER-NEXT: PointerToRelocations: 0x0 -BASEREL-HEADER-NEXT: PointerToLineNumbers: 0x0 -BASEREL-HEADER-NEXT: RelocationCount: 0 -BASEREL-HEADER-NEXT: LineNumberCount: 0 -BASEREL-HEADER-NEXT: Characteristics [ (0x42000040) -BASEREL-HEADER-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) -BASEREL-HEADER-NEXT: IMAGE_SCN_MEM_DISCARDABLE (0x2000000) -BASEREL-HEADER-NEXT: IMAGE_SCN_MEM_READ (0x40000000) -BASEREL-HEADER-NEXT: ] Index: test/pecoff/baseaddr.test =================================================================== --- test/pecoff/baseaddr.test +++ /dev/null @@ -1,18 +0,0 @@ -# RUN: yaml2obj %p/Inputs/nop.obj.yaml > %t.obj -# -# RUN: lld -flavor link /out:%t1.exe /opt:noref /subsystem:console /force \ -# RUN: -- %t.obj -# RUN: llvm-readobj -file-headers %t1.exe | FileCheck -check-prefix=DEFAULT %s -# -# RUN: lld -flavor link /out:%t2.exe /opt:noref /base:8388608 \ -# RUN: /subsystem:console /force -- %t.obj -# RUN: llvm-readobj -file-headers %t2.exe | FileCheck -check-prefix=BASE %s - -DEFAULT: ImageBase: 0x400000 - -BASE: ImageBase: 0x800000 - -# RUN: not lld -flavor link /base:3 /subsystem:console -- %t.obj >& %t.log -# RUN: FileCheck -check-prefix=ERROR %s < %t.log - -ERROR: Base address have to be multiple of 64K, but got 3 Index: test/pecoff/bss-section.test =================================================================== --- test/pecoff/bss-section.test +++ /dev/null @@ -1,21 +0,0 @@ -# RUN: lld -flavor link /out:%t.exe /subsystem:console /force \ -# RUN: -- %p/Inputs/bss.obj -# RUN: llvm-readobj -sections %t.exe | FileCheck %s - -CHECK: Section { -CHECK: Number: 1 -CHECK-NEXT: Name: .bss -CHECK-NEXT: VirtualSize: 0x320 -CHECK-NEXT: VirtualAddress: 0x1000 -CHECK-NEXT: RawDataSize: 0 -CHECK-NEXT: PointerToRawData: 0x0 -CHECK-NEXT: PointerToRelocations: 0x0 -CHECK-NEXT: PointerToLineNumbers: 0x0 -CHECK-NEXT: RelocationCount: 0 -CHECK-NEXT: LineNumberCount: 0 -CHECK-NEXT: Characteristics [ -CHECK-NEXT: IMAGE_SCN_CNT_UNINITIALIZED_DATA -CHECK-NEXT: IMAGE_SCN_MEM_READ -CHECK-NEXT: IMAGE_SCN_MEM_WRITE -CHECK-NEXT: ] -CHECK-NEXT: } Index: test/pecoff/comdat.test =================================================================== --- test/pecoff/comdat.test +++ /dev/null @@ -1,12 +0,0 @@ -# RUN: yaml2obj %p/Inputs/comdat.obj.yaml > %t1.obj -# RUN: yaml2obj %p/Inputs/comdat.obj.yaml > %t2.obj -# -# RUN: lld -flavor link /out:%t.exe /subsystem:console /opt:noref /force \ -# RUN: -- %t1.obj %t2.obj 2>&1 > %t.log -# -# FileCheck complains if the input files is empty, so add a dummy line. -# RUN: echo foo >> %t.log -# -# RUN: FileCheck %s < %t.log - -CHECK-NOT: duplicate symbol error Index: test/pecoff/common-symbol.test =================================================================== --- test/pecoff/common-symbol.test +++ /dev/null @@ -1,14 +0,0 @@ -# REQUIRES: x86 - -# RUN: yaml2obj %p/Inputs/common-symbol.obj.yaml > %t.obj -# -# RUN: lld -flavor link /machine:x64 /out:%t.exe /subsystem:console /force \ -# RUN: /opt:noref -- %t.obj %t.obj -# RUN: llvm-objdump -d %t.exe | FileCheck %s - -# Operands of B8 (MOV EAX) are common symbols -CHECK: 3000: b8 00 10 00 40 -CHECK: 3005: b8 04 10 00 40 -CHECK: 300a: b8 20 10 00 40 -CHECK: 300f: b8 60 10 00 40 -CHECK: 3014: b8 80 10 00 40 Index: test/pecoff/conflicting-machine.test =================================================================== --- test/pecoff/conflicting-machine.test +++ /dev/null @@ -1,6 +0,0 @@ -# RUN: yaml2obj %p/Inputs/vars-main-x64.obj.yaml > %t-x64.obj - -# RUN: not lld -flavor link /machine:x86 /out:%t.exe /entry:main %t-x64.obj 2>&1 \ -# RUN: | FileCheck %s - -CHECK: module machine type 'X64' conflicts with target machine type 'X86' Index: test/pecoff/delayimport.test =================================================================== --- test/pecoff/delayimport.test +++ /dev/null @@ -1,54 +0,0 @@ -# RUN: yaml2obj %p/Inputs/vars-main-x86.obj.yaml > %t-x86.obj -# RUN: yaml2obj %p/Inputs/vars-main-x64.obj.yaml > %t-x64.obj -# -# RUN: lld -flavor link /out:%t1.exe /subsystem:console /entry:main \ -# RUN: /delayload:vars.dll -- %t-x86.obj %p/Inputs/vars.lib -# RUN: llvm-readobj -coff-imports %t1.exe | FileCheck -check-prefix=X86 %s -# -# RUN: lld -flavor link /out:%t2.exe /subsystem:console /entry:main \ -# RUN: /machine:x64 /delayload:vars64.dll -- %t-x64.obj %p/Inputs/vars64.lib -# RUN: llvm-readobj -coff-imports %t2.exe | FileCheck -check-prefix=X64 %s - -X86: DelayImport { -X86-NEXT: Name: vars.dll -X86-NEXT: Attributes: 0x1 -X86-NEXT: ModuleHandle: 0x1000 -X86-NEXT: ImportAddressTable: 0x1004 -X86-NEXT: ImportNameTable: 0x2000 -X86-NEXT: BoundDelayImportTable: 0x0 -X86-NEXT: UnloadDelayImportTable: 0x0 -X86-NEXT: Import { -X86-NEXT: Symbol: _name_with_underscore (0) -X86-NEXT: Address: 0x40501F -X86-NEXT: } -X86-NEXT: Import { -X86-NEXT: Symbol: fn (1) -X86-NEXT: Address: 0x405034 -X86-NEXT: } -X86-NEXT: Import { -X86-NEXT: Symbol: (1) -X86-NEXT: Address: 0x405049 -X86-NEXT: } -X86-NEXT: } - -X64: DelayImport { -X64-NEXT: Name: vars64.dll -X64-NEXT: Attributes: 0x1 -X64-NEXT: ModuleHandle: 0x1000 -X64-NEXT: ImportAddressTable: 0x1008 -X64-NEXT: ImportNameTable: 0x2000 -X64-NEXT: BoundDelayImportTable: 0x0 -X64-NEXT: UnloadDelayImportTable: 0x0 -X64-NEXT: Import { -X64-NEXT: Symbol: _name_with_underscore (0) -X64-NEXT: Address: 0x14000501F -X64-NEXT: } -X64-NEXT: Import { -X64-NEXT: Symbol: fn (1) -X64-NEXT: Address: 0x140005076 -X64-NEXT: } -X64-NEXT: Import { -X64-NEXT: Symbol: (1) -X64-NEXT: Address: 0x1400050CD -X64-NEXT: } -X64-NEXT: } Index: test/pecoff/dll.test =================================================================== --- test/pecoff/dll.test +++ /dev/null @@ -1,7 +0,0 @@ -# RUN: yaml2obj %p/Inputs/nop.obj.yaml > %t.obj -# -# RUN: lld -flavor link /out:%t.exe /subsystem:console \ -# RUN: /entry:start /dll -- %t.obj -# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s - -CHECK: IMAGE_FILE_DLL (0x2000) Index: test/pecoff/dosstub.test =================================================================== --- test/pecoff/dosstub.test +++ /dev/null @@ -1,11 +0,0 @@ -# RUN: yaml2obj %p/Inputs/nop.obj.yaml > %t.obj - -# RUN: echo "MZ Hello world" > %t.stub -# RUN: lld -flavor link /out:%t.exe /entry:start /subsystem:console \ -# RUN: /stub:%t.stub -- %t.obj -# RUN: FileCheck -check-prefix=FILE %s < %t.exe -# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=READOBJ %s - -FILE: MZ Hello world - -READOBJ: Format: COFF-i386 Index: test/pecoff/drectve.test =================================================================== --- test/pecoff/drectve.test +++ /dev/null @@ -1,39 +0,0 @@ -# Test if the linker can properly parse the .drectve section contents. -# "drectve.obj" contains "/defaultlib:vars /subsystem:console,42.195 -?foo" -# in its .drectve section. - -# RUN: yaml2obj %p/Inputs/drectve.obj.yaml > %t.obj -# -# RUN: lld -flavor link /out:%t.exe /entry:main /opt:noref /libpath:%p/Inputs \ -# RUN: -- %t.obj >& %t.log -# -# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=HEADER %s -# RUN: llvm-objdump -p %t.exe | FileCheck -check-prefix=IMPORT %s -# RUN: echo >> %t.log -# RUN: FileCheck -check-prefix=ERROR %s < %t.log - -HEADER: MajorOperatingSystemVersion: 42 -HEADER: MinorOperatingSystemVersion: 195 - -IMPORT: DLL Name: vars.dll -IMPORT-NEXT: Hint/Ord Name -IMPORT-NEXT: 0 _name_with_underscore -IMPORT-NEXT: 1 fn -IMPORT-NEXT: 1 - -ERROR-NOT: foo - - -# drectve2.obj contains "/include:foo". -# RUN: yaml2obj %p/Inputs/drectve2.obj.yaml > %t2.obj -# RUN: not lld -flavor link /out:%t2.exe /entry:main -- %t2.obj >& %t2.log -# RUN: FileCheck -check-prefix=UNDEF2 %s < %t2.log - -UNDEF2: Undefined symbol: {{.*}}: foo - -# drectve4.lib contains "/include:bar". -# RUN: not lld -flavor link /force /out:%t3.exe /entry:main /include:_fn1 -- \ -# RUN: %t2.obj %p/Inputs/drectve3.lib >& %t3.log -# RUN: FileCheck -check-prefix=UNDEF3 %s < %t3.log - -UNDEF3: Undefined symbol: {{.*}}: bar Index: test/pecoff/dynamic.test =================================================================== --- test/pecoff/dynamic.test +++ /dev/null @@ -1,11 +0,0 @@ -# RUN: yaml2obj %p/Inputs/vars-main-x86.obj.yaml > %t.obj -# -# RUN: lld -flavor link /out:%t.exe /subsystem:console /entry:main /opt:noref \ -# RUN: -- %t.obj %p/Inputs/vars.lib -# RUN: llvm-objdump -p %t.exe | FileCheck %s - -CHECK: DLL Name: vars.dll -CHECK-NEXT: Hint/Ord Name -CHECK-NEXT: 0 _name_with_underscore -CHECK-NEXT: 1 fn -CHECK-NEXT: 1 Index: test/pecoff/dynamicbase.test =================================================================== --- test/pecoff/dynamicbase.test +++ /dev/null @@ -1,24 +0,0 @@ -# RUN: yaml2obj %p/Inputs/hello.obj.yaml > %t.obj -# -# RUN: lld -flavor link /out:%t1.exe /subsystem:console /force -- %t.obj -# RUN: llvm-readobj -file-headers %t1.exe | FileCheck %s \ -# RUN: --check-prefix=DYNAMICBASE -# -# RUN: lld -flavor link /out:%t2.exe /subsystem:console /force /dynamicbase:no \ -# RUN: -- %t.obj -# RUN: llvm-readobj -file-headers %t2.exe | FileCheck %s \ -# RUN: --check-prefix=NODYNAMICBASE -# -# RUN: lld -flavor link /out:%t3.exe /subsystem:console /force /fixed -- %t.obj -# RUN: llvm-readobj -file-headers %t3.exe | FileCheck %s \ -# RUN: --check-prefix=NODYNAMICBASE -# -# RUN: not lld -flavor link /out:%t4.exe /subsystem:console /force /fixed \ -# RUN: /dynamicbase -- %t.obj 2> %t.err -# RUN: FileCheck %s --check-prefix=DYNAMIC-AND-FIXED < %t.err - -DYNAMICBASE: IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE - -NODYNAMICBASE-NOT: IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE - -DYNAMIC-AND-FIXED: /dynamicbase must not be specified with /fixed Index: test/pecoff/entry.test =================================================================== --- test/pecoff/entry.test +++ /dev/null @@ -1,41 +0,0 @@ -# REQUIRES: asserts - -# RUN: yaml2obj %p/Inputs/entry.obj.yaml > %t.obj - -# RUN: not lld -flavor link /out:%t.exe /alternatename:_main=_foo \ -# RUN: -- %t.obj 2> %t.log -# RUN: FileCheck -check-prefix=MAIN %s < %t.log - -MAIN: _mainCRTStartup - -# RUN: not lld -flavor link /out:%t.exe /alternatename:_wmain=_foo \ -# RUN: -- %t.obj 2> %t.log -# RUN: FileCheck -check-prefix=WMAIN %s < %t.log - -WMAIN: _wmainCRTStartup - -# RUN: not lld -flavor link /out:%t.exe /alternatename:_WinMain=_foo \ -# RUN: -- %t.obj 2> %t.log -# RUN: FileCheck -check-prefix=WINMAIN %s < %t.log -# RUN: not lld -flavor link /out:%t.exe /alternatename:_WinMain@16=_foo \ -# RUN: -- %t.obj 2> %t.log -# RUN: FileCheck -check-prefix=WINMAIN %s < %t.log - -WINMAIN: _WinMainCRTStartup - -# RUN: not lld -flavor link /out:%t.exe /alternatename:_wWinMain=_foo \ -# RUN: -- %t.obj 2> %t.log -# RUN: FileCheck -check-prefix=WWINMAIN %s < %t.log - -WWINMAIN: _wWinMainCRTStartup - -# RUN: lld -flavor link /out:%t.exe /alternatename:_main=_foo \ -# RUN: /alternatename:_mainCRTStartup=_bar -- %t.obj -# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=MAINADDR %s - -MAINADDR: AddressOfEntryPoint: 0x1004 - -# RUN: lld -flavor link /out:%t.exe /subsystem:console /entry:baz -- %t.obj -# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=MANGLE %s - -MANGLE: AddressOfEntryPoint: 0x1004 Index: test/pecoff/export-warning.test =================================================================== --- test/pecoff/export-warning.test +++ /dev/null @@ -1,19 +0,0 @@ -# RUN: yaml2obj %p/Inputs/export.obj.yaml > %t.obj -# -# RUN: lld -flavor link /out:%t1.dll /dll /entry:init \ -# RUN: /export:exportfn1 /export:exportfn1 -- %t.obj 2> %t1.log -# RUN: echo >> %t1.log -# RUN: FileCheck -check-prefix=CHECK1 %s < %t1.log -CHECK1-NOT: Export symbol '_exportfn1' specified more than once. - -# RUN: lld -flavor link /out:%t2.dll /dll /entry:init \ -# RUN: /export:exportfn1 /export:exportfn1,@5 -- %t.obj 2> %t2.log -# RUN: echo >> %t2.log -# RUN: FileCheck -check-prefix=CHECK2 %s < %t2.log -CHECK2: Export symbol '_exportfn1' specified more than once. - -# RUN: lld -flavor link /out:%t3.dll /dll /entry:init \ -# RUN: /export:exportfn1,@8 /export:exportfn1,@5 -- %t.obj 2> %t3.log -# RUN: echo >> %t3.log -# RUN: FileCheck -check-prefix=CHECK3 %s < %t3.log -CHECK3: Export symbol '_exportfn1' specified more than once. Index: test/pecoff/export.test =================================================================== --- test/pecoff/export.test +++ /dev/null @@ -1,90 +0,0 @@ -# RUN: yaml2obj %p/Inputs/export.obj.yaml > %t.obj -# -# RUN: lld -flavor link /out:%t1.dll /dll /entry:init \ -# RUN: /export:exportfn1 /export:exportfn2 -- %t.obj -# RUN: llvm-objdump -p %t1.dll | FileCheck -check-prefix=CHECK1 %s - -CHECK1: Export Table: -CHECK1: DLL name: export.test.tmp1.dll -CHECK1: Ordinal RVA Name -CHECK1-NEXT: 1 0x2008 exportfn1 -CHECK1-NEXT: 2 0x2010 exportfn2 - -# RUN: lld -flavor link /out:%t2.dll /dll /subsystem:console /entry:init \ -# RUN: /export:exportfn1,@5 /export:exportfn2 -- %t.obj -# RUN: llvm-objdump -p %t2.dll | FileCheck -check-prefix=CHECK2 %s - -CHECK2: Export Table: -CHECK2: DLL name: export.test.tmp2.dll -CHECK2: Ordinal RVA Name -CHECK2-NEXT: 5 0x2008 exportfn1 -CHECK2-NEXT: 6 0x2010 exportfn2 - -# RUN: lld -flavor link /out:%t3.dll /dll /subsystem:console /entry:init \ -# RUN: /export:exportfn1,@5,noname /export:exportfn2 -- %t.obj -# RUN: llvm-objdump -p %t3.dll | FileCheck -check-prefix=CHECK3 %s - -CHECK3: Export Table: -CHECK3: DLL name: export.test.tmp3.dll -CHECK3: Ordinal RVA Name -CHECK3-NEXT: 5 0x2008 -CHECK3-NEXT: 6 0x2010 exportfn2 - -# RUN: lld -flavor link /out:%t4.dll /dll /entry:init \ -# RUN: /def:%p/Inputs/exports.def -- %t.obj -# RUN: llvm-objdump -p %t4.dll | FileCheck -check-prefix=CHECK4 %s - -CHECK4: Export Table: -CHECK4: DLL name: export.test.tmp4.dll -CHECK4: Ordinal RVA Name -CHECK4-NEXT: 5 0x2008 exportfn1 -CHECK4-NEXT: 6 0x2010 exportfn2 -CHECK4-NEXT: 7 0x2010 exportfn3@256 -CHECK4-NEXT: 8 0x2010 exportfn5 - -# RUN: lld -flavor link /out:%t5.dll /dll /entry:init \ -# RUN: /export:exportfn7 -- %t.obj -# RUN: llvm-objdump -p %t5.dll | FileCheck -check-prefix=CHECK5 %s - -CHECK5: Export Table: -CHECK5: DLL name: export.test.tmp5.dll -CHECK5: Ordinal RVA Name -CHECK5-NEXT: 1 0x2010 exportfn3@256 -CHECK5-NEXT: 2 0x2010 exportfn7 - -# RUN: lld -flavor link /out:%t6.dll /dll /entry:init \ -# RUN: /export:exportfn8 -- %t.obj -# RUN: llvm-objdump -p %t6.dll | FileCheck -check-prefix=CHECK6 %s - -CHECK6: Export Table: -CHECK6: DLL name: export.test.tmp6.dll -CHECK6: Ordinal RVA Name -CHECK6-NEXT: 1 0x2010 exportfn3@256 -CHECK6-NEXT: 2 0x2010 exportfn8 - -# RUN: lld -flavor link /out:%t7.dll /dll /entry:init \ -# RUN: /export:exportfn7 /export:exportfn7@8 \ -# RUN: /export:exportfn8 /export:exportfn8 /export:exportfn3 -- %t.obj -# RUN: llvm-objdump -p %t7.dll | FileCheck -check-prefix=DUP %s - -DUP: Export Table: -DUP: DLL name: export.test.tmp7.dll -DUP: Ordinal RVA Name -DUP-NEXT: 1 0x2010 exportfn3 -DUP-NEXT: 2 0x2010 exportfn7 -DUP-NEXT: 3 0x2010 exportfn8 -DUP-NOT: ?exportfn8@@YAXXZ -DUP-NOT: exportfn3@256 - -# RUN: yaml2obj %p/Inputs/export.obj.yaml > %t.obj -# -# RUN: lld -flavor link /out:%t8.dll /dll /entry:init \ -# RUN: /export:f1=exportfn1 /export:f2@4=exportfn2,private -- %t.obj -# RUN: llvm-objdump -p %t8.dll | FileCheck -check-prefix=EQUAL %s - -EQUAL: Export Table: -EQUAL: DLL name: export.test.tmp8.dll -EQUAL: Ordinal RVA Name -EQUAL-NEXT: 1 0x2010 exportfn3@256 -EQUAL-NEXT: 2 0x2008 f1 -EQUAL-NEXT: 3 0x2010 f2{{$}} Index: test/pecoff/exportlib.test =================================================================== --- test/pecoff/exportlib.test +++ /dev/null @@ -1,32 +0,0 @@ -# REQUIRES: winlib - -# RUN: yaml2obj %p/Inputs/export.obj.yaml > %t.obj -# -# RUN: lld -flavor link /out:%t.dll /dll /entry:init \ -# RUN: /export:exportfn1 /export:exportfn2 -- %t.obj -# RUN: llvm-readobj %t.lib | FileCheck %s - -CHECK: File: exportlib.test.tmp.dll -CHECK: Format: COFF-i386 -CHECK: Arch: i386 -CHECK: AddressSize: 32bit - -CHECK: File: exportlib.test.tmp.dll -CHECK: Format: COFF-i386 -CHECK: Arch: i386 -CHECK: AddressSize: 32bit - -CHECK: File: exportlib.test.tmp.dll -CHECK: Format: COFF-i386 -CHECK: Arch: i386 -CHECK: AddressSize: 32bit - -CHECK: File: exportlib.test.tmp.dll -CHECK: Format: COFF- -CHECK: Arch: unknown -CHECK: AddressSize: 32bit - -CHECK: File: exportlib.test.tmp.dll -CHECK: Format: COFF- -CHECK: Arch: unknown -CHECK: AddressSize: 32bit Index: test/pecoff/exportlib2.test =================================================================== --- test/pecoff/exportlib2.test +++ /dev/null @@ -1,21 +0,0 @@ -# RUN: yaml2obj %p/Inputs/export.obj.yaml > %t.obj -# -# RUN: lld -flavor link /out:%t.dll /dll /entry:init \ -# RUN: /export:exportfn1 /export:exportfn2 /lldmoduledeffile:%t1.def -- %t.obj -# RUN: FileCheck -check-prefix=CHECK1 %s < %t1.def - -CHECK1: LIBRARY "exportlib2.test.tmp.dll" -CHECK1: EXPORTS -CHECK1: exportfn1 @1 -CHECK1: exportfn2 @2 -CHECK1: exportfn3@256 @3 - -# RUN: lld -flavor link /out:%t.dll /dll /entry:init \ -# RUN: /def:%p/Inputs/exports2.def /lldmoduledeffile:%t2.def -- %t.obj -# RUN: FileCheck -check-prefix=CHECK2 %s < %t2.def - -CHECK2: LIBRARY "exportlib2.test.tmp.dll" -CHECK2: EXPORTS -CHECK2: exportfn1 @5 -CHECK2: exportfn3@256 @6 -CHECK2: exportfn7@8 @7 Index: test/pecoff/grouped-sections.test =================================================================== --- test/pecoff/grouped-sections.test +++ /dev/null @@ -1,17 +0,0 @@ -# RUN: yaml2obj %p/Inputs/grouped-sections.obj.yaml > %t.obj -# -# RUN: lld -flavor link /out:%t.exe /subsystem:console /entry:main -- %t.obj -# RUN: llvm-objdump -s %t.exe | FileCheck %s -# -# The file "grouped-sections.obj" has three data sections in the following -# order: -# -# .data$2 -# .data$1 -# .data -# -# If all the sections will be merged correctly, the resulting ".data" -# section will have the string "Hello, world". - -CHECK: Contents of section .data: -CHECK-NEXT: Hello, world Index: test/pecoff/hello.test =================================================================== --- test/pecoff/hello.test +++ /dev/null @@ -1,51 +0,0 @@ -# RUN: yaml2obj %p/Inputs/hello.obj.yaml > %t.obj - -# RUN: lld -flavor link /out:%t1.exe /subsystem:console /force -- %t.obj -# RUN: llvm-readobj -file-headers %t1.exe | FileCheck -check-prefix=FILE %s - -FILE: ImageOptionalHeader { -FILE: SizeOfInitializedData: 1024 -FILE: SizeOfHeaders: 512 -FILE: } - -# RUN: lld -flavor link /out:%t2.exe /subsystem:console /force -- %t.obj -# RUN: llvm-readobj -sections %t2.exe | FileCheck -check-prefix=SECTIONS %s - -SECTIONS: Format: COFF-i386 -SECTIONS-NEXT: Arch: i386 -SECTIONS-NEXT: AddressSize: 32bit -SECTIONS-NEXT: Sections [ -SECTIONS-NEXT: Section { -SECTIONS-NEXT: Number: 1 -SECTIONS-NEXT: Name: .data -SECTIONS-NEXT: VirtualSize: 0x12 -SECTIONS-NEXT: VirtualAddress: 0x1000 -SECTIONS-NEXT: RawDataSize: 512 -SECTIONS-NEXT: PointerToRawData: 0x200 -SECTIONS-NEXT: PointerToRelocations: 0x0 -SECTIONS-NEXT: PointerToLineNumbers: 0x0 -SECTIONS-NEXT: RelocationCount: 0 -SECTIONS-NEXT: LineNumberCount: 0 -SECTIONS-NEXT: Characteristics [ -SECTIONS-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA -SECTIONS-NEXT: IMAGE_SCN_MEM_READ -SECTIONS-NEXT: IMAGE_SCN_MEM_WRITE -SECTIONS-NEXT: ] -SECTIONS-NEXT: } -SECTIONS-NEXT: Section { -SECTIONS-NEXT: Number: 2 -SECTIONS-NEXT: Name: .text (2E 74 65 78 74 00 00 00) -SECTIONS-NEXT: VirtualSize: 0x1C -SECTIONS-NEXT: VirtualAddress: 0x2000 -SECTIONS-NEXT: RawDataSize: 512 -SECTIONS-NEXT: PointerToRawData: 0x400 -SECTIONS-NEXT: PointerToRelocations: 0x0 -SECTIONS-NEXT: PointerToLineNumbers: 0x0 -SECTIONS-NEXT: RelocationCount: 0 -SECTIONS-NEXT: LineNumberCount: 0 -SECTIONS-NEXT: Characteristics [ -SECTIONS-NEXT: IMAGE_SCN_CNT_CODE -SECTIONS-NEXT: IMAGE_SCN_MEM_EXECUTE -SECTIONS-NEXT: IMAGE_SCN_MEM_READ -SECTIONS-NEXT: ] -SECTIONS-NEXT: } Index: test/pecoff/hello64.test =================================================================== --- test/pecoff/hello64.test +++ /dev/null @@ -1,22 +0,0 @@ -# REQUIRES: x86 - -# RUN: yaml2obj %p/Inputs/hello64.obj.yaml > %t.obj - -# RUN: lld -flavor link /out:%t.exe /subsystem:windows /machine:x64 \ -# RUN: /entry:main -- %t.obj %p/Inputs/hello64lib.lib -# RUN: llvm-objdump -disassemble %t.exe | FileCheck %s - -CHECK: 6000: 48 83 ec 28 subq $40, %rsp -CHECK: 6004: 48 c7 c1 00 00 00 00 movq $0, %rcx -CHECK: 600b: 48 8d 15 f4 af ff ff leaq -20492(%rip), %rdx -CHECK: 6012: 4c 8d 05 e7 af ff ff leaq -20505(%rip), %r8 -CHECK: 6019: 41 b9 00 00 00 00 movl $0, %r9d -CHECK: 601f: e8 12 00 00 00 callq 18 -CHECK: 6024: b9 00 00 00 00 movl $0, %ecx -CHECK: 6029: e8 00 00 00 00 callq 0 -CHECK: 602e: ff 25 cc cf ff ff jmpq *-12340(%rip) -CHECK: 6034: cc int3 -CHECK: 6035: cc int3 -CHECK: 6036: ff 25 cc cf ff ff jmpq *-12340(%rip) -CHECK: 603c: cc int3 -CHECK: 603d: cc int3 Index: test/pecoff/help.test =================================================================== --- test/pecoff/help.test +++ /dev/null @@ -1,4 +0,0 @@ -# RUN: not lld -flavor link /help | FileCheck %s -# RUN: not lld -flavor link '/?' | FileCheck %s - -CHECK: USAGE Index: test/pecoff/imagebase.test =================================================================== --- test/pecoff/imagebase.test +++ /dev/null @@ -1,15 +0,0 @@ -# REQUIRES: x86 - -# RUN: yaml2obj %p/Inputs/imagebase.obj.yaml > %t.obj - -# RUN: lld -flavor link /out:%t1.exe /subsystem:console /entry:_start \ -# RUN: /opt:noref -- %t.obj -# RUN: llvm-objdump -disassemble %t1.exe | FileCheck -check-prefix=DEFAULT %s - -DEFAULT: a1 00 00 40 00 movl 4194304, %eax - -# RUN: lld -flavor link /out:%t2.exe /subsystem:console /entry:_start \ -# RUN: /base:65536 /opt:noref -- %t.obj -# RUN: llvm-objdump -disassemble %t2.exe | FileCheck -check-prefix=BASE %s - -BASE: a1 00 00 01 00 movl 65536, %eax Index: test/pecoff/importlib.test =================================================================== --- test/pecoff/importlib.test +++ /dev/null @@ -1,61 +0,0 @@ -# REQUIRES: x86 - -# Verify that lld can handle .lib files. "main.obj" refers "var" and -# "fn" defined in "vars.lib". -# -# RUN: yaml2obj %p/Inputs/vars-main-x86.obj.yaml > %t.obj -# -# RUN: lld -flavor link /out:%t1.exe /subsystem:console /entry:main /opt:noref \ -# RUN: -- %t.obj %p/Inputs/vars.lib -# RUN: llvm-objdump -d %t1.exe | FileCheck -check-prefix=TEXT %s -# RUN: llvm-readobj -coff-imports %t1.exe | FileCheck -check-prefix=IMPORT %s -# RUN: llvm-readobj -sections %t1.exe | FileCheck -check-prefix=SIZE %s -# -# RUN: lld -flavor link /out:%t2.exe /subsystem:console /entry:main /opt:noref \ -# RUN: /libpath:%p/Inputs -- %t.obj vars.lib -# RUN: llvm-objdump -d %t2.exe | FileCheck -check-prefix=TEXT %s -# RUN: llvm-readobj -coff-imports %t2.exe | FileCheck -check-prefix=IMPORT %s -# -# RUN: lld -flavor link /out:%t3.exe /subsystem:console /entry:main /opt:noref \ -# RUN: /libpath:%p/Inputs /defaultlib:vars.lib -- %t.obj -# RUN: llvm-objdump -d %t3.exe | FileCheck -check-prefix=TEXT %s -# RUN: llvm-readobj -coff-imports %t3.exe | FileCheck -check-prefix=IMPORT %s -# -# RUN: env LIB=%p/Inputs lld -flavor link /out:%t4.exe /subsystem:console \ -# RUN: /opt:noref /entry:main -- %t.obj vars.lib -# RUN: llvm-objdump -d %t4.exe | FileCheck -check-prefix=TEXT %s -# RUN: llvm-readobj -coff-imports %t4.exe | FileCheck -check-prefix=IMPORT %s -# -# RUN: env LINK="/out:%t5.exe /subsystem:console /entry:main /opt:noref \ -# RUN: -- %t.obj" lld -flavor link %p/Inputs/vars.lib -# RUN: llvm-objdump -d %t5.exe | FileCheck -check-prefix=TEXT %s -# RUN: llvm-readobj -coff-imports %t5.exe | FileCheck -check-prefix=IMPORT %s - -TEXT: Disassembly of section .text: -TEXT-NEXT: .text: -TEXT-NEXT: pushl %ebp -TEXT-NEXT: movl %esp, %ebp -TEXT-NEXT: pushl %esi -TEXT-NEXT: calll *{{[0-9]+}} -TEXT-NEXT: movl {{[0-9]+}}, %ecx -TEXT-NEXT: movl (%ecx), %esi -TEXT-NEXT: addl %eax, %esi -TEXT-NEXT: calll *{{[0-9]+}} -TEXT-NEXT: addl %esi, %eax -TEXT-NEXT: popl %esi -TEXT-NEXT: popl %ebp -TEXT-NEXT: ret - -IMPORT: Import { -IMPORT-NEXT: Name: vars.dll -IMPORT-NEXT: ImportLookupTableRVA: 0x4000 -IMPORT-NEXT: ImportAddressTableRVA: 0x2000 -IMPORT-NEXT: Symbol: _name_with_underscore (0) -IMPORT-NEXT: Symbol: fn (1) -IMPORT-NEXT: Symbol: (1) -IMPORT-NEXT: } - -SIZE: Section { -SIZE-NEXT: Number: 1 -SIZE-NEXT: Name: .idata (2E 69 64 61 74 61 00 00) -SIZE-NEXT: VirtualSize: 0x27 Index: test/pecoff/include.test =================================================================== --- test/pecoff/include.test +++ /dev/null @@ -1,8 +0,0 @@ -# RUN: yaml2obj %p/Inputs/nop.obj.yaml > %t.obj -# -# RUN: not lld -flavor link /out:%t.exe /include:sym1 /include:sym2 \ -# RUN: /subsystem:console -- %t.obj 2> %t.log -# RUN: FileCheck %s < %t.log - -CHECK: Undefined symbol: : sym1 -CHECK: Undefined symbol: : sym2 Index: test/pecoff/lib.test =================================================================== --- test/pecoff/lib.test +++ /dev/null @@ -1,15 +0,0 @@ -# REQUIRES: x86 - -# Verify that lld can handle a library file. -# -# RUN: yaml2obj %p/Inputs/main.obj.yaml > %t.obj -# -# RUN: lld -flavor link /out:%t.exe /subsystem:console /entry:main /opt:noref \ -# RUN: -- %t.obj %p/Inputs/static.lib -# RUN: llvm-objdump -d %t.exe | FileCheck %s - -CHECK: Disassembly of section .text: -CHECK-NEXT: .text: -CHECK-NEXT: movl 4198400, %eax -CHECK-NEXT: addl 4198404, %eax -CHECK-NEXT: ret Index: test/pecoff/libarg.test =================================================================== --- test/pecoff/libarg.test +++ /dev/null @@ -1,9 +0,0 @@ -# REQUIRES: winlib -# -# If argv[1] == "/lib", link.exe morphs into lib.exe. -# -# RUN: lld -flavor link /lib >& %t.log -# RUN: FileCheck %s < %t.log - -CHECK-NOT: unrecognized option '/lib' -CHECK: usage: LIB Index: test/pecoff/localyimported.test =================================================================== --- test/pecoff/localyimported.test +++ /dev/null @@ -1,15 +0,0 @@ -# RUN: yaml2obj %p/Inputs/hello.obj.yaml > %t.obj -# -# RUN: not lld -flavor link /out:%t.exe /include:__imp__nosuchsym %t.obj \ -# RUN: >& %t.log -# RUN: FileCheck -check-prefix=X86 %s < %t.log - -X86: Undefined symbol: __imp__nosuchsym: _nosuchsym - -# RUN: yaml2obj %p/Inputs/hello64.obj.yaml > %t2.obj -# -# RUN: not lld -flavor link /out:%t2.exe /include:__imp__nosuchsym %t2.obj \ -# RUN: /machine:x64 >& %t2.log -# RUN: FileCheck -check-prefix=X64 %s < %t2.log - -X64: Undefined symbol: __imp__nosuchsym: _nosuchsym Index: test/pecoff/long-section-name.test =================================================================== --- test/pecoff/long-section-name.test +++ /dev/null @@ -1,7 +0,0 @@ -# RUN: yaml2obj %p/Inputs/nop.obj.yaml > %t.obj -# -# RUN: lld -flavor link /out:%t.exe /subsystem:console /entry:start \ -# RUN: /merge:.text=.longsectionname -- %t.obj -# RUN: llvm-readobj -sections %t.exe | FileCheck %s - -CHECK: Name: .longsectionname (2F 34 00 00 00 00 00 00) Index: test/pecoff/machinetype.test =================================================================== --- test/pecoff/machinetype.test +++ /dev/null @@ -1,13 +0,0 @@ -# RUN: yaml2obj %p/Inputs/machine-type-unknown.obj.yaml > %t1.obj -# RUN: yaml2obj %p/Inputs/hello.obj.yaml > %t2.obj -# RUN: yaml2obj %p/Inputs/hello64.obj.yaml > %t3.obj - -# RUN: lld -flavor link /out:%t.exe /subsystem:console /force -- %t1.obj %t2.obj -# RUN: llvm-readobj %t.exe | FileCheck -check-prefix=X86 %s - -X86: Arch: i386 - -# RUN: lld -flavor link /out:%t.exe /subsystem:console /force -- %t1.obj %t3.obj -# RUN: llvm-readobj %t.exe | FileCheck -check-prefix=X64 %s - -X64: Arch: x86_64 Index: test/pecoff/manifest.test =================================================================== --- test/pecoff/manifest.test +++ /dev/null @@ -1,63 +0,0 @@ -# RUN: yaml2obj %p/Inputs/nop.obj.yaml > %t.obj - -# RUN: lld -flavor link /out:%t1.exe /subsystem:console /force \ -# RUN: -- %t.obj -# RUN: FileCheck -check-prefix=MANIFEST %s < %t1.exe.manifest - -MANIFEST: -MANIFEST: -MANIFEST: -MANIFEST: -MANIFEST: -MANIFEST: -MANIFEST: -MANIFEST: -MANIFEST: -MANIFEST: - -# RUN: lld -flavor link /out:%t2.exe /subsystem:console /force \ -# RUN: /manifestuac:"level='requireAdministrator' uiAccess='true'" -- %t.obj -# RUN: FileCheck -check-prefix=UAC %s < %t2.exe.manifest - -UAC: -UAC: -UAC: -UAC: -UAC: -UAC: -UAC: -UAC: -UAC: -UAC: - -# RUN: lld -flavor link /out:%t3.exe /subsystem:console /force \ -# RUN: /manifestdependency:"foo='bar'" -- %t.obj -# RUN: FileCheck -check-prefix=DEPENDENCY %s < %t3.exe.manifest - -DEPENDENCY: -DEPENDENCY: -DEPENDENCY: -DEPENDENCY: -DEPENDENCY: -DEPENDENCY: -DEPENDENCY: -DEPENDENCY: -DEPENDENCY: -DEPENDENCY: -DEPENDENCY: -DEPENDENCY: -DEPENDENCY: -DEPENDENCY: -DEPENDENCY: - -# RUN: lld -flavor link /out:%t4.exe /subsystem:console /force \ -# RUN: /manifestuac:no -- %t.obj -# RUN: FileCheck -check-prefix=NOUAC %s < %t4.exe.manifest - -NOUAC: -NOUAC: -NOUAC: Index: test/pecoff/merge-largest.test =================================================================== --- test/pecoff/merge-largest.test +++ /dev/null @@ -1,24 +0,0 @@ -# RUN: yaml2obj %p/Inputs/merge-largest1.obj.yaml > %t1.obj -# RUN: yaml2obj %p/Inputs/merge-largest2.obj.yaml > %t2.obj -# -# RUN: lld -flavor link /out:%t.exe /subsystem:console /opt:noref /force \ -# RUN: -- %t1.obj %t2.obj 2>&1 > %t.log -# -# FileCheck complains if the input files is empty, so add a dummy line. -# RUN: echo foo >> %t.log -# RUN: FileCheck -check-prefix=STDERR %s < %t.log -# -# RUN: llvm-readobj -sections %t.exe | FileCheck -check-prefix=READOBJ %s - -STDERR-NOT: duplicate symbol error - -READOBJ: Format: COFF-i386 -READOBJ-NEXT: Arch: i386 -READOBJ-NEXT: AddressSize: 32bit -READOBJ-NEXT: Sections [ -READOBJ-NEXT: Section { -READOBJ-NEXT: Number: 1 -READOBJ-NEXT: Name: .text (2E 74 65 78 74 00 00 00) -READOBJ-NEXT: VirtualSize: 0x8 -READOBJ-NEXT: VirtualAddress: 0x1000 -READOBJ-NEXT: RawDataSize: 512 Index: test/pecoff/merge-same-size.test =================================================================== --- test/pecoff/merge-same-size.test +++ /dev/null @@ -1,32 +0,0 @@ -# RUN: yaml2obj %p/Inputs/merge-same-size1.obj.yaml > %t1.obj -# RUN: yaml2obj %p/Inputs/merge-same-size2.obj.yaml > %t2.obj -# RUN: yaml2obj %p/Inputs/merge-same-size3.obj.yaml > %t3.obj -# -# RUN: lld -flavor link /out:%t.exe /subsystem:console /opt:noref /force \ -# RUN: -- %t1.obj %t2.obj > %t1.log 2>&1 -# -# FileCheck complains if the input files is empty, so add a dummy line. -# RUN: echo foo >> %t1.log -# RUN: FileCheck -check-prefix=SAMESIZE %s < %t1.log -# -# RUN: not lld -flavor link /out:%t.exe /subsystem:console /opt:noref /force \ -# RUN: -- %t1.obj %t3.obj > %t2.log 2>&1 -# RUN: FileCheck -check-prefix=DIFFERENT %s < %t2.log -# -# RUN: llvm-readobj -sections %t.exe | FileCheck -check-prefix=READOBJ %s - -SAMESIZE-NOT: duplicate symbol error - -DIFFERENT: Size mismatch -DIFFERENT: duplicate symbol error - -READOBJ: Format: COFF-i386 -READOBJ-NEXT: Arch: i386 -READOBJ-NEXT: AddressSize: 32bit -READOBJ-NEXT: Sections [ -READOBJ-NEXT: Section { -READOBJ-NEXT: Number: 1 -READOBJ-NEXT: Name: .text (2E 74 65 78 74 00 00 00) -READOBJ-NEXT: VirtualSize: 0x7 -READOBJ-NEXT: VirtualAddress: 0x1000 -READOBJ-NEXT: RawDataSize: 512 Index: test/pecoff/multi.test =================================================================== --- test/pecoff/multi.test +++ /dev/null @@ -1,17 +0,0 @@ -# REQUIRES: x86 - -# Verify that lld can handle multiple input files. -# -# RUN: yaml2obj %p/Inputs/main.obj.yaml > %t1.obj -# RUN: yaml2obj %p/Inputs/static-data1.obj.yaml > %t2.obj -# RUN: yaml2obj %p/Inputs/static-data2.obj.yaml > %t3.obj -# -# RUN: lld -flavor link /out:%t.exe /subsystem:console /entry:main /opt:noref \ -# RUN: -- %t1.obj %t2.obj %t3.obj -# RUN: llvm-objdump -d %t.exe | FileCheck %s - -CHECK: Disassembly of section .text: -CHECK: .text: -CHECK: movl {{[0-9]+}}, %eax -CHECK: addl {{[0-9]+}}, %eax -CHECK: ret Index: test/pecoff/noentry.test =================================================================== --- test/pecoff/noentry.test +++ /dev/null @@ -1,10 +0,0 @@ -# RUN: yaml2obj %p/Inputs/nop.obj.yaml > %t.obj -# RUN: lld -flavor link /out:%t.exe /noentry /dll -- %t.obj -# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s - -CHECK: AddressOfEntryPoint: 0x0 - -# RUN: not lld -flavor link /out:%t.exe /noentry -- %t.obj >& %t.log -# RUN: FileCheck --check-prefix=ERROR %s < %t.log - -ERROR: /noentry must be specified with /dll Index: test/pecoff/nonstandard-sections.test =================================================================== --- test/pecoff/nonstandard-sections.test +++ /dev/null @@ -1,75 +0,0 @@ -# RUN: yaml2obj %p/Inputs/nonstandard-sections.obj.yaml > %t.obj -# RUN: lld -flavor link /out:%t.exe /subsystem:console /force -- %t.obj -# RUN: llvm-readobj -sections %t.exe | FileCheck %s - -CHECK: Arch: i386 -CHECK-NEXT: AddressSize: 32bit -CHECK-NEXT: Sections [ -CHECK-NEXT: Section { -CHECK-NEXT: Number: 1 -CHECK-NEXT: Name: .bar (2E 62 61 72 00 00 00 00) -CHECK-NEXT: VirtualSize: 0x4 -CHECK-NEXT: VirtualAddress: 0x1000 -CHECK-NEXT: RawDataSize: 512 -CHECK-NEXT: PointerToRawData: 0x400 -CHECK-NEXT: PointerToRelocations: 0x0 -CHECK-NEXT: PointerToLineNumbers: 0x0 -CHECK-NEXT: RelocationCount: 0 -CHECK-NEXT: LineNumberCount: 0 -CHECK-NEXT: Characteristics [ (0x40000040) -CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) -CHECK-NEXT: IMAGE_SCN_MEM_READ (0x40000000) -CHECK-NEXT: ] -CHECK-NEXT: } -CHECK-NEXT: Section { -CHECK-NEXT: Number: 2 -CHECK-NEXT: Name: .data (2E 64 61 74 61 00 00 00) -CHECK-NEXT: VirtualSize: 0x4 -CHECK-NEXT: VirtualAddress: 0x2000 -CHECK-NEXT: RawDataSize: 512 -CHECK-NEXT: PointerToRawData: 0x600 -CHECK-NEXT: PointerToRelocations: 0x0 -CHECK-NEXT: PointerToLineNumbers: 0x0 -CHECK-NEXT: RelocationCount: 0 -CHECK-NEXT: LineNumberCount: 0 -CHECK-NEXT: Characteristics [ (0xC0000040) -CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) -CHECK-NEXT: IMAGE_SCN_MEM_READ (0x40000000) -CHECK-NEXT: IMAGE_SCN_MEM_WRITE (0x80000000) -CHECK-NEXT: ] -CHECK-NEXT: } -CHECK-NEXT: Section { -CHECK-NEXT: Number: 3 -CHECK-NEXT: Name: .foo (2E 66 6F 6F 00 00 00 00) -CHECK-NEXT: VirtualSize: 0x4 -CHECK-NEXT: VirtualAddress: 0x3000 -CHECK-NEXT: RawDataSize: 512 -CHECK-NEXT: PointerToRawData: 0x800 -CHECK-NEXT: PointerToRelocations: 0x0 -CHECK-NEXT: PointerToLineNumbers: 0x0 -CHECK-NEXT: RelocationCount: 0 -CHECK-NEXT: LineNumberCount: 0 -CHECK-NEXT: Characteristics [ (0xC0000040) -CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) -CHECK-NEXT: IMAGE_SCN_MEM_READ (0x40000000) -CHECK-NEXT: IMAGE_SCN_MEM_WRITE (0x80000000) -CHECK-NEXT: ] -CHECK-NEXT: } -CHECK-NEXT: Section { -CHECK-NEXT: Number: 4 -CHECK-NEXT: Name: .text (2E 74 65 78 74 00 00 00) -CHECK-NEXT: VirtualSize: 0x4 -CHECK-NEXT: VirtualAddress: 0x4000 -CHECK-NEXT: RawDataSize: 512 -CHECK-NEXT: PointerToRawData: 0xA00 -CHECK-NEXT: PointerToRelocations: 0x0 -CHECK-NEXT: PointerToLineNumbers: 0x0 -CHECK-NEXT: RelocationCount: 0 -CHECK-NEXT: LineNumberCount: 0 -CHECK-NEXT: Characteristics [ (0x60000020) -CHECK-NEXT: IMAGE_SCN_CNT_CODE (0x20) -CHECK-NEXT: IMAGE_SCN_MEM_EXECUTE (0x20000000) -CHECK-NEXT: IMAGE_SCN_MEM_READ (0x40000000) -CHECK-NEXT: ] -CHECK-NEXT: } -CHECK-NEXT: ] Index: test/pecoff/options.test =================================================================== --- test/pecoff/options.test +++ /dev/null @@ -1,40 +0,0 @@ -# Tests for miscellaneous command line options. - -# RUN: yaml2obj %p/Inputs/nop.obj.yaml > %t-x86.obj -# RUN: yaml2obj %p/Inputs/nop64.obj.yaml > %t-x64.obj - -# RUN: lld -flavor link /align:8192 /out:%t.exe /entry:start \ -# RUN: /subsystem:console -- %t-x86.obj -# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=ALIGN %s -ALIGN: SectionAlignment: 8192 - -# RUN: lld -flavor link /allowbind:no /out:%t.exe /entry:start \ -# RUN: /subsystem:console -- %t-x86.obj -# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOBIND %s -NOBIND: IMAGE_DLL_CHARACTERISTICS_NO_BIND - -# RUN: lld -flavor link /allowisolation:no /out:%t.exe /entry:start \ -# RUN: /subsystem:console -- %t-x86.obj -# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOISO %s -NOISO: IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION - -# RUN: lld -flavor link /swaprun:cd /out:%t.exe /entry:start \ -# RUN: /subsystem:console -- %t-x86.obj -# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=RUNCD %s -RUNCD: IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP - -# RUN: lld -flavor link /swaprun:net /out:%t.exe /entry:start \ -# RUN: /subsystem:console -- %t-x86.obj -# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=RUNNET %s -RUNNET: IMAGE_FILE_NET_RUN_FROM_SWAP - -# RUN: lld -flavor link /machine:x64 /force /highentropyva /out:%t.exe \ -# RUN: /entry:start /subsystem:console -- %t-x64.obj -# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=ENT %s -ENT: IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA - -# RUN: lld -flavor link /machine:x64 /force /highentropyva:no /out:%t.exe \ -# RUN: /entry:start /subsystem:console -- %t-x64.obj -# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOENT %s -NOENT-NOT: IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA - Index: test/pecoff/pe32plus.test =================================================================== --- test/pecoff/pe32plus.test +++ /dev/null @@ -1,87 +0,0 @@ -# RUN: yaml2obj %p/Inputs/nop64.obj.yaml > %t.obj - -# RUN: lld -flavor link /out:%t.exe /subsystem:console /entry:start \ -# RUN: /machine:x64 -- %t.obj %p/Inputs/vars.lib -# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s - -CHECK: Format: COFF-x86-64 -CHECK-NEXT: Arch: x86_64 -CHECK-NEXT: AddressSize: 64bit -CHECK-NEXT: ImageFileHeader { -CHECK-NEXT: Machine: IMAGE_FILE_MACHINE_AMD64 (0x8664) -CHECK-NEXT: SectionCount: 5 -CHECK-NEXT: TimeDateStamp: -CHECK-NEXT: PointerToSymbolTable: 0x0 -CHECK-NEXT: SymbolCount: 0 -CHECK-NEXT: OptionalHeaderSize: 240 -CHECK-NEXT: Characteristics [ (0x22) -CHECK-NEXT: IMAGE_FILE_EXECUTABLE_IMAGE (0x2) -CHECK-NEXT: IMAGE_FILE_LARGE_ADDRESS_AWARE (0x20) -CHECK-NEXT: ] -CHECK-NEXT: } -CHECK-NEXT: ImageOptionalHeader { -CHECK-NEXT: MajorLinkerVersion: 0 -CHECK-NEXT: MinorLinkerVersion: 0 -CHECK-NEXT: SizeOfCode: 512 -CHECK-NEXT: SizeOfInitializedData: 2048 -CHECK-NEXT: SizeOfUninitializedData: 0 -CHECK-NEXT: AddressOfEntryPoint: 0x5000 -CHECK-NEXT: BaseOfCode: 0x5000 -CHECK-NEXT: ImageBase: 0x140000000 -CHECK-NEXT: SectionAlignment: 4096 -CHECK-NEXT: FileAlignment: 512 -CHECK-NEXT: MajorOperatingSystemVersion: 6 -CHECK-NEXT: MinorOperatingSystemVersion: 0 -CHECK-NEXT: MajorImageVersion: 0 -CHECK-NEXT: MinorImageVersion: 0 -CHECK-NEXT: MajorSubsystemVersion: 6 -CHECK-NEXT: MinorSubsystemVersion: 0 -CHECK-NEXT: SizeOfImage: 24576 -CHECK-NEXT: SizeOfHeaders: 1024 -CHECK-NEXT: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI (0x3) -CHECK-NEXT: Characteristics [ (0x8160) -CHECK-NEXT: IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE (0x40) -CHECK-NEXT: IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA (0x20) -CHECK-NEXT: IMAGE_DLL_CHARACTERISTICS_NX_COMPAT (0x100) -CHECK-NEXT: IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE (0x8000) -CHECK-NEXT: ] -CHECK-NEXT: SizeOfStackReserve: 1048576 -CHECK-NEXT: SizeOfStackCommit: 4096 -CHECK-NEXT: SizeOfHeapReserve: 1048576 -CHECK-NEXT: SizeOfHeapCommit: 4096 -CHECK-NEXT: NumberOfRvaAndSize: 16 -CHECK-NEXT: DataDirectory { -CHECK-NEXT: ExportTableRVA: 0x0 -CHECK-NEXT: ExportTableSize: 0x0 -CHECK-NEXT: ImportTableRVA: 0x3000 -CHECK-NEXT: ImportTableSize: 0x28 -CHECK-NEXT: ResourceTableRVA: 0x0 -CHECK-NEXT: ResourceTableSize: 0x0 -CHECK-NEXT: ExceptionTableRVA: 0x0 -CHECK-NEXT: ExceptionTableSize: 0x0 -CHECK-NEXT: CertificateTableRVA: 0x0 -CHECK-NEXT: CertificateTableSize: 0x0 -CHECK-NEXT: BaseRelocationTableRVA: 0x0 -CHECK-NEXT: BaseRelocationTableSize: 0x0 -CHECK-NEXT: DebugRVA: 0x0 -CHECK-NEXT: DebugSize: 0x0 -CHECK-NEXT: ArchitectureRVA: 0x0 -CHECK-NEXT: ArchitectureSize: 0x0 -CHECK-NEXT: GlobalPtrRVA: 0x0 -CHECK-NEXT: GlobalPtrSize: 0x0 -CHECK-NEXT: TLSTableRVA: 0x0 -CHECK-NEXT: TLSTableSize: 0x0 -CHECK-NEXT: LoadConfigTableRVA: 0x0 -CHECK-NEXT: LoadConfigTableSize: 0x0 -CHECK-NEXT: BoundImportRVA: 0x0 -CHECK-NEXT: BoundImportSize: 0x0 -CHECK-NEXT: IATRVA: 0x2000 -CHECK-NEXT: IATSize: 0x10 -CHECK-NEXT: DelayImportDescriptorRVA: 0x0 -CHECK-NEXT: DelayImportDescriptorSize: 0x0 -CHECK-NEXT: CLRRuntimeHeaderRVA: 0x0 -CHECK-NEXT: CLRRuntimeHeaderSize: 0x0 -CHECK-NEXT: ReservedRVA: 0x0 -CHECK-NEXT: ReservedSize: 0x0 -CHECK-NEXT: } -CHECK-NEXT: } Index: test/pecoff/reloc.test =================================================================== --- test/pecoff/reloc.test +++ /dev/null @@ -1,16 +0,0 @@ -# REQUIRES: x86 - -# RUN: yaml2obj %p/Inputs/reloc.obj.yaml > %t1.obj -# RUN: yaml2obj %p/Inputs/abs.obj.yaml > %t2.obj -# -# RUN: lld -flavor link /out:%t.exe /subsystem:console /force /opt:noref \ -# RUN: -- %t1.obj %t2.obj -# RUN: llvm-objdump -d %t.exe | FileCheck %s - -CHECK: .text: -CHECK: 3000: 68 02 00 00 00 -CHECK: 3005: 68 05 00 00 00 -CHECK: 300a: 68 00 10 40 00 -CHECK: 300f: 68 00 10 40 00 -CHECK: 3014: 68 00 20 40 00 -CHECK: 3019: 68 ef be ad de Index: test/pecoff/reloc64.test =================================================================== --- test/pecoff/reloc64.test +++ /dev/null @@ -1,20 +0,0 @@ -# REQUIRES: x86 - -# RUN: yaml2obj %p/Inputs/reloc64.obj.yaml > %t.obj - -# RUN: lld -flavor link /out:%t.exe /subsystem:console /machine:x64 \ -# RUN: /entry:entry -- %t.obj -# RUN: llvm-objdump -d %t.exe | FileCheck %s - -CHECK: Disassembly of section .text: -CHECK-NEXT: .text: -CHECK-NEXT: 1000: 48 b8 28 10 00 40 01 00 00 ff -CHECK-NEXT: 100a: e8 19 00 00 ff -CHECK-NEXT: 100f: e8 13 00 00 ff -CHECK-NEXT: 1014: e8 0d 00 00 ff -CHECK-NEXT: 1019: e8 07 00 00 ff -CHECK-NEXT: 101e: e8 01 00 00 ff -CHECK-NEXT: 1023: e8 fb ff ff fe -CHECK-NEXT: 1028: e8 01 00 00 ff -CHECK-NEXT: 102d: e8 28 00 00 ff -CHECK-NEXT: 1032: c3 Index: test/pecoff/resource.test =================================================================== --- test/pecoff/resource.test +++ /dev/null @@ -1,18 +0,0 @@ -# REQUIRES: winres - -# RUN: yaml2obj %p/Inputs/nop.obj.yaml > %t.obj - -# RUN: lld -flavor link /out:%t.exe /subsystem:console /entry:start /opt:noref \ -# RUN: -- %t.obj %p/Inputs/resource.res - -# Check if the binary contains UTF-16LE string "Hello" copied from resource.res. -# RUN: FileCheck --check-prefix=EXE %s < %t.exe - -EXE: {{H.e.l.l.o}} - -# RUN: lld -flavor link /out:%t.exe /subsystem:console /entry:start /opt:noref \ -# RUN: /manifest:embed -- %t.obj %p/Inputs/resource.res -# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s - -CHECK: ResourceTableRVA: 0x1000 -CHECK: ResourceTableSize: 0x208 Index: test/pecoff/responsefile.test =================================================================== --- test/pecoff/responsefile.test +++ /dev/null @@ -1,7 +0,0 @@ -# RUN: yaml2obj %p/Inputs/hello.obj.yaml > %t.obj -# RUN: not lld -flavor link /verbose @%p/Inputs/responsefile.txt >& %t.log -# RUN: FileCheck %s < %t.log - -CHECK: warning: ignoring unknown argument: -foo -CHECK: warning: ignoring unknown argument: -bar\baz -Command line: link /verbose -foo -bar\baz Index: test/pecoff/safeseh.test =================================================================== --- test/pecoff/safeseh.test +++ /dev/null @@ -1,9 +0,0 @@ -# "hello.obj" does not have the symbol "@feat.00", so it's not -# compatible with SEH. - -# RUN: yaml2obj %p/Inputs/hello.obj.yaml > %t1.obj -# RUN: not lld -flavor link /safeseh /out:%t1.exe /subsystem:console \ -# RUN: -- %t1.obj 2> %t1.err -# RUN: FileCheck -check-prefix=INCOMPAT %s < %t1.err - -INCOMPAT: /SAFESEH is specified, but {{.*}} is not compatible with SEH. Index: test/pecoff/secrel.test =================================================================== --- test/pecoff/secrel.test +++ /dev/null @@ -1,16 +0,0 @@ -# RUN: yaml2obj %p/Inputs/secrel1.obj.yaml > %t1.obj -# RUN: yaml2obj %p/Inputs/secrel2.obj.yaml > %t2.obj -# RUN: yaml2obj %p/Inputs/secrel2.obj.yaml > %t3.obj -# -# RUN: lld -flavor link /out:%t.exe /subsystem:console /entry:main \ -# RUN: -- %t1.obj %t2.obj %t3.obj -# RUN: llvm-objdump -s %t.exe | FileCheck %s - -CHECK: Contents of section .data: -CHECK: 1000 00000000 00000000 00000000 00000000 -CHECK: 1010 10000000 00000000 00000000 00000000 -CHECK: 1020 20000000 00000000 00000000 00000000 -CHECK: Contents of section .data2: -CHECK: 2000 00000000 00000000 00000000 00000000 -CHECK: 2010 10000000 00000000 00000000 00000000 -CHECK: 2020 20000000 00000000 00000000 00000000 Index: test/pecoff/section-attribute.test =================================================================== --- test/pecoff/section-attribute.test +++ /dev/null @@ -1,45 +0,0 @@ -# RUN: yaml2obj %p/Inputs/nonstandard-sections.obj.yaml > %t.obj -# RUN: lld -flavor link /out:%t.exe /subsystem:console /force \ -# RUN: /section:.foo,d /section:.bar,rw /section:.text,rwe -- %t.obj -# RUN: llvm-readobj -sections %t.exe | FileCheck %s - -CHECK: Sections [ -CHECK: Section { -CHECK: Number: 1 -CHECK: Name: .bar (2E 62 61 72 00 00 00 00) -CHECK: Characteristics [ (0xC0000040) -CHECK: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) -CHECK: IMAGE_SCN_MEM_READ (0x40000000) -CHECK: IMAGE_SCN_MEM_WRITE (0x80000000) -CHECK: ] -CHECK: } -CHECK: Section { -CHECK: Number: 2 -CHECK: Name: .data (2E 64 61 74 61 00 00 00) -CHECK: Characteristics [ (0xC0000040) -CHECK: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) -CHECK: IMAGE_SCN_MEM_READ (0x40000000) -CHECK: IMAGE_SCN_MEM_WRITE (0x80000000) -CHECK: ] -CHECK: } -CHECK: Section { -CHECK: Number: 3 -CHECK: Name: .foo (2E 66 6F 6F 00 00 00 00) -CHECK: Characteristics [ (0xC2000040) -CHECK: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) -CHECK: IMAGE_SCN_MEM_DISCARDABLE (0x2000000) -CHECK: IMAGE_SCN_MEM_READ (0x40000000) -CHECK: IMAGE_SCN_MEM_WRITE (0x80000000) -CHECK: ] -CHECK: } -CHECK: Section { -CHECK: Number: 4 -CHECK: Name: .text (2E 74 65 78 74 00 00 00) -CHECK: Characteristics [ (0xE0000020) -CHECK: IMAGE_SCN_CNT_CODE (0x20) -CHECK: IMAGE_SCN_MEM_EXECUTE (0x20000000) -CHECK: IMAGE_SCN_MEM_READ (0x40000000) -CHECK: IMAGE_SCN_MEM_WRITE (0x80000000) -CHECK: ] -CHECK: } -CHECK: ] Index: test/pecoff/section-renaming.test =================================================================== --- test/pecoff/section-renaming.test +++ /dev/null @@ -1,61 +0,0 @@ -# RUN: yaml2obj %p/Inputs/nonstandard-sections.obj.yaml > %t.obj -# RUN: lld -flavor link /out:%t.exe /subsystem:console /force \ -# RUN: /merge:.foo=.hoge /merge:.bar=.text -- %t.obj -# RUN: llvm-readobj -sections %t.exe | FileCheck %s - -CHECK: Format: COFF-i386 -CHECK-NEXT: Arch: i386 -CHECK-NEXT: AddressSize: 32bit -CHECK-NEXT: Sections [ -CHECK-NEXT: Section { -CHECK-NEXT: Number: 1 -CHECK-NEXT: Name: .data (2E 64 61 74 61 00 00 00) -CHECK-NEXT: VirtualSize: 0x4 -CHECK-NEXT: VirtualAddress: 0x1000 -CHECK-NEXT: RawDataSize: 512 -CHECK-NEXT: PointerToRawData: 0x200 -CHECK-NEXT: PointerToRelocations: 0x0 -CHECK-NEXT: PointerToLineNumbers: 0x0 -CHECK-NEXT: RelocationCount: 0 -CHECK-NEXT: LineNumberCount: 0 -CHECK-NEXT: Characteristics [ (0xC0000040) -CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) -CHECK-NEXT: IMAGE_SCN_MEM_READ (0x40000000) -CHECK-NEXT: IMAGE_SCN_MEM_WRITE (0x80000000) -CHECK-NEXT: ] -CHECK-NEXT: } -CHECK-NEXT: Section { -CHECK-NEXT: Number: 2 -CHECK-NEXT: Name: .hoge (2E 68 6F 67 65 00 00 00) -CHECK-NEXT: VirtualSize: 0x4 -CHECK-NEXT: VirtualAddress: 0x2000 -CHECK-NEXT: RawDataSize: 512 -CHECK-NEXT: PointerToRawData: 0x400 -CHECK-NEXT: PointerToRelocations: 0x0 -CHECK-NEXT: PointerToLineNumbers: 0x0 -CHECK-NEXT: RelocationCount: 0 -CHECK-NEXT: LineNumberCount: 0 -CHECK-NEXT: Characteristics [ (0xC0000040) -CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) -CHECK-NEXT: IMAGE_SCN_MEM_READ (0x40000000) -CHECK-NEXT: IMAGE_SCN_MEM_WRITE (0x80000000) -CHECK-NEXT: ] -CHECK-NEXT: } -CHECK-NEXT: Section { -CHECK-NEXT: Number: 3 -CHECK-NEXT: Name: .text (2E 74 65 78 74 00 00 00) -CHECK-NEXT: VirtualSize: 0x8 -CHECK-NEXT: VirtualAddress: 0x3000 -CHECK-NEXT: RawDataSize: 512 -CHECK-NEXT: PointerToRawData: 0x600 -CHECK-NEXT: PointerToRelocations: 0x0 -CHECK-NEXT: PointerToLineNumbers: 0x0 -CHECK-NEXT: RelocationCount: 0 -CHECK-NEXT: LineNumberCount: 0 -CHECK-NEXT: Characteristics [ (0x60000020) -CHECK-NEXT: IMAGE_SCN_CNT_CODE (0x20) -CHECK-NEXT: IMAGE_SCN_MEM_EXECUTE (0x20000000) -CHECK-NEXT: IMAGE_SCN_MEM_READ (0x40000000) -CHECK-NEXT: ] -CHECK-NEXT: } -CHECK-NEXT: ] Index: test/pecoff/seh.test =================================================================== --- test/pecoff/seh.test +++ /dev/null @@ -1,31 +0,0 @@ -# RUN: yaml2obj %p/Inputs/seh.obj.yaml > %t.obj -# -# RUN: lld -flavor link /out:%t.exe /subsystem:console /force /nodefaultlib \ -# RUN: -- %t.obj -# RUN: llvm-objdump -private-headers %t.exe | FileCheck %s - -CHECK: Load configuration: -CHECK: Timestamp: 0 -CHECK: Major Version: 0 -CHECK: Minor Version: 0 -CHECK: GlobalFlags Clear: 0 -CHECK: GlobalFlags Set: 0 -CHECK: Critical Section Default Timeout: 0 -CHECK: Decommit Free Block Threshold: 0 -CHECK: Decommit Total Free Threshold: 0 -CHECK: Lock Prefix Table: 0 -CHECK: Maximum Allocation Size: 0 -CHECK: Virtual Memory Threshold: 0 -CHECK: Process Affinity Mask: 0 -CHECK: Process Heap Flags: 0 -CHECK: CSD Version: 0 -CHECK: Security Cookie: 0 -CHECK: SEH Table: 4206592 -CHECK: SEH Count: 2 -CHECK: SEH Table: 0x{{[0-9a-f]+}} 0x{{[0-9a-f]+}} - -# RUN: lld -flavor link /out:%t.exe /subsystem:console /force /nodefaultlib \ -# RUN: /safeseh:no -- %t.obj -# RUN: llvm-objdump -private-headers %t.exe | FileCheck -check-prefix=NOSEH %s - -NOSEH-NOT: SEH Table: Index: test/pecoff/seh64.test =================================================================== --- test/pecoff/seh64.test +++ /dev/null @@ -1,57 +0,0 @@ -# RUN: yaml2obj %p/Inputs/unwind.obj.yaml > %t.obj -# -# RUN: lld -flavor link /machine:x64 /out:%t.exe /subsystem:console /force \ -# RUN: /nodefaultlib -- %t.obj -# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=HEADER %s -# RUN: llvm-objdump -unwind-info %t.exe | FileCheck -check-prefix=UNWIND %s - -HEADER: ExceptionTableRVA: 0x1000 - -UNWIND: Function Table: -UNWIND: Start Address: 0x2000 -UNWIND: End Address: 0x201b -UNWIND: Unwind Info Address: 0x3000 -UNWIND: Version: 1 -UNWIND: Flags: 1 UNW_ExceptionHandler -UNWIND: Size of prolog: 18 -UNWIND: Number of Codes: 8 -UNWIND: Frame register: RBX -UNWIND: Frame offset: 0 -UNWIND: Unwind Codes: -UNWIND: 0x12: UOP_SetFPReg -UNWIND: 0x0f: UOP_PushNonVol RBX -UNWIND: 0x0e: UOP_SaveXMM128 XMM8 [0x0000] -UNWIND: 0x09: UOP_SaveNonVol RSI [0x0010] -UNWIND: 0x04: UOP_AllocSmall 24 -UNWIND: 0x00: UOP_PushMachFrame w/o error code -UNWIND: Function Table: -UNWIND: Start Address: 0x2012 -UNWIND: End Address: 0x2012 -UNWIND: Unwind Info Address: 0x301c -UNWIND: Version: 1 -UNWIND: Flags: 4 UNW_ChainInfo -UNWIND: Size of prolog: 0 -UNWIND: Number of Codes: 0 -UNWIND: No frame pointer used -UNWIND: Function Table: -UNWIND: Start Address: 0x201b -UNWIND: End Address: 0x201c -UNWIND: Unwind Info Address: 0x302c -UNWIND: Version: 1 -UNWIND: Flags: 0 -UNWIND: Size of prolog: 0 -UNWIND: Number of Codes: 0 -UNWIND: No frame pointer used -UNWIND: Function Table: -UNWIND: Start Address: 0x201c -UNWIND: End Address: 0x2039 -UNWIND: Unwind Info Address: 0x3034 -UNWIND: Version: 1 -UNWIND: Flags: 0 -UNWIND: Size of prolog: 14 -UNWIND: Number of Codes: 6 -UNWIND: No frame pointer used -UNWIND: Unwind Codes: -UNWIND: 0x0e: UOP_AllocLarge 8454128 -UNWIND: 0x07: UOP_AllocLarge 8190 -UNWIND: 0x00: UOP_PushMachFrame w/o error code Index: test/pecoff/subsystem.test =================================================================== --- test/pecoff/subsystem.test +++ /dev/null @@ -1,12 +0,0 @@ -# RUN: yaml2obj %p/Inputs/subsystem.main.yaml > %t.main.obj -# RUN: yaml2obj %p/Inputs/subsystem.winmain.yaml > %t.winmain.obj -# -# RUN: lld -flavor link /out:%t.main.exe -- %t.main.obj -# RUN: llvm-readobj -file-headers %t.main.exe | FileCheck -check-prefix=MAIN %s -# -# RUN: lld -flavor link /out:%t.winmain.exe -- %t.winmain.obj -# RUN: llvm-readobj -file-headers %t.winmain.exe | \ -# RUN: FileCheck -check-prefix=WINMAIN %s - -MAIN: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI -WINMAIN: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_GUI Index: test/pecoff/tls.test =================================================================== --- test/pecoff/tls.test +++ /dev/null @@ -1,14 +0,0 @@ -# RUN: yaml2obj %p/Inputs/hello.obj.yaml > %t1.obj -# RUN: yaml2obj %p/Inputs/tlsused.obj.yaml > %t2.obj - -# RUN: lld -flavor link /out:%t1.exe /subsystem:console /force -- %t1.obj -# RUN: llvm-readobj -file-headers %t1.exe | FileCheck -check-prefix=NOTLS %s - -# RUN: lld -flavor link /out:%t2.exe /subsystem:console /force -- %t1.obj %t2.obj -# RUN: llvm-readobj -file-headers %t2.exe | FileCheck -check-prefix=TLS %s - -NOTLS: TLSTableRVA: 0x0 -NOTLS: TLSTableSize: 0x0 - -TLS: TLSTableRVA: 0x1014 -TLS: TLSTableSize: 0x18 Index: test/pecoff/trivial.test =================================================================== --- test/pecoff/trivial.test +++ /dev/null @@ -1,103 +0,0 @@ -# Checks functionality of PECOFF writer. "nop.obj" is an object that has only -# text section. Other data, including data sections, relocations, symbol -# tables are not present in nop.obj. -# -# RUN: yaml2obj %p/Inputs/nop.obj.yaml > %t.obj -# -# RUN: lld -flavor link /out:%t1.exe /subsystem:console,3.11 /version:1.25 \ -# RUN: /entry:start /opt:noref -- %t.obj -# RUN: llvm-readobj -file-headers %t1.exe | FileCheck -check-prefix=FILE %s -# -# RUN: lld -flavor link /out:%t2.exe /subsystem:console /entry:start \ -# RUN: /opt:noref -- %t.obj -# RUN: llvm-readobj -sections %t2.exe | FileCheck -check-prefix=SECTIONS %s - -FILE: Format: COFF-i386 -FILE-NEXT: Arch: i386 -FILE-NEXT: AddressSize: 32bit -FILE-NEXT: ImageFileHeader { -FILE-NEXT: Machine: IMAGE_FILE_MACHINE_I386 (0x14C) -FILE-NEXT: SectionCount: 1 -FILE-NEXT: TimeDateStamp: -FILE-NEXT: PointerToSymbolTable: 0x0 -FILE-NEXT: SymbolCount: 0 -FILE-NEXT: OptionalHeaderSize: 224 -FILE-NEXT: Characteristics [ (0x102) -FILE-NEXT: IMAGE_FILE_32BIT_MACHINE (0x100) -FILE-NEXT: IMAGE_FILE_EXECUTABLE_IMAGE (0x2) -FILE-NEXT: ] -FILE-NEXT: } -FILE-NEXT: ImageOptionalHeader { -FILE-NEXT: MajorLinkerVersion: 0 -FILE-NEXT: MinorLinkerVersion: 0 -FILE-NEXT: SizeOfCode: 512 -FILE-NEXT: SizeOfInitializedData: 0 -FILE-NEXT: SizeOfUninitializedData: 0 -FILE-NEXT: AddressOfEntryPoint: 0x1000 -FILE-NEXT: BaseOfCode: 0x1000 -FILE-NEXT: BaseOfData: 0 -FILE-NEXT: ImageBase: 0x400000 -FILE-NEXT: SectionAlignment: 4096 -FILE-NEXT: FileAlignment: 512 -FILE-NEXT: MajorOperatingSystemVersion: 3 -FILE-NEXT: MinorOperatingSystemVersion: 11 -FILE-NEXT: MajorImageVersion: 1 -FILE-NEXT: MinorImageVersion: 25 -FILE-NEXT: MajorSubsystemVersion: 3 -FILE-NEXT: MinorSubsystemVersion: 11 -FILE-NEXT: SizeOfImage: 8192 -FILE-NEXT: SizeOfHeaders: 512 -FILE-NEXT: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI (0x3) -FILE-NEXT: Characteristics [ (0x8540) -FILE-NEXT: IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE (0x40) -FILE-NEXT: IMAGE_DLL_CHARACTERISTICS_NO_SEH (0x400) -FILE-NEXT: IMAGE_DLL_CHARACTERISTICS_NX_COMPAT (0x100) -FILE-NEXT: IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE (0x8000) -FILE-NEXT: ] -FILE-NEXT: SizeOfStackReserve: 1048576 -FILE-NEXT: SizeOfStackCommit: 4096 -FILE-NEXT: SizeOfHeapReserve: 1048576 -FILE-NEXT: SizeOfHeapCommit: 4096 -FILE-NEXT: NumberOfRvaAndSize: 16 -FILE: DOSHeader { -FILE-NEXT: Magic: MZ -FILE-NEXT: UsedBytesInTheLastPage: 0 -FILE-NEXT: FileSizeInPages: 0 -FILE-NEXT: NumberOfRelocationItems: 0 -FILE-NEXT: HeaderSizeInParagraphs: 0 -FILE-NEXT: MinimumExtraParagraphs: 0 -FILE-NEXT: MaximumExtraParagraphs: 0 -FILE-NEXT: InitialRelativeSS: 0 -FILE-NEXT: InitialSP: 0 -FILE-NEXT: Checksum: 0 -FILE-NEXT: InitialIP: 0 -FILE-NEXT: InitialRelativeCS: 0 -FILE-NEXT: AddressOfRelocationTable: 64 -FILE-NEXT: OverlayNumber: 0 -FILE-NEXT: OEMid: 0 -FILE-NEXT: OEMinfo: 0 -FILE-NEXT: AddressOfNewExeHeader: 128 -FILE-NEXT: } - -SECTIONS: Format: COFF-i386 -SECTIONS-NEXT: Arch: i386 -SECTIONS-NEXT: AddressSize: 32bit -SECTIONS-NEXT: Sections [ -SECTIONS-NEXT: Section { -SECTIONS-NEXT: Number: 1 -SECTIONS-NEXT: Name: .text (2E 74 65 78 74 00 00 00) -SECTIONS-NEXT: VirtualSize: 0x6 -SECTIONS-NEXT: VirtualAddress: 0x1000 -SECTIONS-NEXT: RawDataSize: 512 -SECTIONS-NEXT: PointerToRawData: 0x200 -SECTIONS-NEXT: PointerToRelocations: 0x0 -SECTIONS-NEXT: PointerToLineNumbers: 0x0 -SECTIONS-NEXT: RelocationCount: 0 -SECTIONS-NEXT: LineNumberCount: 0 -SECTIONS-NEXT: Characteristics [ -SECTIONS-NEXT: IMAGE_SCN_CNT_CODE -SECTIONS-NEXT: IMAGE_SCN_MEM_EXECUTE -SECTIONS-NEXT: IMAGE_SCN_MEM_READ -SECTIONS-NEXT: ] -SECTIONS-NEXT: } -SECTIONS-NEXT: ] Index: test/pecoff/unknown-drectve.test =================================================================== --- test/pecoff/unknown-drectve.test +++ /dev/null @@ -1,6 +0,0 @@ -# RUN: yaml2obj %p/Inputs/unknown-drectve.obj.yaml > %t.obj -# -# RUN: not lld -flavor link /out:%t.exe -- %t.obj >& %t.log -# RUN: FileCheck -check-prefix=ERROR %s < %t.log - -ERROR: Cannot open /nosuchoption:foobar Index: test/pecoff/weak-external.test =================================================================== --- test/pecoff/weak-external.test +++ /dev/null @@ -1,9 +0,0 @@ -# RUN: yaml2obj %p/Inputs/weak-externals.obj.yaml > %t.obj - -# RUN: lld -flavor link /force /out:%t.exe /subsystem:console \ -# RUN: /entry:fn -- %t.obj %p/Inputs/static.lib 2> %t2.log -# RUN: FileCheck %s < %t2.log - -CHECK: _no_such_symbol1 -CHECK-NOT: _no_such_symbol2 -CHECK: _no_such_symbol3 Index: unittests/DriverTests/CMakeLists.txt =================================================================== --- unittests/DriverTests/CMakeLists.txt +++ unittests/DriverTests/CMakeLists.txt @@ -2,14 +2,11 @@ UniversalDriverTest.cpp GnuLdDriverTest.cpp DarwinLdDriverTest.cpp - WinLinkDriverTest.cpp - WinLinkModuleDefTest.cpp ) target_link_libraries(DriverTests lldDriver lldCOFF lldCore - lldPECOFF lldMachO ) Index: unittests/DriverTests/WinLinkDriverTest.cpp =================================================================== --- unittests/DriverTests/WinLinkDriverTest.cpp +++ /dev/null @@ -1,728 +0,0 @@ -//===- lld/unittest/WinLinkDriverTest.cpp ---------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// \brief Windows link.exe driver tests. -/// -//===----------------------------------------------------------------------===// - -#include "DriverTest.h" -#include "lld/ReaderWriter/PECOFFLinkingContext.h" -#include "llvm/ADT/Optional.h" -#include "llvm/Support/COFF.h" -#include -#include - -using namespace llvm; -using namespace lld; - -namespace { -class WinLinkParserTest - : public ParserTest { -protected: - const LinkingContext *linkingContext() override { return &_ctx; } -}; -} - -TEST_F(WinLinkParserTest, Basic) { - EXPECT_TRUE(parse("link.exe", "/subsystem:console", "/out:a.exe", - "-entry:start", "a.obj", "b.obj", "c.obj", nullptr)); - EXPECT_EQ(llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI, _ctx.getSubsystem()); - EXPECT_EQ(llvm::COFF::IMAGE_FILE_MACHINE_I386, _ctx.getMachineType()); - EXPECT_EQ("a.exe", _ctx.outputPath()); - EXPECT_EQ("start", _ctx.getEntrySymbolName()); - EXPECT_EQ(4, inputFileCount()); - EXPECT_EQ("a.obj", inputFile(0)); - EXPECT_EQ("b.obj", inputFile(1)); - EXPECT_EQ("c.obj", inputFile(2)); - EXPECT_TRUE(_ctx.getInputSearchPaths().empty()); - - // Unspecified flags will have default values. - EXPECT_FALSE(_ctx.isDll()); - EXPECT_EQ(6, _ctx.getMinOSVersion().majorVersion); - EXPECT_EQ(0, _ctx.getMinOSVersion().minorVersion); - EXPECT_EQ(0x400000U, _ctx.getBaseAddress()); - EXPECT_EQ(1024 * 1024U, _ctx.getStackReserve()); - EXPECT_EQ(4096U, _ctx.getStackCommit()); - EXPECT_EQ(4096U, _ctx.getSectionDefaultAlignment()); - EXPECT_FALSE(_ctx.allowRemainingUndefines()); - EXPECT_TRUE(_ctx.isNxCompat()); - EXPECT_FALSE(_ctx.getLargeAddressAware()); - EXPECT_TRUE(_ctx.getAllowBind()); - EXPECT_TRUE(_ctx.getAllowIsolation()); - EXPECT_FALSE(_ctx.getSwapRunFromCD()); - EXPECT_FALSE(_ctx.getSwapRunFromNet()); - EXPECT_TRUE(_ctx.getBaseRelocationEnabled()); - EXPECT_TRUE(_ctx.isTerminalServerAware()); - EXPECT_TRUE(_ctx.getDynamicBaseEnabled()); - EXPECT_TRUE(_ctx.getCreateManifest()); - EXPECT_EQ("", _ctx.getManifestDependency()); - EXPECT_FALSE(_ctx.getEmbedManifest()); - EXPECT_EQ(1, _ctx.getManifestId()); - EXPECT_TRUE(_ctx.getManifestUAC()); - EXPECT_EQ("'asInvoker'", _ctx.getManifestLevel()); - EXPECT_EQ("'false'", _ctx.getManifestUiAccess()); - EXPECT_TRUE(_ctx.deadStrip()); - EXPECT_FALSE(_ctx.logInputFiles()); -} - -TEST_F(WinLinkParserTest, StartsWithHyphen) { - EXPECT_TRUE( - parse("link.exe", "-subsystem:console", "-out:a.exe", "a.obj", nullptr)); - EXPECT_EQ(llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI, _ctx.getSubsystem()); - EXPECT_EQ("a.exe", _ctx.outputPath()); - EXPECT_EQ(2, inputFileCount()); - EXPECT_EQ("a.obj", inputFile(0)); -} - -TEST_F(WinLinkParserTest, UppercaseOption) { - EXPECT_TRUE( - parse("link.exe", "/SUBSYSTEM:CONSOLE", "/OUT:a.exe", "a.obj", nullptr)); - EXPECT_EQ(llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI, _ctx.getSubsystem()); - EXPECT_EQ("a.exe", _ctx.outputPath()); - EXPECT_EQ(2, inputFileCount()); - EXPECT_EQ("a.obj", inputFile(0)); -} - -TEST_F(WinLinkParserTest, Mllvm) { - EXPECT_TRUE(parse("link.exe", "/mllvm:-debug", "a.obj", nullptr)); - const std::vector &options = _ctx.llvmOptions(); - EXPECT_EQ(1U, options.size()); - EXPECT_STREQ("-debug", options[0]); -} - -TEST_F(WinLinkParserTest, NoInputFiles) { - EXPECT_FALSE(parse("link.exe", nullptr)); - EXPECT_EQ("No input files\n", errorMessage()); -} - -// -// Tests for implicit file extension interpolation. -// - -TEST_F(WinLinkParserTest, NoFileExtension) { - EXPECT_TRUE(parse("link.exe", "foo", "bar", nullptr)); - EXPECT_EQ("foo.exe", _ctx.outputPath()); - EXPECT_EQ(3, inputFileCount()); - EXPECT_EQ("foo.obj", inputFile(0)); - EXPECT_EQ("bar.obj", inputFile(1)); -} - -TEST_F(WinLinkParserTest, NonStandardFileExtension) { - EXPECT_TRUE(parse("link.exe", "foo.o", nullptr)); - EXPECT_EQ("foo.exe", _ctx.outputPath()); - EXPECT_EQ(2, inputFileCount()); - EXPECT_EQ("foo.o", inputFile(0)); -} - -TEST_F(WinLinkParserTest, Libpath) { - EXPECT_TRUE( - parse("link.exe", "/libpath:dir1", "/libpath:dir2", "a.obj", nullptr)); - const std::vector &paths = _ctx.getInputSearchPaths(); - EXPECT_EQ(2U, paths.size()); - EXPECT_EQ("dir1", paths[0]); - EXPECT_EQ("dir2", paths[1]); -} - -// -// Tests for input file order -// - -TEST_F(WinLinkParserTest, InputOrder) { - EXPECT_TRUE(parse("link.exe", "a.lib", "b.obj", "c.obj", "a.lib", "d.obj", - nullptr)); - EXPECT_EQ(5, inputFileCount()); - EXPECT_EQ("b.obj", inputFile(0)); - EXPECT_EQ("c.obj", inputFile(1)); - EXPECT_EQ("d.obj", inputFile(2)); - EXPECT_EQ("a.lib", inputFile(3)); -} - -// -// Tests for command line options that take values. -// - -TEST_F(WinLinkParserTest, AlternateName) { - EXPECT_TRUE(parse("link.exe", "/alternatename:sym1=sym", - "/alternatename:sym2=sym", "a.out", nullptr)); - const std::set &aliases = _ctx.getAlternateNames("sym"); - EXPECT_EQ(2U, aliases.size()); - auto it = aliases.begin(); - EXPECT_EQ("sym1", *it++); - EXPECT_EQ("sym2", *it++); -} - -TEST_F(WinLinkParserTest, Export) { - EXPECT_TRUE(parse("link.exe", "/export:foo", "a.out", nullptr)); - const std::vector &exports = - _ctx.getDllExports(); - EXPECT_EQ(1U, exports.size()); - EXPECT_EQ("_foo", exports[0].name); - EXPECT_EQ(-1, exports[0].ordinal); - EXPECT_FALSE(exports[0].noname); - EXPECT_FALSE(exports[0].isData); -} - -TEST_F(WinLinkParserTest, ExportWithOptions) { - EXPECT_TRUE(parse("link.exe", "/export:foo,@8,noname,data", - "/export:bar,@10,data", "a.out", nullptr)); - const std::vector &exports = - _ctx.getDllExports(); - EXPECT_EQ(2U, exports.size()); - EXPECT_EQ("_foo", exports[0].name); - EXPECT_EQ(8, exports[0].ordinal); - EXPECT_TRUE(exports[0].noname); - EXPECT_TRUE(exports[0].isData); - EXPECT_EQ("_bar", exports[1].name); - EXPECT_EQ(10, exports[1].ordinal); - EXPECT_FALSE(exports[1].noname); - EXPECT_TRUE(exports[1].isData); -} - -TEST_F(WinLinkParserTest, ExportDuplicateExports) { - EXPECT_TRUE( - parse("link.exe", "/export:foo", "/export:foo,@2", "a.out", nullptr)); - const std::vector &exports = - _ctx.getDllExports(); - EXPECT_EQ(1U, exports.size()); - EXPECT_EQ("_foo", exports[0].name); - EXPECT_EQ(-1, exports[0].ordinal); -} - -TEST_F(WinLinkParserTest, ExportDuplicateOrdinals) { - EXPECT_FALSE( - parse("link.exe", "/export:foo,@1", "/export:bar,@1", "a.out", nullptr)); -} - -TEST_F(WinLinkParserTest, ExportInvalid1) { - EXPECT_FALSE(parse("link.exe", "/export:foo,@0", "a.out", nullptr)); -} - -TEST_F(WinLinkParserTest, ExportInvalid2) { - EXPECT_FALSE(parse("link.exe", "/export:foo,@65536", "a.out", nullptr)); -} - -TEST_F(WinLinkParserTest, MachineX86) { - EXPECT_TRUE(parse("link.exe", "/machine:x86", "a.obj", nullptr)); - EXPECT_EQ(llvm::COFF::IMAGE_FILE_MACHINE_I386, _ctx.getMachineType()); -} - -TEST_F(WinLinkParserTest, MachineX64) { - EXPECT_TRUE(parse("link.exe", "/machine:x64", "a.obj", nullptr)); - EXPECT_EQ(llvm::COFF::IMAGE_FILE_MACHINE_AMD64, _ctx.getMachineType()); -} - -TEST_F(WinLinkParserTest, MachineArm) { - EXPECT_TRUE(parse("link.exe", "/machine:arm", "a.obj", nullptr)); - EXPECT_EQ(llvm::COFF::IMAGE_FILE_MACHINE_ARMNT, _ctx.getMachineType()); -} - -TEST_F(WinLinkParserTest, MachineUnknown) { - EXPECT_FALSE(parse("link.exe", "/machine:nosucharch", "a.obj", nullptr)); - EXPECT_EQ("error: unknown machine type: nosucharch\n", errorMessage()); -} - -TEST_F(WinLinkParserTest, MajorImageVersion) { - EXPECT_TRUE(parse("link.exe", "/version:7", "foo.o", nullptr)); - EXPECT_EQ(7, _ctx.getImageVersion().majorVersion); - EXPECT_EQ(0, _ctx.getImageVersion().minorVersion); -} - -TEST_F(WinLinkParserTest, MajorMinorImageVersion) { - EXPECT_TRUE(parse("link.exe", "/version:72.35", "foo.o", nullptr)); - EXPECT_EQ(72, _ctx.getImageVersion().majorVersion); - EXPECT_EQ(35, _ctx.getImageVersion().minorVersion); -} - -TEST_F(WinLinkParserTest, MinMajorOSVersion) { - EXPECT_TRUE(parse("link.exe", "/subsystem:windows,3", "foo.o", nullptr)); - EXPECT_EQ(llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_GUI, _ctx.getSubsystem()); - EXPECT_EQ(3, _ctx.getMinOSVersion().majorVersion); - EXPECT_EQ(0, _ctx.getMinOSVersion().minorVersion); -} - -TEST_F(WinLinkParserTest, MinMajorMinorOSVersion) { - EXPECT_TRUE(parse("link.exe", "/subsystem:windows,3.1", "foo.o", nullptr)); - EXPECT_EQ(llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_GUI, _ctx.getSubsystem()); - EXPECT_EQ(3, _ctx.getMinOSVersion().majorVersion); - EXPECT_EQ(1, _ctx.getMinOSVersion().minorVersion); -} - -TEST_F(WinLinkParserTest, Base) { - EXPECT_TRUE(parse("link.exe", "/base:8388608", "a.obj", nullptr)); - EXPECT_EQ(0x800000U, _ctx.getBaseAddress()); -} - -TEST_F(WinLinkParserTest, InvalidBase) { - EXPECT_FALSE(parse("link.exe", "/base:1234", "a.obj", nullptr)); - EXPECT_TRUE(StringRef(errorMessage()) - .startswith("Base address have to be multiple of 64K")); -} - -TEST_F(WinLinkParserTest, StackReserve) { - EXPECT_TRUE(parse("link.exe", "/stack:8192", "a.obj", nullptr)); - EXPECT_EQ(8192U, _ctx.getStackReserve()); - EXPECT_EQ(4096U, _ctx.getStackCommit()); -} - -TEST_F(WinLinkParserTest, StackReserveAndCommit) { - EXPECT_TRUE(parse("link.exe", "/stack:16384,8192", "a.obj", nullptr)); - EXPECT_EQ(16384U, _ctx.getStackReserve()); - EXPECT_EQ(8192U, _ctx.getStackCommit()); -} - -TEST_F(WinLinkParserTest, InvalidStackSize) { - EXPECT_FALSE(parse("link.exe", "/stack:8192,16384", "a.obj", nullptr)); - EXPECT_TRUE(StringRef(errorMessage()).startswith("Invalid stack size")); -} - -TEST_F(WinLinkParserTest, HeapReserve) { - EXPECT_TRUE(parse("link.exe", "/heap:8192", "a.obj", nullptr)); - EXPECT_EQ(8192U, _ctx.getHeapReserve()); - EXPECT_EQ(4096U, _ctx.getHeapCommit()); -} - -TEST_F(WinLinkParserTest, HeapReserveAndCommit) { - EXPECT_TRUE(parse("link.exe", "/heap:16384,8192", "a.obj", nullptr)); - EXPECT_EQ(16384U, _ctx.getHeapReserve()); - EXPECT_EQ(8192U, _ctx.getHeapCommit()); -} - -TEST_F(WinLinkParserTest, InvalidHeapSize) { - EXPECT_FALSE(parse("link.exe", "/heap:8192,16384", "a.obj", nullptr)); - EXPECT_TRUE(StringRef(errorMessage()).startswith("Invalid heap size")); -} - -TEST_F(WinLinkParserTest, SectionAlignment) { - EXPECT_TRUE(parse("link.exe", "/align:8192", "a.obj", nullptr)); - EXPECT_EQ(8192U, _ctx.getSectionDefaultAlignment()); -} - -TEST_F(WinLinkParserTest, InvalidAlignment) { - EXPECT_FALSE(parse("link.exe", "/align:1000", "a.obj", nullptr)); - EXPECT_EQ("Section alignment must be a power of 2, but got 1000\n", - errorMessage()); -} - -TEST_F(WinLinkParserTest, Include) { - EXPECT_TRUE(parse("link.exe", "/include:foo", "a.out", nullptr)); - auto symbols = _ctx.initialUndefinedSymbols(); - EXPECT_FALSE(symbols.empty()); - EXPECT_EQ("foo", symbols[0]); -} - -TEST_F(WinLinkParserTest, Merge) { - EXPECT_TRUE(parse("link.exe", "/merge:.foo=.bar", "/merge:.bar=.baz", - "a.out", nullptr)); - EXPECT_EQ(".baz", _ctx.getOutputSectionName(".foo")); - EXPECT_EQ(".baz", _ctx.getOutputSectionName(".bar")); - EXPECT_EQ(".abc", _ctx.getOutputSectionName(".abc")); -} - -TEST_F(WinLinkParserTest, Merge_Circular) { - EXPECT_FALSE(parse("link.exe", "/merge:.foo=.bar", "/merge:.bar=.foo", - "a.out", nullptr)); -} - -TEST_F(WinLinkParserTest, Implib) { - EXPECT_TRUE(parse("link.exe", "/implib:foo.dll.lib", "a.out", nullptr)); - EXPECT_EQ("foo.dll.lib", _ctx.getOutputImportLibraryPath()); -} - -TEST_F(WinLinkParserTest, ImplibDefault) { - EXPECT_TRUE(parse("link.exe", "/out:foobar.dll", "a.out", nullptr)); - EXPECT_EQ("foobar.lib", _ctx.getOutputImportLibraryPath()); -} - -// -// Tests for /section -// - -namespace { -const uint32_t discardable = llvm::COFF::IMAGE_SCN_MEM_DISCARDABLE; -const uint32_t not_cached = llvm::COFF::IMAGE_SCN_MEM_NOT_CACHED; -const uint32_t not_paged = llvm::COFF::IMAGE_SCN_MEM_NOT_PAGED; -const uint32_t shared = llvm::COFF::IMAGE_SCN_MEM_SHARED; -const uint32_t execute = llvm::COFF::IMAGE_SCN_MEM_EXECUTE; -const uint32_t read = llvm::COFF::IMAGE_SCN_MEM_READ; -const uint32_t write = llvm::COFF::IMAGE_SCN_MEM_WRITE; - -#define TEST_SECTION(testname, arg, expect) \ - TEST_F(WinLinkParserTest, testname) { \ - EXPECT_TRUE(parse("link.exe", "/section:.text," arg, "a.obj", nullptr)); \ - EXPECT_EQ(expect, _ctx.getSectionAttributes(".text", execute | read)); \ - } - -TEST_SECTION(SectionD, "d", execute | read | discardable) -TEST_SECTION(SectionE, "e", execute) -TEST_SECTION(SectionK, "k", execute | read | not_cached) -TEST_SECTION(SectionP, "p", execute | read | not_paged) -TEST_SECTION(SectionR, "r", read) -TEST_SECTION(SectionS, "s", execute | read | shared) -TEST_SECTION(SectionW, "w", write) - -#undef TEST_SECTION - -TEST_F(WinLinkParserTest, Section) { - EXPECT_TRUE(parse("link.exe", "/section:.text,dekprsw", - "/section:.text,!dekprsw", "a.obj", nullptr)); - EXPECT_EQ(0U, _ctx.getSectionAttributes(".text", execute | read)); -} - -TEST_F(WinLinkParserTest, SectionNegate) { - EXPECT_TRUE(parse("link.exe", "/section:.text,!e", "a.obj", nullptr)); - EXPECT_EQ(read, _ctx.getSectionAttributes(".text", execute | read)); -} - -TEST_F(WinLinkParserTest, SectionMultiple) { - EXPECT_TRUE(parse("link.exe", "/section:.foo,e", "/section:.foo,rw", - "/section:.foo,!d", "a.obj", nullptr)); - uint32_t flags = execute | read | not_paged | discardable; - uint32_t expected = execute | read | write | not_paged; - EXPECT_EQ(expected, _ctx.getSectionAttributes(".foo", flags)); -} - -} // end anonymous namespace - -// -// Tests for /defaultlib and /nodefaultlib. -// - -TEST_F(WinLinkParserTest, DefaultLib) { - EXPECT_TRUE(parse("link.exe", "/defaultlib:user32.lib", - "/defaultlib:kernel32", "a.obj", nullptr)); - EXPECT_EQ(4, inputFileCount()); - EXPECT_EQ("a.obj", inputFile(0)); - EXPECT_EQ("user32.lib", inputFile(1)); - EXPECT_EQ("kernel32.lib", inputFile(2)); -} - -TEST_F(WinLinkParserTest, DefaultLibDuplicates) { - EXPECT_TRUE(parse("link.exe", "/defaultlib:user32.lib", - "/defaultlib:user32.lib", "a.obj", nullptr)); - EXPECT_EQ(3, inputFileCount()); - EXPECT_EQ("a.obj", inputFile(0)); - EXPECT_EQ("user32.lib", inputFile(1)); -} - -TEST_F(WinLinkParserTest, NoDefaultLib) { - EXPECT_TRUE(parse("link.exe", "/defaultlib:user32.lib", - "/defaultlib:kernel32", "/nodefaultlib:user32.lib", "a.obj", - nullptr)); - EXPECT_EQ(3, inputFileCount()); - EXPECT_EQ("a.obj", inputFile(0)); - EXPECT_EQ("kernel32.lib", inputFile(1)); -} - -TEST_F(WinLinkParserTest, NoDefaultLibCase) { - EXPECT_TRUE(parse("link.exe", "/defaultlib:user32", - "/defaultlib:kernel32", "/nodefaultlib:USER32.LIB", "a.obj", - nullptr)); - EXPECT_EQ(3, inputFileCount()); - EXPECT_EQ("a.obj", inputFile(0)); - EXPECT_EQ("kernel32.lib", inputFile(1)); -} - -TEST_F(WinLinkParserTest, NoDefaultLibAll) { - EXPECT_TRUE(parse("link.exe", "/defaultlib:user32.lib", - "/defaultlib:kernel32", "/nodefaultlib", "a.obj", nullptr)); - EXPECT_EQ(2, inputFileCount()); - EXPECT_EQ("a.obj", inputFile(0)); -} - -TEST_F(WinLinkParserTest, DisallowLib) { - EXPECT_TRUE(parse("link.exe", "/defaultlib:user32.lib", - "/defaultlib:kernel32", "/disallowlib:user32.lib", "a.obj", - nullptr)); - EXPECT_EQ(3, inputFileCount()); - EXPECT_EQ("a.obj", inputFile(0)); - EXPECT_EQ("kernel32.lib", inputFile(1)); -} - -// -// Tests for DLL. -// - -TEST_F(WinLinkParserTest, NoEntry) { - EXPECT_TRUE(parse("link.exe", "/noentry", "/dll", "a.obj", nullptr)); - EXPECT_TRUE(_ctx.isDll()); - EXPECT_EQ(0x10000000U, _ctx.getBaseAddress()); - EXPECT_EQ("", _ctx.entrySymbolName()); -} - -TEST_F(WinLinkParserTest, NoEntryError) { - // /noentry without /dll is an error. - EXPECT_FALSE(parse("link.exe", "/noentry", "a.obj", nullptr)); - EXPECT_EQ("/noentry must be specified with /dll\n", errorMessage()); -} - -// -// Tests for DELAYLOAD. -// - -TEST_F(WinLinkParserTest, DelayLoad) { - EXPECT_TRUE(parse("link.exe", "/delayload:abc.dll", "/delayload:def.dll", - "a.obj", nullptr)); - EXPECT_TRUE(_ctx.isDelayLoadDLL("abc.dll")); - EXPECT_TRUE(_ctx.isDelayLoadDLL("DEF.DLL")); - EXPECT_FALSE(_ctx.isDelayLoadDLL("xyz.dll")); -} - -// -// Tests for SEH. -// - -TEST_F(WinLinkParserTest, SafeSEH) { - EXPECT_TRUE(parse("link.exe", "/safeseh", "a.obj", nullptr)); - EXPECT_TRUE(_ctx.requireSEH()); - EXPECT_FALSE(_ctx.noSEH()); -} - -TEST_F(WinLinkParserTest, NoSafeSEH) { - EXPECT_TRUE(parse("link.exe", "/safeseh:no", "a.obj", nullptr)); - EXPECT_FALSE(_ctx.requireSEH()); - EXPECT_TRUE(_ctx.noSEH()); -} - -// -// Tests for boolean flags. -// - -TEST_F(WinLinkParserTest, Force) { - EXPECT_TRUE(parse("link.exe", "/force", "a.obj", nullptr)); - EXPECT_TRUE(_ctx.allowRemainingUndefines()); -} - -TEST_F(WinLinkParserTest, ForceUnresolved) { - EXPECT_TRUE(parse("link.exe", "/force:unresolved", "a.obj", nullptr)); - EXPECT_TRUE(_ctx.allowRemainingUndefines()); -} - -TEST_F(WinLinkParserTest, NoNxCompat) { - EXPECT_TRUE(parse("link.exe", "/nxcompat:no", "a.obj", nullptr)); - EXPECT_FALSE(_ctx.isNxCompat()); -} - -TEST_F(WinLinkParserTest, LargeAddressAware) { - EXPECT_TRUE(parse("link.exe", "/largeaddressaware", "a.obj", nullptr)); - EXPECT_TRUE(_ctx.getLargeAddressAware()); -} - -TEST_F(WinLinkParserTest, NoLargeAddressAware) { - EXPECT_TRUE(parse("link.exe", "/largeaddressaware:no", "a.obj", nullptr)); - EXPECT_FALSE(_ctx.getLargeAddressAware()); -} - -TEST_F(WinLinkParserTest, AllowBind) { - EXPECT_TRUE(parse("link.exe", "/allowbind", "a.obj", nullptr)); - EXPECT_TRUE(_ctx.getAllowBind()); -} - -TEST_F(WinLinkParserTest, NoAllowBind) { - EXPECT_TRUE(parse("link.exe", "/allowbind:no", "a.obj", nullptr)); - EXPECT_FALSE(_ctx.getAllowBind()); -} - -TEST_F(WinLinkParserTest, AllowIsolation) { - EXPECT_TRUE(parse("link.exe", "/allowisolation", "a.obj", nullptr)); - EXPECT_TRUE(_ctx.getAllowIsolation()); -} - -TEST_F(WinLinkParserTest, NoAllowIsolation) { - EXPECT_TRUE(parse("link.exe", "/allowisolation:no", "a.obj", nullptr)); - EXPECT_FALSE(_ctx.getAllowIsolation()); -} - -TEST_F(WinLinkParserTest, SwapRunFromCD) { - EXPECT_TRUE(parse("link.exe", "/swaprun:cd", "a.obj", nullptr)); - EXPECT_TRUE(_ctx.getSwapRunFromCD()); -} - -TEST_F(WinLinkParserTest, SwapRunFromNet) { - EXPECT_TRUE(parse("link.exe", "/swaprun:net", "a.obj", nullptr)); - EXPECT_TRUE(_ctx.getSwapRunFromNet()); -} - -TEST_F(WinLinkParserTest, Debug) { - EXPECT_TRUE(parse("link.exe", "/debug", "a.obj", nullptr)); - EXPECT_TRUE(_ctx.deadStrip()); - EXPECT_TRUE(_ctx.getDebug()); - EXPECT_EQ("a.pdb", _ctx.getPDBFilePath()); -} - -TEST_F(WinLinkParserTest, PDB) { - EXPECT_TRUE(parse("link.exe", "/debug", "/pdb:foo.pdb", "a.obj", nullptr)); - EXPECT_TRUE(_ctx.getDebug()); - EXPECT_EQ("foo.pdb", _ctx.getPDBFilePath()); -} - -TEST_F(WinLinkParserTest, Fixed) { - EXPECT_TRUE(parse("link.exe", "/fixed", "a.out", nullptr)); - EXPECT_FALSE(_ctx.getBaseRelocationEnabled()); - EXPECT_FALSE(_ctx.getDynamicBaseEnabled()); -} - -TEST_F(WinLinkParserTest, NoFixed) { - EXPECT_TRUE(parse("link.exe", "/fixed:no", "a.out", nullptr)); - EXPECT_TRUE(_ctx.getBaseRelocationEnabled()); -} - -TEST_F(WinLinkParserTest, TerminalServerAware) { - EXPECT_TRUE(parse("link.exe", "/tsaware", "a.out", nullptr)); - EXPECT_TRUE(_ctx.isTerminalServerAware()); -} - -TEST_F(WinLinkParserTest, NoTerminalServerAware) { - EXPECT_TRUE(parse("link.exe", "/tsaware:no", "a.out", nullptr)); - EXPECT_FALSE(_ctx.isTerminalServerAware()); -} - -TEST_F(WinLinkParserTest, DynamicBase) { - EXPECT_TRUE(parse("link.exe", "/dynamicbase", "a.out", nullptr)); - EXPECT_TRUE(_ctx.getDynamicBaseEnabled()); -} - -TEST_F(WinLinkParserTest, NoDynamicBase) { - EXPECT_TRUE(parse("link.exe", "/dynamicbase:no", "a.out", nullptr)); - EXPECT_FALSE(_ctx.getDynamicBaseEnabled()); -} - -// -// Test for /failifmismatch -// - -TEST_F(WinLinkParserTest, FailIfMismatch_Match) { - EXPECT_TRUE(parse("link.exe", "/failifmismatch:foo=bar", - "/failifmismatch:foo=bar", "/failifmismatch:abc=def", - "a.out", nullptr)); -} - -TEST_F(WinLinkParserTest, FailIfMismatch_Mismatch) { - EXPECT_FALSE(parse("link.exe", "/failifmismatch:foo=bar", - "/failifmismatch:foo=baz", "a.out", nullptr)); -} - -// -// Tests for /manifest, /manifestuac, /manifestfile, and /manifestdependency. -// -TEST_F(WinLinkParserTest, Manifest_Default) { - EXPECT_TRUE(parse("link.exe", "/manifest", "a.out", nullptr)); - EXPECT_TRUE(_ctx.getCreateManifest()); - EXPECT_FALSE(_ctx.getEmbedManifest()); - EXPECT_EQ(1, _ctx.getManifestId()); - EXPECT_EQ("'asInvoker'", _ctx.getManifestLevel()); - EXPECT_EQ("'false'", _ctx.getManifestUiAccess()); -} - -TEST_F(WinLinkParserTest, Manifest_No) { - EXPECT_TRUE(parse("link.exe", "/manifest:no", "a.out", nullptr)); - EXPECT_FALSE(_ctx.getCreateManifest()); -} - -TEST_F(WinLinkParserTest, Manifestuac_no) { - EXPECT_TRUE(parse("link.exe", "/manifestuac:NO", "a.out", nullptr)); - EXPECT_FALSE(_ctx.getManifestUAC()); -} - -TEST_F(WinLinkParserTest, Manifestuac_Level) { - EXPECT_TRUE(parse("link.exe", "/manifestuac:level='requireAdministrator'", - "a.out", nullptr)); - EXPECT_EQ("'requireAdministrator'", _ctx.getManifestLevel()); - EXPECT_EQ("'false'", _ctx.getManifestUiAccess()); -} - -TEST_F(WinLinkParserTest, Manifestuac_UiAccess) { - EXPECT_TRUE(parse("link.exe", "/manifestuac:uiAccess='true'", "a.out", nullptr)); - EXPECT_EQ("'asInvoker'", _ctx.getManifestLevel()); - EXPECT_EQ("'true'", _ctx.getManifestUiAccess()); -} - -TEST_F(WinLinkParserTest, Manifestuac_LevelAndUiAccess) { - EXPECT_TRUE(parse("link.exe", - "/manifestuac:level='requireAdministrator' uiAccess='true'", - "a.out", nullptr)); - EXPECT_EQ("'requireAdministrator'", _ctx.getManifestLevel()); - EXPECT_EQ("'true'", _ctx.getManifestUiAccess()); -} - -TEST_F(WinLinkParserTest, Manifestfile) { - EXPECT_TRUE(parse("link.exe", "/manifestfile:bar.manifest", - "a.out", nullptr)); - EXPECT_EQ("bar.manifest", _ctx.getManifestOutputPath()); -} - -TEST_F(WinLinkParserTest, Manifestdependency) { - EXPECT_TRUE(parse("link.exe", "/manifestdependency:foo bar", "a.out", - nullptr)); - EXPECT_EQ("foo bar", _ctx.getManifestDependency()); -} - -// -// Test for /OPT -// - -TEST_F(WinLinkParserTest, OptNoRef) { - EXPECT_TRUE(parse("link.exe", "/opt:noref", "a.obj", nullptr)); - EXPECT_FALSE(_ctx.deadStrip()); -} - -TEST_F(WinLinkParserTest, OptIgnore) { - EXPECT_TRUE(parse("link.exe", "/opt:ref", "/opt:icf", "/opt:noicf", - "/opt:icf=foo", "/opt:lbr", "/opt:nolbr", "a.obj", - nullptr)); -} - -TEST_F(WinLinkParserTest, OptUnknown) { - EXPECT_FALSE(parse("link.exe", "/opt:foo", "a.obj", nullptr)); -} - -// -// Test for /PROFILE -// - -TEST_F(WinLinkParserTest, Profile) { - EXPECT_TRUE(parse("link.exe", "/profile", "a.obj", nullptr)); - EXPECT_TRUE(_ctx.deadStrip()); - EXPECT_TRUE(_ctx.getBaseRelocationEnabled()); - EXPECT_TRUE(_ctx.getDynamicBaseEnabled()); -} - -// -// Test for command line flags that are ignored. -// - -TEST_F(WinLinkParserTest, Ignore) { - // There are some no-op command line options that are recognized for - // compatibility with link.exe. - EXPECT_TRUE(parse("link.exe", "/nologo", "/errorreport:prompt", - "/incremental", "/incremental:no", "/delay:unload", - "/disallowlib:foo", "/pdbaltpath:bar", - "/wx", "/wx:no", "/tlbid:1", "/tlbout:foo", "/idlout:foo", - "/ignore:4000", "/ignoreidl", "/implib:foo", "/safeseh", - "/safeseh:no", "/functionpadmin", "/maxilksize:1024", - "a.obj", nullptr)); - EXPECT_EQ("", errorMessage()); - EXPECT_EQ(2, inputFileCount()); - EXPECT_EQ("a.obj", inputFile(0)); -} - -// -// Test for "--" -// - -TEST_F(WinLinkParserTest, DashDash) { - EXPECT_TRUE(parse("link.exe", "/subsystem:console", "/out:a.exe", "a.obj", - "--", "b.obj", "-c.obj", nullptr)); - EXPECT_EQ(llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI, _ctx.getSubsystem()); - EXPECT_EQ("a.exe", _ctx.outputPath()); - EXPECT_EQ(4, inputFileCount()); - EXPECT_EQ("a.obj", inputFile(0)); - EXPECT_EQ("b.obj", inputFile(1)); - EXPECT_EQ("-c.obj", inputFile(2)); -} Index: unittests/DriverTests/WinLinkModuleDefTest.cpp =================================================================== --- unittests/DriverTests/WinLinkModuleDefTest.cpp +++ /dev/null @@ -1,155 +0,0 @@ -//===- lld/unittest/WinLinkModuleDefTest.cpp ------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "gtest/gtest.h" -#include "lld/Driver/WinLinkModuleDef.h" -#include "llvm/Support/MemoryBuffer.h" -#include - -using namespace llvm; -using namespace lld; - -class ParserTest : public testing::Test { -protected: - std::vector _dirs; - - void parse(const char *contents) { - auto membuf = - std::unique_ptr(MemoryBuffer::getMemBuffer(contents)); - moduledef::Lexer lexer(std::move(membuf)); - moduledef::Parser parser(lexer, _alloc); - EXPECT_TRUE(parser.parse(_dirs)); - EXPECT_TRUE(!_dirs.empty()); - } - - void verifyExportDesc(const PECOFFLinkingContext::ExportDesc &exp, - StringRef sym, int ordinal, bool noname, bool isData) { - EXPECT_EQ(sym, exp.name); - EXPECT_EQ(ordinal, exp.ordinal); - EXPECT_EQ(noname, exp.noname); - EXPECT_EQ(isData, exp.isData); - } - -private: - llvm::BumpPtrAllocator _alloc; -}; - -TEST_F(ParserTest, Exports) { - parse("EXPORTS\n" - " sym1\n" - " sym2 @5\n" - " sym3 @8 NONAME\n" - " sym4 DATA\n" - " sym5 @10 NONAME DATA\n"); - EXPECT_EQ(1U, _dirs.size()); - const std::vector &exports = - cast(_dirs[0])->getExports(); - EXPECT_EQ(5U, exports.size()); - verifyExportDesc(exports[0], "sym1", -1, false, false); - verifyExportDesc(exports[1], "sym2", 5, false, false); - verifyExportDesc(exports[2], "sym3", 8, true, false); - verifyExportDesc(exports[3], "sym4", -1, false, true); - verifyExportDesc(exports[4], "sym5", 10, true, true); -} - -TEST_F(ParserTest, Heapsize) { - parse("HEAPSIZE 65536"); - EXPECT_EQ(1U, _dirs.size()); - auto *heapsize = cast(_dirs[0]); - EXPECT_EQ(65536U, heapsize->getReserve()); - EXPECT_EQ(0U, heapsize->getCommit()); -} - -TEST_F(ParserTest, HeapsizeWithCommit) { - parse("HEAPSIZE 65536, 8192"); - EXPECT_EQ(1U, _dirs.size()); - auto *heapsize = cast(_dirs[0]); - EXPECT_EQ(65536U, heapsize->getReserve()); - EXPECT_EQ(8192U, heapsize->getCommit()); -} - -TEST_F(ParserTest, StacksizeBasic) { - parse("STACKSIZE 65536"); - EXPECT_EQ(1U, _dirs.size()); - auto *stacksize = cast(_dirs[0]); - EXPECT_EQ(65536U, stacksize->getReserve()); - EXPECT_EQ(0U, stacksize->getCommit()); -} - -TEST_F(ParserTest, StacksizeWithCommit) { - parse("STACKSIZE 65536, 8192"); - EXPECT_EQ(1U, _dirs.size()); - auto *stacksize = cast(_dirs[0]); - EXPECT_EQ(65536U, stacksize->getReserve()); - EXPECT_EQ(8192U, stacksize->getCommit()); -} - -TEST_F(ParserTest, Library) { - parse("LIBRARY foo.dll"); - EXPECT_EQ(1U, _dirs.size()); - auto *lib = cast(_dirs[0]); - EXPECT_EQ("foo.dll", lib->getName()); -} - -TEST_F(ParserTest, NameBasic) { - parse("NAME foo.exe"); - EXPECT_EQ(1U, _dirs.size()); - auto *name = cast(_dirs[0]); - EXPECT_EQ("foo.exe", name->getOutputPath()); - EXPECT_EQ(0U, name->getBaseAddress()); -} - -TEST_F(ParserTest, NameWithBase) { - parse("NAME foo.exe BASE=4096"); - EXPECT_EQ(1U, _dirs.size()); - auto *name = cast(_dirs[0]); - EXPECT_EQ("foo.exe", name->getOutputPath()); - EXPECT_EQ(4096U, name->getBaseAddress()); -} - -TEST_F(ParserTest, NameLongFileName) { - parse("NAME \"a long file name.exe\""); - EXPECT_EQ(1U, _dirs.size()); - auto *name = cast(_dirs[0]); - EXPECT_EQ("a long file name.exe", name->getOutputPath()); - EXPECT_EQ(0U, name->getBaseAddress()); -} - -TEST_F(ParserTest, VersionMajor) { - parse("VERSION 12"); - EXPECT_EQ(1U, _dirs.size()); - auto *ver = cast(_dirs[0]); - EXPECT_EQ(12, ver->getMajorVersion()); - EXPECT_EQ(0, ver->getMinorVersion()); -} - -TEST_F(ParserTest, VersionMajorMinor) { - parse("VERSION 12.34"); - EXPECT_EQ(1U, _dirs.size()); - auto *ver = cast(_dirs[0]); - EXPECT_EQ(12, ver->getMajorVersion()); - EXPECT_EQ(34, ver->getMinorVersion()); -} - -TEST_F(ParserTest, Multiple) { - parse("LIBRARY foo\n" - "EXPORTS sym\n" - "VERSION 12"); - EXPECT_EQ(3U, _dirs.size()); - auto *lib = cast(_dirs[0]); - EXPECT_EQ("foo.dll", lib->getName()); - - const std::vector &exports = - cast(_dirs[1])->getExports(); - EXPECT_EQ(1U, exports.size()); - verifyExportDesc(exports[0], "sym", -1, false, false); - - auto *ver = cast(_dirs[2]); - EXPECT_EQ(12, ver->getMajorVersion()); -}