diff options
author | Rui Ueyama <ruiu@google.com> | 2015-01-28 18:38:50 +0000 |
---|---|---|
committer | Rui Ueyama <ruiu@google.com> | 2015-01-28 18:38:50 +0000 |
commit | 0b55151d3e191cebe5083ba1e587f5c53c32d918 (patch) | |
tree | 838a35065742ca86f06bc6c7d48a61ce7e9e70d5 | |
parent | d558ffaf69e252c22415e4f622cc3ab5d8373266 (diff) | |
download | bcm5719-llvm-0b55151d3e191cebe5083ba1e587f5c53c32d918.tar.gz bcm5719-llvm-0b55151d3e191cebe5083ba1e587f5c53c32d918.zip |
Add a unit test for LinkerScript.
llvm-svn: 227341
-rw-r--r-- | lld/include/lld/Driver/Driver.h | 6 | ||||
-rw-r--r-- | lld/lib/Driver/GnuLdDriver.cpp | 34 | ||||
-rw-r--r-- | lld/unittests/DriverTests/GnuLdDriverTest.cpp | 19 |
3 files changed, 46 insertions, 13 deletions
diff --git a/lld/include/lld/Driver/Driver.h b/lld/include/lld/Driver/Driver.h index b42ea3ad333..1875ab23b82 100644 --- a/lld/include/lld/Driver/Driver.h +++ b/lld/include/lld/Driver/Driver.h @@ -76,6 +76,12 @@ public: std::unique_ptr<ELFLinkingContext> &context, raw_ostream &diagnostics = llvm::errs()); + /// Parses a given memory buffer as a linker script and evaluate that. + /// Public function for testing. + static std::error_code evalLinkerScript(ELFLinkingContext &ctx, + std::unique_ptr<MemoryBuffer> mb, + raw_ostream &diag); + private: static llvm::Triple getDefaultTarget(const char *progName); static bool applyEmulation(llvm::Triple &triple, diff --git a/lld/lib/Driver/GnuLdDriver.cpp b/lld/lib/Driver/GnuLdDriver.cpp index 6b68f9cfe80..244438470c9 100644 --- a/lld/lib/Driver/GnuLdDriver.cpp +++ b/lld/lib/Driver/GnuLdDriver.cpp @@ -249,9 +249,12 @@ evaluateLinkerScriptGroup(ELFLinkingContext &ctx, StringRef path, for (const script::Path &path : group->getPaths()) { ErrorOr<StringRef> pathOrErr = path._isDashlPrefix ? ctx.searchLibrary(path._path) : ctx.searchFile(path._path, sysroot); - if (std::error_code ec = pathOrErr.getError()) - return make_dynamic_error_code( - Twine("Unable to find file ") + path._path + ": " + ec.message()); + if (std::error_code ec = pathOrErr.getError()) { + auto file = llvm::make_unique<ErrorFile>(path._path, ec); + ctx.getNodes().push_back(llvm::make_unique<FileNode>(std::move(file))); + ++numfiles; + continue; + } std::vector<std::unique_ptr<File>> files = loadFile(ctx, pathOrErr.get(), false); @@ -266,20 +269,17 @@ evaluateLinkerScriptGroup(ELFLinkingContext &ctx, StringRef path, return std::error_code(); } -static std::error_code -evaluateLinkerScript(ELFLinkingContext &ctx, StringRef path, - raw_ostream &diag) { +std::error_code +GnuLdDriver::evalLinkerScript(ELFLinkingContext &ctx, + std::unique_ptr<MemoryBuffer> mb, + raw_ostream &diag) { // Read the script file from disk and parse. - ErrorOr<std::unique_ptr<MemoryBuffer>> mb = - MemoryBuffer::getFileOrSTDIN(path); - if (std::error_code ec = mb.getError()) - return ec; - auto lexer = llvm::make_unique<script::Lexer>(std::move(mb.get())); + StringRef path = mb->getBufferIdentifier(); + auto lexer = llvm::make_unique<script::Lexer>(std::move(mb)); auto parser = llvm::make_unique<script::Parser>(*lexer); script::LinkerScript *script = parser->parse(); if (!script) return LinkerScriptReaderError::parse_error; - // Evaluate script commands. // Currently we only recognize GROUP() command. for (const script::Command *c : script->_commands) @@ -623,7 +623,15 @@ bool GnuLdDriver::parse(int argc, const char *argv[], if (isScript) { if (ctx->logInputFiles()) diagnostics << path << "\n"; - std::error_code ec = evaluateLinkerScript(*ctx, realpath, diagnostics); + ErrorOr<std::unique_ptr<MemoryBuffer>> mb = + MemoryBuffer::getFileOrSTDIN(path); + if (std::error_code ec = mb.getError()) { + diagnostics << "Cannot open " << path << ": " + << ec.message() << "\n"; + return false; + } + std::error_code ec = evalLinkerScript(*ctx, std::move(mb.get()), + diagnostics); if (ec) { diagnostics << path << ": Error parsing linker script: " << ec.message() << "\n"; diff --git a/lld/unittests/DriverTests/GnuLdDriverTest.cpp b/lld/unittests/DriverTests/GnuLdDriverTest.cpp index a1445ab95b7..b5a819cf916 100644 --- a/lld/unittests/DriverTests/GnuLdDriverTest.cpp +++ b/lld/unittests/DriverTests/GnuLdDriverTest.cpp @@ -14,6 +14,7 @@ #include "DriverTest.h" #include "lld/ReaderWriter/ELFLinkingContext.h" +#include "llvm/Support/MemoryBuffer.h" using namespace llvm; using namespace lld; @@ -145,3 +146,21 @@ TEST_F(GnuLdParserTest, DefsymMisssingSymbol) { TEST_F(GnuLdParserTest, DefsymMisssingValue) { EXPECT_FALSE(parse("ld", "a.o", "--defsym=sym=", nullptr)); } + +// Linker script + +TEST_F(GnuLdParserTest, LinkerScriptGroup) { + parse("ld", "a.o", nullptr); + std::unique_ptr<MemoryBuffer> mb = MemoryBuffer::getMemBuffer( + "GROUP(/x /y)", "foo.so"); + std::string s; + raw_string_ostream out(s); + std::error_code ec = GnuLdDriver::evalLinkerScript( + *_context, std::move(mb), out); + EXPECT_FALSE(ec); + std::vector<std::unique_ptr<Node>> &nodes = _context->getNodes(); + EXPECT_EQ((size_t)4, nodes.size()); + EXPECT_EQ("/x", cast<FileNode>(nodes[1].get())->getFile()->path()); + EXPECT_EQ("/y", cast<FileNode>(nodes[2].get())->getFile()->path()); + EXPECT_EQ(2, cast<GroupEnd>(nodes[3].get())->getSize()); +} |