[lld] r187084 - [PECOFF] Add /include command line option.
Rui Ueyama
ruiu at google.com
Wed Jul 24 15:53:24 PDT 2013
Author: ruiu
Date: Wed Jul 24 17:53:23 2013
New Revision: 187084
URL: http://llvm.org/viewvc/llvm-project?rev=187084&view=rev
Log:
[PECOFF] Add /include command line option.
The /include command line option is equivalent to Unix --undefined
option, which forces the linker to resolve the given symbol name
as if it's an unresolved symbol in one of its input files. This feature
is used to link an additional object file or a shared library that no
input files refer to.
Added:
lld/trunk/test/pecoff/include.test
Modified:
lld/trunk/include/lld/ReaderWriter/PECOFFTargetInfo.h
lld/trunk/lib/Driver/WinLinkDriver.cpp
lld/trunk/lib/Driver/WinLinkOptions.td
lld/trunk/lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp
lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp
Modified: lld/trunk/include/lld/ReaderWriter/PECOFFTargetInfo.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/PECOFFTargetInfo.h?rev=187084&r1=187083&r2=187084&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/PECOFFTargetInfo.h (original)
+++ lld/trunk/include/lld/ReaderWriter/PECOFFTargetInfo.h Wed Jul 24 17:53:23 2013
@@ -46,6 +46,8 @@ public:
virtual void addPasses(PassManager &pm) const;
+ virtual void addImplicitFiles(InputFiles &) const;
+
void appendInputSearchPath(StringRef dirPath) {
_inputSearchPaths.push_back(dirPath);
}
@@ -92,7 +94,7 @@ public:
virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
StringRef allocateString(const StringRef &ref) {
- char *x = _extraStrings.Allocate<char>(ref.size() + 1);
+ char *x = _alloc.Allocate<char>(ref.size() + 1);
memcpy(x, ref.data(), ref.size());
x[ref.size()] = '\0';
return x;
@@ -117,7 +119,7 @@ private:
std::vector<StringRef> _inputSearchPaths;
mutable std::unique_ptr<Reader> _reader;
mutable std::unique_ptr<Writer> _writer;
- llvm::BumpPtrAllocator _extraStrings;
+ mutable llvm::BumpPtrAllocator _alloc;
};
} // end namespace lld
Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=187084&r1=187083&r2=187084&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkDriver.cpp Wed Jul 24 17:53:23 2013
@@ -351,6 +351,10 @@ bool WinLinkDriver::parse(int argc, cons
if (parsedArgs->getLastArg(OPT_no_tsaware))
info.setTerminalServerAware(false);
+ // Handle -include
+ if (llvm::opt::Arg *sym = parsedArgs->getLastArg(OPT_incl))
+ info.addInitialUndefinedSymbol(sym->getValue());
+
// Handle -out
if (llvm::opt::Arg *outpath = parsedArgs->getLastArg(OPT_out))
info.setOutputPath(outpath->getValue());
Modified: lld/trunk/lib/Driver/WinLinkOptions.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkOptions.td?rev=187084&r1=187083&r2=187084&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkOptions.td (original)
+++ lld/trunk/lib/Driver/WinLinkOptions.td Wed Jul 24 17:53:23 2013
@@ -60,5 +60,9 @@ def tsaware : Flag<["-", "/"], "tsaware"
def no_tsaware : Flag<["-", "/"], "tsaware:no">,
HelpText<"Create non-Terminal Server aware executable">;
+def incl : Separate<["-", "/"], "include">,
+ HelpText<"Force symbol to be added to symbol table as undefined one">;
+def incl_c : Joined<["-", "/"], "include:">, Alias<incl>;
+
def help : Flag<["-", "/"], "help">;
def help_q : Flag<["-", "/"], "?">, Alias<help>;
Modified: lld/trunk/lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp?rev=187084&r1=187083&r2=187084&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp Wed Jul 24 17:53:23 2013
@@ -7,15 +7,19 @@
//
//===----------------------------------------------------------------------===//
+#include "Atoms.h"
#include "GroupedSectionsPass.h"
#include "IdataPass.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/Allocator.h"
#include "llvm/Support/Path.h"
+#include "lld/Core/InputFiles.h"
#include "lld/Core/PassManager.h"
#include "lld/Passes/LayoutPass.h"
#include "lld/ReaderWriter/PECOFFTargetInfo.h"
#include "lld/ReaderWriter/Reader.h"
+#include "lld/ReaderWriter/Simple.h"
#include "lld/ReaderWriter/Writer.h"
namespace lld {
@@ -26,6 +30,24 @@ bool containDirectoryName(StringRef path
llvm::sys::path::remove_filename(smallStr);
return !smallStr.str().empty();
}
+
+/// An instance of UndefinedSymbolFile has a list of undefined symbols
+/// specified by "/include" command line option. This will be added to the
+/// input file list to force the core linker to try to resolve the undefined
+/// symbols.
+class UndefinedSymbolFile : public SimpleFile {
+public:
+ UndefinedSymbolFile(const TargetInfo &ti)
+ : SimpleFile(ti, "Linker Internal File") {
+ for (StringRef symbol : ti.initialUndefinedSymbols()) {
+ UndefinedAtom *atom = new (_alloc) coff::COFFUndefinedAtom(*this, symbol);
+ addAtom(*atom);
+ }
+ };
+
+private:
+ llvm::BumpPtrAllocator _alloc;
+};
} // anonymous namespace
error_code PECOFFTargetInfo::parseFile(
@@ -59,6 +81,12 @@ bool PECOFFTargetInfo::validateImpl(raw_
return false;
}
+void PECOFFTargetInfo::addImplicitFiles(InputFiles &files) const {
+ // Add a pseudo file for "/include" linker option.
+ auto *file = new (_alloc) UndefinedSymbolFile(*this);
+ files.prependFile(*file);
+}
+
/// 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) {
Added: lld/trunk/test/pecoff/include.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/include.test?rev=187084&view=auto
==============================================================================
--- lld/trunk/test/pecoff/include.test (added)
+++ lld/trunk/test/pecoff/include.test Wed Jul 24 17:53:23 2013
@@ -0,0 +1,7 @@
+# RUN: yaml2obj %p/Inputs/nop.obj.yaml > %t.obj
+#
+# RUN: not lld -flavor link -out %t1 -subsystem console \
+# RUN: -include nosuchsym -- %t.obj 2> %t1
+# RUN: FileCheck %s < %t1
+
+CHECK: Undefined Symbol: Linker Internal File : nosuchsym
\ No newline at end of file
Modified: lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp?rev=187084&r1=187083&r2=187084&view=diff
==============================================================================
--- lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp (original)
+++ lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp Wed Jul 24 17:53:23 2013
@@ -54,6 +54,7 @@ TEST_F(WinLinkParserTest, Basic) {
EXPECT_FALSE(_info.getLargeAddressAware());
EXPECT_TRUE(_info.getBaseRelocationEnabled());
EXPECT_TRUE(_info.isTerminalServerAware());
+ EXPECT_TRUE(_info.initialUndefinedSymbols().empty());
}
TEST_F(WinLinkParserTest, WindowsStyleOption) {
@@ -172,6 +173,15 @@ TEST_F(WinLinkParserTest, NoTerminalServ
EXPECT_FALSE(_info.isTerminalServerAware());
}
+TEST_F(WinLinkParserTest, Include) {
+ EXPECT_FALSE(parse("link.exe", "-include", "foo", "a.out", nullptr));
+ auto symbols = _info.initialUndefinedSymbols();
+ EXPECT_FALSE(symbols.empty());
+ EXPECT_EQ("foo", symbols[0]);
+ symbols.pop_front();
+ EXPECT_TRUE(symbols.empty());
+}
+
TEST_F(WinLinkParserTest, NoInputFiles) {
EXPECT_TRUE(parse("link.exe", nullptr));
EXPECT_EQ("No input files\n", errorMessage());
More information about the llvm-commits
mailing list