diff options
Diffstat (limited to 'lld')
| -rw-r--r-- | lld/ELF/Config.h | 1 | ||||
| -rw-r--r-- | lld/ELF/Driver.cpp | 7 | ||||
| -rw-r--r-- | lld/ELF/LinkerScript.cpp | 13 | ||||
| -rw-r--r-- | lld/test/elf2/linkerscript.s | 4 | ||||
| -rw-r--r-- | lld/test/elf2/undefined-opt.s | 4 |
5 files changed, 27 insertions, 2 deletions
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 8028a6e3e44..59b41ad5648 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 2d7d75ce39a..19639efe170 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 2a63be4ca5d..1607247aa98 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 67d580d06a3..0a45cec7d64 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 14e5d879c25..b986f89f8f2 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. |

