[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