[lld] [lld][ELF] Enable link script to support absolute path matching (PR #156353)

via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 22 02:24:02 PDT 2025


https://github.com/mykouHW updated https://github.com/llvm/llvm-project/pull/156353

>From 21474f0df8585188f67189a514bf8bf7e317a46f Mon Sep 17 00:00:00 2001
From: koumeiyuan <koumeiyuan at huawei.com>
Date: Mon, 25 Aug 2025 17:34:40 +0000
Subject: [PATCH] [lld][ELF] Enable link script to support absolute path
 matching

Fixing the compatibility issue with filename matching in linker scripts. When input files use absolute paths, the matching results from lld do not meet expectations.
---
 lld/ELF/LinkerScript.cpp                   | 23 ++++++---
 lld/ELF/LinkerScript.h                     |  2 +-
 lld/test/ELF/linkerscript/abs-path-match.s | 57 ++++++++++++++++++++++
 3 files changed, 74 insertions(+), 8 deletions(-)
 create mode 100644 lld/test/ELF/linkerscript/abs-path-match.s

diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 921128dae2bdb..0b2fa5cb6d35a 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -27,6 +27,7 @@
 #include "llvm/BinaryFormat/ELF.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/TimeProfiler.h"
 #include <algorithm>
 #include <cassert>
@@ -411,7 +412,8 @@ void LinkerScript::assignSymbol(SymbolAssignment *cmd, bool inSec) {
   cmd->sym->type = v.type;
 }
 
-bool InputSectionDescription::matchesFile(const InputFile &file) const {
+bool InputSectionDescription::matchesFile(const InputFile &file,
+                                          bool ExtractFlag) const {
   if (filePat.isTrivialMatchAll())
     return true;
 
@@ -419,10 +421,17 @@ bool InputSectionDescription::matchesFile(const InputFile &file) const {
     if (matchType == MatchType::WholeArchive) {
       matchesFileCache.emplace(&file, filePat.match(file.archiveName));
     } else {
-      if (matchType == MatchType::ArchivesExcluded && !file.archiveName.empty())
+      if (matchType == MatchType::ArchivesExcluded &&
+          !file.archiveName.empty()) {
         matchesFileCache.emplace(&file, false);
-      else
-        matchesFileCache.emplace(&file, filePat.match(file.getNameForScript()));
+      } else {
+        bool MatchFilename = filePat.match(file.getNameForScript());
+        StringRef Filename = llvm::sys::path::filename(file.getNameForScript());
+        // only use for computeInputSections
+        if (ExtractFlag)
+          MatchFilename = MatchFilename || filePat.match(Filename);
+        matchesFileCache.emplace(&file, MatchFilename);
+      }
     }
   }
 
@@ -442,7 +451,7 @@ bool SectionPattern::excludesFile(const InputFile &file) const {
 
 bool LinkerScript::shouldKeep(InputSectionBase *s) {
   for (InputSectionDescription *id : keptSections)
-    if (id->matchesFile(*s->file))
+    if (id->matchesFile(*s->file, false))
       for (SectionPattern &p : id->sectionPatterns)
         if (p.sectionPat.match(s->name) &&
             (s->flags & id->withFlags) == id->withFlags &&
@@ -571,8 +580,8 @@ LinkerScript::computeInputSections(const InputSectionDescription *cmd,
         if (!pat.sectionPat.match(sec->name))
           continue;
 
-        if (!cmd->matchesFile(*sec->file) || pat.excludesFile(*sec->file) ||
-            !flagsMatch(sec))
+        if (!cmd->matchesFile(*sec->file, true) ||
+            pat.excludesFile(*sec->file) || !flagsMatch(sec))
           continue;
 
         if (sec->parent) {
diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h
index 80c4f564afabc..452cfbcd9b777 100644
--- a/lld/ELF/LinkerScript.h
+++ b/lld/ELF/LinkerScript.h
@@ -227,7 +227,7 @@ class InputSectionDescription : public SectionCommand {
     return c->kind == InputSectionKind;
   }
 
-  bool matchesFile(const InputFile &file) const;
+  bool matchesFile(const InputFile &file, bool ExtractFilename) const;
 
   // Input sections that matches at least one of SectionPatterns
   // will be associated with this InputSectionDescription.
diff --git a/lld/test/ELF/linkerscript/abs-path-match.s b/lld/test/ELF/linkerscript/abs-path-match.s
new file mode 100644
index 0000000000000..1d87b4ee50c73
--- /dev/null
+++ b/lld/test/ELF/linkerscript/abs-path-match.s
@@ -0,0 +1,57 @@
+# REQUIRES: x86
+# RUN: rm -rf %t && mkdir -p %t
+# RUN: split-file %s %t && cd %t
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64 main.s -o main.o
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64 foo.s -o foo.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64 bar.s -o bar.o
+
+# RUN: ld.lld main.o %t/foo.o %t/bar.o -T script.ld -o main_abs.o -Map=main_abs.map
+
+# RUN: FileCheck %s < main_abs.map
+# CHECK: .goo
+# CHECK: bar.o:(.text_bar)
+# CHECK: bar
+# CHECK: foo.o:(.text_foo) 
+# CHECK: foo
+# CHECK-NOT: .text_bar
+# CHECK-NOT: .text_foo
+
+#--- foo.s
+    .section .text_foo, "ax", %progbits
+    .globl	foo
+    .p2align	4
+    .type	foo, at function
+foo:
+    nop
+
+
+#--- bar.s
+    .section .text_bar, "ax", %progbits
+    .globl	bar
+    .p2align	4
+    .type	bar, at function
+bar:      
+    nop
+
+
+#--- main.s
+	.text
+	.globl	main
+	.p2align	4
+	.type	main, at function
+main:
+	callq	foo at PLT
+	callq	bar at PLT
+	retq
+
+
+#--- script.ld
+SECTIONS {
+  .text : { *(.text) }
+  .goo : {
+    bar.o(.text_bar);
+    foo.o(.text_foo);
+  }
+}
\ No newline at end of file



More information about the llvm-commits mailing list