aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Rimar <grimar@accesssoftek.com>2015-10-19 17:35:12 +0000
committerGeorge Rimar <grimar@accesssoftek.com>2015-10-19 17:35:12 +0000
commit83f406cff501a79f0aad0790b9850d38bb815ddb (patch)
tree128f9c256689d957386c28f8b1342f0c97da97f1
parent2adc80107a03b4e589b7ee46cdf5617b678fdc11 (diff)
downloadllvm-83f406cff501a79f0aad0790b9850d38bb815ddb.zip
llvm-83f406cff501a79f0aad0790b9850d38bb815ddb.tar.gz
llvm-83f406cff501a79f0aad0790b9850d38bb815ddb.tar.bz2
[ELF2] - Linker script EXTERN command implemented.
The reason of collecting all undefines in vector is that during reading files we already need to have Symtab created. Or like was done in that patch - to put undefines from scripts somewhere to delay Symtab.addUndefinedOpt() call. Differential Revision: http://reviews.llvm.org/D13870 llvm-svn: 250711
-rw-r--r--lld/ELF/Config.h1
-rw-r--r--lld/ELF/Driver.cpp7
-rw-r--r--lld/ELF/LinkerScript.cpp13
-rw-r--r--lld/test/elf2/linkerscript.s4
-rw-r--r--lld/test/elf2/undefined-opt.s4
5 files changed, 27 insertions, 2 deletions
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 8028a6e..59b41ad 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -42,6 +42,7 @@ struct Configuration {
llvm::StringRef Sysroot;
std::string RPath;
std::vector<llvm::StringRef> SearchPaths;
+ std::vector<llvm::StringRef> Undefined;
bool AllowMultipleDefinition;
bool AsNeeded = false;
bool Bsymbolic;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 2d7d75c..19639ef 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -155,6 +155,9 @@ void LinkerDriver::createFiles(opt::InputArgList &Args) {
Config->SoName = getString(Args, OPT_soname);
Config->Sysroot = getString(Args, OPT_sysroot);
+ for (auto *Arg : Args.filtered(OPT_undefined))
+ Config->Undefined.push_back(Arg->getValue());
+
for (auto *Arg : Args.filtered(OPT_z))
if (Arg->getValue() == StringRef("now"))
Config->ZNow = true;
@@ -225,8 +228,8 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
for (std::unique_ptr<InputFile> &F : Files)
Symtab.addFile(std::move(F));
- for (auto *Arg : Args.filtered(OPT_undefined))
- Symtab.addUndefinedOpt(Arg->getValue());
+ for (auto &U : Config->Undefined)
+ Symtab.addUndefinedOpt(U);
if (Config->OutputFile.empty())
Config->OutputFile = "a.out";
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 2a63be4..1607247 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -43,6 +43,7 @@ private:
void readAsNeeded();
void readEntry();
+ void readExtern();
void readGroup();
void readInclude();
void readOutput();
@@ -63,6 +64,8 @@ void LinkerScript::run() {
continue;
if (Tok == "ENTRY") {
readEntry();
+ } else if (Tok == "EXTERN") {
+ readExtern();
} else if (Tok == "GROUP" || Tok == "INPUT") {
readGroup();
} else if (Tok == "INCLUDE") {
@@ -181,6 +184,16 @@ void LinkerScript::readEntry() {
expect(")");
}
+void LinkerScript::readExtern() {
+ expect("(");
+ for (;;) {
+ StringRef Tok = next();
+ if (Tok == ")")
+ return;
+ Config->Undefined.push_back(Tok);
+ }
+}
+
void LinkerScript::readGroup() {
expect("(");
for (;;) {
diff --git a/lld/test/elf2/linkerscript.s b/lld/test/elf2/linkerscript.s
index 67d580d..0a45cec 100644
--- a/lld/test/elf2/linkerscript.s
+++ b/lld/test/elf2/linkerscript.s
@@ -6,6 +6,10 @@
# RUN: rm -f %t.dir/libxyz.a
# RUN: llvm-ar rcs %t.dir/libxyz.a %t2.o
+# RUN: echo "EXTERN( undef undef2 )" > %t.script
+# RUN: ld.lld2 %t -o %t2 %t.script
+# RUN: llvm-readobj %t2 > /dev/null
+
# RUN: echo "GROUP(" %t ")" > %t.script
# RUN: ld.lld2 -o %t2 %t.script
# RUN: llvm-readobj %t2 > /dev/null
diff --git a/lld/test/elf2/undefined-opt.s b/lld/test/elf2/undefined-opt.s
index 14e5d87..b986f89 100644
--- a/lld/test/elf2/undefined-opt.s
+++ b/lld/test/elf2/undefined-opt.s
@@ -37,6 +37,10 @@
# TWO-UNDEFINED: Name: bar
# TWO-UNDEFINED: Name: zed
# TWO-UNDEFINED: ]
+# Now the same logic but linker script is used to set undefines
+# RUN: echo "EXTERN( bar abs )" > %t.script
+# RUN: ld.lld2 -o %t3 %t.o %tar.a %t.script
+# RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TWO-UNDEFINED %s
# Added undefined symbol may be left undefined without error, but
# shouldn't show up in the dynamic table.