[lld] [LLD][COFF] Adds `/includeglob` flag (PR #109721)

Miguel A. Arroyo via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 23 14:55:52 PDT 2024


https://github.com/mayanez created https://github.com/llvm/llvm-project/pull/109721

## Description

* This PR implements parity with the `--undefined-glob` flag on [ELF](https://reviews.llvm.org/D63244), but for COFF.

>From 5fbedb71dd70e778890ac22c3e9d9497541078ef Mon Sep 17 00:00:00 2001
From: Miguel Arroyo <miguel.arroyo at rockstargames.com>
Date: Mon, 23 Sep 2024 14:48:44 -0700
Subject: [PATCH] [LLD][COFF] Adds /includeglob flag

---
 lld/COFF/Driver.cpp                 | 23 ++++++++++++
 lld/COFF/Driver.h                   |  2 ++
 lld/COFF/Options.td                 |  2 ++
 lld/docs/ReleaseNotes.rst           |  1 +
 lld/test/COFF/Inputs/include1d.yaml | 29 ++++++++++++++++
 lld/test/COFF/include.test          | 54 +++++++++++++++++++++++++++++
 lld/test/COFF/include2.test         | 10 ++++--
 7 files changed, 119 insertions(+), 2 deletions(-)
 create mode 100644 lld/test/COFF/Inputs/include1d.yaml

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



More information about the llvm-commits mailing list