[lld] [LLD][COFF] Adds `/includeglob` flag (PR #109721)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 23 14:56:24 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-platform-windows
@llvm/pr-subscribers-lld
Author: Miguel A. Arroyo (mayanez)
<details>
<summary>Changes</summary>
## Description
* This PR implements parity with the `--undefined-glob` flag on [ELF](https://reviews.llvm.org/D63244), but for COFF.
---
Full diff: https://github.com/llvm/llvm-project/pull/109721.diff
7 Files Affected:
- (modified) lld/COFF/Driver.cpp (+23)
- (modified) lld/COFF/Driver.h (+2)
- (modified) lld/COFF/Options.td (+2)
- (modified) lld/docs/ReleaseNotes.rst (+1)
- (added) lld/test/COFF/Inputs/include1d.yaml (+29)
- (modified) lld/test/COFF/include.test (+54)
- (modified) lld/test/COFF/include2.test (+8-2)
``````````diff
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index f66fe3cab5a2f0..5a6a4a61030e64 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -37,6 +37,7 @@
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/GlobPattern.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Parallel.h"
@@ -704,6 +705,24 @@ Symbol *LinkerDriver::addUndefined(StringRef name) {
return b;
}
+void LinkerDriver::addUndefinedGlob(StringRef arg) {
+ Expected<GlobPattern> pat = GlobPattern::create(arg);
+ if (!pat) {
+ error("/includeglob: " + toString(pat.takeError()));
+ return;
+ }
+
+ SmallVector<Symbol *, 0> syms;
+ ctx.symtab.forEachSymbol([&syms, &pat](Symbol *sym) {
+ if (pat->match(sym->getName())) {
+ syms.push_back(sym);
+ }
+ });
+
+ for (Symbol *sym : syms)
+ addUndefined(sym->getName());
+}
+
StringRef LinkerDriver::mangleMaybe(Symbol *s) {
// If the plain symbol name has already been resolved, do nothing.
Undefined *unmangled = dyn_cast<Undefined>(s);
@@ -2524,6 +2543,10 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
} while (run());
}
+ // Handle /includeglob
+ for (StringRef pat : args::getStrings(args, OPT_incl_glob))
+ addUndefinedGlob(pat);
+
// Create wrapped symbols for -wrap option.
std::vector<WrappedSymbol> wrapped = addWrappedSymbols(ctx, args);
// Load more object files that might be needed for wrapped symbols.
diff --git a/lld/COFF/Driver.h b/lld/COFF/Driver.h
index 0c195a7cc3148c..58a2ed23106243 100644
--- a/lld/COFF/Driver.h
+++ b/lld/COFF/Driver.h
@@ -172,6 +172,8 @@ class LinkerDriver {
Symbol *addUndefined(StringRef sym);
+ void addUndefinedGlob(StringRef arg);
+
StringRef mangleMaybe(Symbol *s);
// Windows specific -- "main" is not the only main function in Windows.
diff --git a/lld/COFF/Options.td b/lld/COFF/Options.td
index 4bc4d7c4b5a477..ef49b659f9a25a 100644
--- a/lld/COFF/Options.td
+++ b/lld/COFF/Options.td
@@ -132,6 +132,8 @@ def manifestinput : P<
// a reserved keyword in tablegen.
def incl : Joined<["/", "-", "/?", "-?"], "include:">,
HelpText<"Force symbol to be added to symbol table as undefined one">;
+def incl_glob : Joined<["/", "-", "/?", "-?"], "includeglob:">,
+ HelpText<"Force symbol to be added to symbol table as undefined one using a glob pattern">;
// "def" is also a keyword.
def deffile : Joined<["/", "-", "/?", "-?"], "def:">,
diff --git a/lld/docs/ReleaseNotes.rst b/lld/docs/ReleaseNotes.rst
index 6d09de10e7195e..6e043773f00379 100644
--- a/lld/docs/ReleaseNotes.rst
+++ b/lld/docs/ReleaseNotes.rst
@@ -41,6 +41,7 @@ Breaking changes
COFF Improvements
-----------------
+* ``/includeglob`` has been implemented to match the behavior of ``--undefined-glob`` available for ELF.
MinGW Improvements
------------------
diff --git a/lld/test/COFF/Inputs/include1d.yaml b/lld/test/COFF/Inputs/include1d.yaml
new file mode 100644
index 00000000000000..d315cc885dd7ce
--- /dev/null
+++ b/lld/test/COFF/Inputs/include1d.yaml
@@ -0,0 +1,29 @@
+--- !COFF
+header:
+ Machine: IMAGE_FILE_MACHINE_AMD64
+ Characteristics: []
+sections:
+ - Name: .text
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 4
+ SectionData: B800000000506800000000680000000050E80000000050E800000000
+symbols:
+ - Name: .text
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 28
+ NumberOfRelocations: 4
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 0
+ - Name: baz
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+...
diff --git a/lld/test/COFF/include.test b/lld/test/COFF/include.test
index 8879ee5bd7a61b..2a8a8fe4034c4a 100644
--- a/lld/test/COFF/include.test
+++ b/lld/test/COFF/include.test
@@ -9,10 +9,18 @@
# RUN: echo dummy >> %t.log
# RUN: FileCheck -check-prefix=CHECK2 %s < %t.log
+# RUN: lld-link /out:%t.exe /entry:main %t.obj /verbose /includeglob:"glob_*" >& %t.log
+# RUN: echo dummy >> %t.log
+# RUN: FileCheck -check-prefix=CHECK3 %s < %t.log
+
# CHECK1: Discarded unused
+# CHECK1: Discarded glob_match1
+# CHECK1: Discarded glob_match2
# CHECK1-NOT: Discarded used
# CHECK2-NOT: Discarded unused
# CHECK2-NOT: Discarded used
+# CHECK3-NOT: Discarded glob_match1
+# CHECK3-NOT: Discarded glob_match2
--- !COFF
header:
@@ -31,6 +39,14 @@ sections:
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
Alignment: 4
SectionData: B82A000000C3
+ - Name: '.text$mn'
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 4
+ SectionData: B82A000000C3
+ - Name: '.text$mn'
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 4
+ SectionData: B82A000000C3
- Name: .drectve
Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
Alignment: 1
@@ -75,6 +91,32 @@ symbols:
CheckSum: 0
Number: 0
Selection: IMAGE_COMDAT_SELECT_ANY
+ - Name: '.text$mn'
+ Value: 0
+ SectionNumber: 4
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 6
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 0
+ Selection: IMAGE_COMDAT_SELECT_ANY
+ - Name: '.text$mn'
+ Value: 0
+ SectionNumber: 5
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 6
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 0
+ Selection: IMAGE_COMDAT_SELECT_ANY
- Name: main
Value: 0
SectionNumber: 1
@@ -93,4 +135,16 @@ symbols:
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: glob_match1
+ Value: 0
+ SectionNumber: 4
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: glob_match2
+ Value: 0
+ SectionNumber: 5
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
...
diff --git a/lld/test/COFF/include2.test b/lld/test/COFF/include2.test
index 557de47d9e1987..4796512fff93fd 100644
--- a/lld/test/COFF/include2.test
+++ b/lld/test/COFF/include2.test
@@ -1,14 +1,20 @@
# RUN: yaml2obj %p/Inputs/include1a.yaml -o %t1.obj
# RUN: yaml2obj %p/Inputs/include1b.yaml -o %t2.obj
# RUN: yaml2obj %p/Inputs/include1c.yaml -o %t3.obj
-# RUN: rm -f %t2.lib %t3.lib
+# RUN: yaml2obj %p/Inputs/include1d.yaml -o %t4.obj
+# RUN: rm -f %t2.lib %t3.lib %t4.lib
# RUN: llvm-ar cru %t2.lib %t2.obj
# RUN: llvm-ar cru %t3.lib %t3.obj
-# RUN: lld-link /out:%t.exe /entry:main %t1.obj %t2.lib %t3.lib /verbose >& %t.log
+# RUN: llvm-ar cru %t4.lib %t4.obj
+# RUN: lld-link /out:%t.exe /entry:main %t1.obj %t2.lib %t3.lib %t4.lib /verbose >& %t.log
# RUN: FileCheck %s < %t.log
+# RUN: lld-link /out:%t.exe /entry:main %t1.obj %t2.lib %t3.lib %t4.lib /includeglob:baz /verbose >& %t.glob.log
+# RUN: FileCheck -check-prefix=GLOB %s < %t.glob.log
CHECK: include2.test.tmp1.obj
CHECK: include2.test.tmp2.lib
CHECK: include2.test.tmp2.lib(include2.test.tmp2.obj) for foo
CHECK: include2.test.tmp3.lib
CHECK: include2.test.tmp3.lib(include2.test.tmp3.obj) for bar
+CHECK-NOT: include2.test.tmp4.lib(include2.test.tmp4.obj) for baz
+GLOB: include2.test.tmp4.lib(include2.test.tmp4.obj) for baz
``````````
</details>
https://github.com/llvm/llvm-project/pull/109721
More information about the llvm-commits
mailing list