summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2015-01-28 18:38:50 +0000
committerRui Ueyama <ruiu@google.com>2015-01-28 18:38:50 +0000
commit0b55151d3e191cebe5083ba1e587f5c53c32d918 (patch)
tree838a35065742ca86f06bc6c7d48a61ce7e9e70d5
parentd558ffaf69e252c22415e4f622cc3ab5d8373266 (diff)
downloadbcm5719-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.h6
-rw-r--r--lld/lib/Driver/GnuLdDriver.cpp34
-rw-r--r--lld/unittests/DriverTests/GnuLdDriverTest.cpp19
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());
+}
OpenPOWER on IntegriCloud