summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMeador Inge <meadori@codesourcery.com>2015-03-12 21:55:55 +0000
committerMeador Inge <meadori@codesourcery.com>2015-03-12 21:55:55 +0000
commit28dac858cddabfbfd488f993be1481c5d601e699 (patch)
tree1762e3f875cde630bb2ecb533dcb6b8dc8b63e71
parent748a71b8de2f632f813dc328b94570a2916094e7 (diff)
downloadbcm5719-llvm-28dac858cddabfbfd488f993be1481c5d601e699.tar.gz
bcm5719-llvm-28dac858cddabfbfd488f993be1481c5d601e699.zip
LinkerScript: Add evaluation of the EXTERN command
This patch implements evaluation of the GNU ld EXTERN command. llvm-svn: 232111
-rw-r--r--lld/include/lld/ReaderWriter/LinkerScript.h4
-rw-r--r--lld/lib/Driver/GnuLdDriver.cpp5
-rw-r--r--lld/test/elf/linkerscript/Inputs/externs.ls3
-rw-r--r--lld/test/elf/linkerscript/externs.objtxt21
4 files changed, 33 insertions, 0 deletions
diff --git a/lld/include/lld/ReaderWriter/LinkerScript.h b/lld/include/lld/ReaderWriter/LinkerScript.h
index 5c74ae1d3f1..e4a8bf50f0b 100644
--- a/lld/include/lld/ReaderWriter/LinkerScript.h
+++ b/lld/include/lld/ReaderWriter/LinkerScript.h
@@ -846,6 +846,8 @@ private:
/// Represents an extern command.
class Extern : public Command {
public:
+ typedef llvm::ArrayRef<StringRef>::const_iterator const_iterator;
+
Extern(Parser &ctx,
const SmallVectorImpl<StringRef> &symbols)
: Command(ctx, Kind::Extern) {
@@ -861,6 +863,8 @@ public:
}
void dump(raw_ostream &os) const override;
+ const_iterator begin() const { return _symbols.begin(); }
+ const_iterator end() const { return _symbols.end(); }
private:
llvm::ArrayRef<StringRef> _symbols;
diff --git a/lld/lib/Driver/GnuLdDriver.cpp b/lld/lib/Driver/GnuLdDriver.cpp
index 48ec24a9a90..c20e1081c7a 100644
--- a/lld/lib/Driver/GnuLdDriver.cpp
+++ b/lld/lib/Driver/GnuLdDriver.cpp
@@ -308,6 +308,11 @@ std::error_code GnuLdDriver::evalLinkerScript(ELFLinkingContext &ctx,
ctx.setEntrySymbolName(entry->getEntryName());
if (auto *output = dyn_cast<script::Output>(c))
ctx.setOutputPath(output->getOutputFileName());
+ if (auto *externs = dyn_cast<script::Extern>(c)) {
+ for (auto symbol : *externs) {
+ ctx.addInitialUndefinedSymbol(symbol);
+ }
+ }
}
// Transfer ownership of the script to the linking context
ctx.addLinkerScript(std::move(parser));
diff --git a/lld/test/elf/linkerscript/Inputs/externs.ls b/lld/test/elf/linkerscript/Inputs/externs.ls
new file mode 100644
index 00000000000..20fdc0c3f98
--- /dev/null
+++ b/lld/test/elf/linkerscript/Inputs/externs.ls
@@ -0,0 +1,3 @@
+/* A simple valid linker script used for testing the EXTERN command.
+ */
+EXTERN(_foo bar __baz)
diff --git a/lld/test/elf/linkerscript/externs.objtxt b/lld/test/elf/linkerscript/externs.objtxt
new file mode 100644
index 00000000000..154891eaf71
--- /dev/null
+++ b/lld/test/elf/linkerscript/externs.objtxt
@@ -0,0 +1,21 @@
+# Check symbols defined with the EXTERN command are added as undefined
+# symbols.
+
+# RUN: lld -flavor gnu -target x86_64 -T %p/Inputs/externs.ls -r %s \
+# RUN: --output-filetype=yaml | FileCheck %s
+
+defined-atoms:
+ - name: main
+ scope: global
+ content: [ B8, 00, 00, 00, 00, C7, 44, 24, FC, 00, 00, 00, 00, C3 ]
+ alignment: 2^4
+ section-choice: custom-required
+ section-name: .text
+
+# CHECK: undefined-atoms:
+# CHECK: - name: _foo
+# CHECK: can-be-null: at-buildtime
+# CHECK: - name: bar
+# CHECK: can-be-null: at-buildtime
+# CHECK: - name: __baz
+# CHECK: can-be-null: at-buildtime
OpenPOWER on IntegriCloud