[lld] [lld][ELF] Allow implicit wildcard in archive file name (PR #119293)

via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 9 15:51:50 PST 2024


https://github.com/amosher-nvidia created https://github.com/llvm/llvm-project/pull/119293

According to the binutils spec: https://sourceware.org/binutils/docs/ld/Input-Section-Basics.htm

You should be able to specify all files in an archive using this syntax `archivename:` , however, lld currently will only accept `archivename:*` to match all files within an archive.

This patch will, only when necessary, create a copy of the file specification and add an implicit wildcard `*` to the end. It also updates the filename-spec linkerscript test to check for this behavior. 

>From eb7db25b385950255c0a70d54f2fd76e85e4f6e1 Mon Sep 17 00:00:00 2001
From: Avery Mosher <amosher at nvidia.com>
Date: Mon, 9 Dec 2024 23:41:22 +0000
Subject: [PATCH] [lld][ELF] Allow implicit wildcard in archive file name

---
 lld/ELF/LinkerScript.h                    | 13 ++++++++++++-
 lld/test/ELF/linkerscript/filename-spec.s |  2 +-
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h
index 328368fd3b4333..b7e84a1849637d 100644
--- a/lld/ELF/LinkerScript.h
+++ b/lld/ELF/LinkerScript.h
@@ -195,6 +195,7 @@ class SectionPattern {
 
 class InputSectionDescription : public SectionCommand {
   SingleStringMatcher filePat;
+  SmallString<0> implicitArchiveWildcardPat;
 
   // Cache of the most recent input argument and result of matchesFile().
   mutable std::optional<std::pair<const InputFile *, bool>> matchesFileCache;
@@ -203,9 +204,19 @@ class InputSectionDescription : public SectionCommand {
   InputSectionDescription(StringRef filePattern, uint64_t withFlags = 0,
                           uint64_t withoutFlags = 0, StringRef classRef = {})
       : SectionCommand(InputSectionKind), filePat(filePattern),
-        classRef(classRef), withFlags(withFlags), withoutFlags(withoutFlags) {
+        implicitArchiveWildcardPat(), classRef(classRef), withFlags(withFlags),
+        withoutFlags(withoutFlags) {
     assert((filePattern.empty() || classRef.empty()) &&
            "file pattern and class reference are mutually exclusive");
+
+    // Fixes up the input file pattern, adding an implicit wildcard
+    // if the trailing character is an ':' to allow matching entire archives
+    if (!filePattern.empty() && filePattern.back() == ':') {
+      implicitArchiveWildcardPat.reserve(filePattern.size() + 1);
+      implicitArchiveWildcardPat.append(filePattern);
+      implicitArchiveWildcardPat.push_back('*');
+      filePat = SingleStringMatcher(implicitArchiveWildcardPat);
+    }
   }
 
   static bool classof(const SectionCommand *c) {
diff --git a/lld/test/ELF/linkerscript/filename-spec.s b/lld/test/ELF/linkerscript/filename-spec.s
index 4fc4f2f4217528..d91b4a76ca24e2 100644
--- a/lld/test/ELF/linkerscript/filename-spec.s
+++ b/lld/test/ELF/linkerscript/filename-spec.s
@@ -55,7 +55,7 @@
 # RUN: llvm-objdump -s 8 | FileCheck --check-prefix=SECONDFIRST %s
 
 ## Verify matching of archive library names in KEEP.
-# RUN: echo 'SECTIONS{.foo :{ KEEP(*lib2*(.foo)) KEEP(*lib1*(.foo)) }}' > 9.t
+# RUN: echo 'SECTIONS{.foo :{ KEEP(*lib2.a:(.foo)) KEEP(*lib1*(.foo)) }}' > 9.t
 # RUN: ld.lld -o 9 -T 9.t --whole-archive \
 # RUN:   dir1/lib1.a dir2/lib2.a
 # RUN: llvm-objdump -s 9 | FileCheck --check-prefix=SECONDFIRST %s



More information about the llvm-commits mailing list