[lld] r363396 - Add --undefined-glob which is an --undefined with wildcard pattern match
Rui Ueyama via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 14 07:00:59 PDT 2019
Author: ruiu
Date: Fri Jun 14 07:00:59 2019
New Revision: 363396
URL: http://llvm.org/viewvc/llvm-project?rev=363396&view=rev
Log:
Add --undefined-glob which is an --undefined with wildcard pattern match
This patch adds new command line option `--undefined-glob` to lld.
That option is a variant of `--undefined` but accepts wildcard
patterns so that all symbols that match with a given pattern are
handled as if they were given by `-u`.
`-u foo` is to force resolve symbol foo if foo is not a defined symbol
and there's a static archive that contains a definition of symbol foo.
Now, you can specify a wildcard pattern as an argument for `--undefined-glob`.
So, if you want to include all JNI symbols (which start with "Java_"), you
can do that by passing `--undefined-glob "Java_*"` to the linker, for example.
In this patch, I use the same glob pattern matcher as the version script
processor is using, so it does not only support `*` but also `?` and `[...]`.
Differential Revision: https://reviews.llvm.org/D63244
Added:
lld/trunk/test/ELF/undefined-glob.s
Modified:
lld/trunk/ELF/Driver.cpp
lld/trunk/ELF/Options.td
lld/trunk/docs/ld.lld.1
Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=363396&r1=363395&r2=363396&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Fri Jun 14 07:00:59 2019
@@ -50,6 +50,7 @@
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compression.h"
+#include "llvm/Support/GlobPattern.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/TarWriter.h"
@@ -1319,12 +1320,8 @@ static void excludeLibs(opt::InputArgLis
}
// Force Sym to be entered in the output. Used for -u or equivalent.
-static void handleUndefined(StringRef Name) {
- Symbol *Sym = Symtab->find(Name);
- if (!Sym)
- return;
-
- // Since symbol S may not be used inside the program, LTO may
+static void handleUndefined(Symbol *Sym) {
+ // Since a symbol may not be used inside the program, LTO may
// eliminate it. Mark the symbol as "used" to prevent it.
Sym->IsUsedInRegularObj = true;
@@ -1332,6 +1329,29 @@ static void handleUndefined(StringRef Na
Sym->fetch();
}
+// As an extention to GNU linkers, lld supports a variant of `-u`
+// which accepts wildcard patterns. All symbols that match a given
+// pattern are handled as if they were given by `-u`.
+static void handleUndefinedGlob(StringRef Arg) {
+ Expected<GlobPattern> Pat = GlobPattern::create(Arg);
+ if (!Pat) {
+ error("--undefined-glob: " + toString(Pat.takeError()));
+ return;
+ }
+
+ std::vector<Symbol *> Syms;
+ Symtab->forEachSymbol([&](Symbol *Sym) {
+ // Calling Sym->fetch() from here is not safe because it may
+ // add new symbols to the symbol table, invalidating the
+ // current iterator. So we just keep a note.
+ if (Pat->match(Sym->getName()))
+ Syms.push_back(Sym);
+ });
+
+ for (Symbol *Sym : Syms)
+ handleUndefined(Sym);
+}
+
static void handleLibcall(StringRef Name) {
Symbol *Sym = Symtab->find(Name);
if (!Sym || !Sym->isLazy())
@@ -1698,11 +1718,17 @@ template <class ELFT> void LinkerDriver:
addUndefined(Name);
// Handle the `--undefined <sym>` options.
- for (StringRef S : Config->Undefined)
- handleUndefined(S);
+ for (StringRef Arg : Config->Undefined)
+ if (Symbol *Sym = Symtab->find(Arg))
+ handleUndefined(Sym);
// If an entry symbol is in a static archive, pull out that file now.
- handleUndefined(Config->Entry);
+ if (Symbol *Sym = Symtab->find(Config->Entry))
+ handleUndefined(Sym);
+
+ // Handle the `--undefined-glob <pattern>` options.
+ for (StringRef Pat : args::getStrings(Args, OPT_undefined_glob))
+ handleUndefinedGlob(Pat);
// If any of our inputs are bitcode files, the LTO code generator may create
// references to certain library functions that might not be explicit in the
Modified: lld/trunk/ELF/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=363396&r1=363395&r2=363396&view=diff
==============================================================================
--- lld/trunk/ELF/Options.td (original)
+++ lld/trunk/ELF/Options.td Fri Jun 14 07:00:59 2019
@@ -366,6 +366,9 @@ defm trace_symbol: Eq<"trace-symbol", "T
defm undefined: Eq<"undefined", "Force undefined symbol during linking">,
MetaVarName<"<symbol>">;
+defm undefined_glob: Eq<"undefined-glob", "Force undefined symbol during linking">,
+ MetaVarName<"<pattern>">;
+
defm unresolved_symbols:
Eq<"unresolved-symbols", "Determine how to handle unresolved symbols">;
Modified: lld/trunk/docs/ld.lld.1
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/docs/ld.lld.1?rev=363396&r1=363395&r2=363396&view=diff
==============================================================================
--- lld/trunk/docs/ld.lld.1 (original)
+++ lld/trunk/docs/ld.lld.1 Fri Jun 14 07:00:59 2019
@@ -504,9 +504,23 @@ Print the names of the input files.
Trace references to
.Ar symbol .
.It Fl -undefined Ns = Ns Ar symbol , Fl u Ar symbol
-Force
+If
.Ar symbol
-to be an undefined symbol during linking.
+is not defined after symbol resolution, and there's a static library
+that contains an object file defining the symbol, load the member
+to include the object file in the output file.
+.It Fl -undefined-glob Ns = Ns Ar pattern
+Synonym for
+.Fl -undefined ,
+except that it takes a glob pattern. In a glob pattern,
+.Cm *
+matches zero or more characters,
+.Cm ?
+matches any single character, and
+.Cm [...]
+matches the characters within brackets. All symbols that match
+a given pattern are handled as if they were given as arguments of
+.Fl -undefined .
.It Fl -unresolved-symbols Ns = Ns Ar value
Determine how to handle unresolved symbols.
.It Fl -use-android-relr-tags
Added: lld/trunk/test/ELF/undefined-glob.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/undefined-glob.s?rev=363396&view=auto
==============================================================================
--- lld/trunk/test/ELF/undefined-glob.s (added)
+++ lld/trunk/test/ELF/undefined-glob.s Fri Jun 14 07:00:59 2019
@@ -0,0 +1,58 @@
+# REQUIRES: x86
+
+# RUN: echo '.globl foo1; foo1:' | \
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t1.o
+# RUN: echo '.globl foo2; foo2:' | \
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t2.o
+# RUN: echo '.globl foo32; foo32:' | \
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t3.o
+# RUN: echo '.globl bar; bar:' | \
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t4.o
+# RUN: rm -f %t.a
+# RUN: llvm-ar rcs %t.a %t1.o %t2.o %t3.o %t4.o
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+
+# RUN: ld.lld -o %t.exe %t.o %t.a
+# RUN: llvm-readobj --symbols %t.exe | FileCheck --check-prefix=NO-OPT %s
+
+# NO-OPT-NOT: foo
+# NO-OPT-NOT: bar
+
+# RUN: ld.lld -o %t.exe %t.o %t.a --undefined-glob foo1
+# RUN: llvm-readobj --symbols %t.exe | FileCheck --check-prefix=FOO1 %s
+
+# FOO1: foo1
+# FOO1-NOT: foo2
+
+# RUN: ld.lld -o %t.exe %t.o %t.a --undefined-glob 'foo*'
+# RUN: llvm-readobj --symbols %t.exe | FileCheck --check-prefix=FOO-STAR %s
+
+# FOO-STAR: foo1
+# FOO-STAR: foo2
+# FOO-STAR: foo32
+# FOO-STAR-NOT: bar
+
+# RUN: ld.lld -o %t.exe %t.o %t.a --undefined-glob 'foo?'
+# RUN: llvm-readobj --symbols %t.exe | FileCheck --check-prefix=FOO-Q %s
+
+# FOO-Q: foo1
+# FOO-Q: foo2
+# FOO-Q-NOT: foo32
+# FOO-Q-NOT: bar
+
+# RUN: ld.lld -o %t.exe %t.o %t.a --undefined-glob 'foo[13]*'
+# RUN: llvm-readobj --symbols %t.exe | FileCheck --check-prefix=FOO13 %s
+
+# FOO13: foo1
+# FOO13-NOT: foo2
+# FOO13: foo32
+# FOO13-NOT: bar
+
+# RUN: not ld.lld -o %t.exe %t.o %t.a --undefined-glob '[' 2>&1 | \
+# RUN: FileCheck -check-prefix=BAD-PATTERN %s
+
+# BAD-PATTERN: --undefined-glob: invalid glob pattern: [
+
+.globl _start
+_start:
More information about the llvm-commits
mailing list