diff options
| -rw-r--r-- | lld/include/lld/ReaderWriter/PECOFFTargetInfo.h | 3 | ||||
| -rw-r--r-- | lld/lib/Driver/WinLinkDriver.cpp | 13 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp | 51 | ||||
| -rw-r--r-- | lld/test/pecoff/importlib.test | 3 |
4 files changed, 60 insertions, 10 deletions
diff --git a/lld/include/lld/ReaderWriter/PECOFFTargetInfo.h b/lld/include/lld/ReaderWriter/PECOFFTargetInfo.h index 9d2f57b7d53..a4edb4671c2 100644 --- a/lld/include/lld/ReaderWriter/PECOFFTargetInfo.h +++ b/lld/include/lld/ReaderWriter/PECOFFTargetInfo.h @@ -53,6 +53,9 @@ public: return _inputSearchPaths; } + bool appendInputFileOrLibrary(std::string path); + bool appendLibraryFile(StringRef path); + void setStackReserve(uint64_t size) { _stackReserve = size; } void setStackCommit(uint64_t size) { _stackCommit = size; } uint64_t getStackReserve() const { return _stackReserve; } diff --git a/lld/lib/Driver/WinLinkDriver.cpp b/lld/lib/Driver/WinLinkDriver.cpp index d1e51f95706..8c909d848be 100644 --- a/lld/lib/Driver/WinLinkDriver.cpp +++ b/lld/lib/Driver/WinLinkDriver.cpp @@ -167,13 +167,6 @@ bool parseSubsystemOption(PECOFFTargetInfo &info, std::string arg, return true; } -// Add ".obj" extension if the given path name has no file extension. -StringRef canonicalizeInputFileName(PECOFFTargetInfo &info, std::string path) { - if (llvm::sys::path::extension(path).empty()) - path.append(".obj"); - return info.allocateString(path); -} - // Replace a file extension with ".exe". If the given file has no // extension, just add ".exe". StringRef getDefaultOutputFileName(PECOFFTargetInfo &info, StringRef path) { @@ -290,12 +283,12 @@ bool WinLinkDriver::parse(int argc, const char *argv[], for (int i = doubleDashPosition + 1; i < argc; ++i) inputPaths.push_back(argv[i]); - // Add ".obj" extension for those who have no file extension. for (const StringRef &path : inputPaths) - info.appendInputFile(canonicalizeInputFileName(info, path)); + info.appendInputFileOrLibrary(path); // If -out option was not specified, the default output file name is - // constructed by replacing an extension with ".exe". + // constructed by replacing an extension of the first input file + // with ".exe". if (info.outputPath().empty() && !inputPaths.empty()) info.setOutputPath(getDefaultOutputFileName(info, inputPaths[0])); diff --git a/lld/lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp b/lld/lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp index 4b182346d8a..8c2352319ec 100644 --- a/lld/lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp +++ b/lld/lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp @@ -10,6 +10,8 @@ #include "GroupedSectionsPass.h" #include "IdataPass.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/Path.h" #include "lld/Core/PassManager.h" #include "lld/Passes/LayoutPass.h" #include "lld/ReaderWriter/PECOFFTargetInfo.h" @@ -18,6 +20,14 @@ namespace lld { +namespace { +bool containDirectoryName(StringRef path) { + SmallString<128> smallStr = StringRef(path); + llvm::sys::path::remove_filename(smallStr); + return !smallStr.str().empty(); +} +} // anonymous namespace + error_code PECOFFTargetInfo::parseFile( std::unique_ptr<MemoryBuffer> &mb, std::vector<std::unique_ptr<File>> &result) const { @@ -44,6 +54,47 @@ bool PECOFFTargetInfo::validateImpl(raw_ostream &diagnostics) { return false; } +/// Append the given file to the input file list. The file must be an object +/// file or an import library file. +bool PECOFFTargetInfo::appendInputFileOrLibrary(std::string path) { + StringRef ext = llvm::sys::path::extension(path).lower(); + // This is an import library file. Look for the library file in the search + // paths, unless the path contains a directory name. + if (ext == ".lib") { + if (containDirectoryName(path)) { + appendInputFile(path); + return true; + } + return appendLibraryFile(path); + } + // This is an object file otherwise. Add ".obj" extension if the given path + // name has no file extension. + if (ext.empty()) + path.append(".obj"); + appendInputFile(allocateString(path)); + 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. +bool PECOFFTargetInfo::appendLibraryFile(StringRef filename) { + // Current directory always takes precedence over the search paths. + if (llvm::sys::fs::exists(filename)) { + appendInputFile(filename); + return true; + } + // 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())) { + appendInputFile(allocateString(path.str())); + return true; + } + } + return false; +} + Writer &PECOFFTargetInfo::writer() const { return *_writer; } diff --git a/lld/test/pecoff/importlib.test b/lld/test/pecoff/importlib.test index 62f5f3693d2..41bdbedb403 100644 --- a/lld/test/pecoff/importlib.test +++ b/lld/test/pecoff/importlib.test @@ -5,6 +5,9 @@ # # RUN: lld -flavor link -out %t1 -subsystem console -- %t.obj \ # RUN: %p/Inputs/vars.lib && llvm-objdump -d %t1 | FileCheck %s +# +# RUN: lld -flavor link -out %t1 -subsystem console -libpath %p/Inputs \ +# RUN: -- %t.obj vars.lib && llvm-objdump -d %t1 | FileCheck %s CHECK: Disassembly of section .text: CHECK: .text: |

