[lld] [lld][ELF] Handle archive special casing in Input Sections (PR #119293)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 17 12:45:29 PST 2024
https://github.com/amosher-nvidia updated https://github.com/llvm/llvm-project/pull/119293
>From 4c1215f4fcad0fbb730e63f91ba849921d8fccaf 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 1/2] [lld][ELF] Handle archive special casing in Input
Sections
Co-authored-by: Peter Smith <peter.smith at arm.com>
---
lld/ELF/LinkerScript.cpp | 17 +++++++++++++++--
lld/ELF/LinkerScript.h | 19 +++++++++++++++++--
lld/test/ELF/linkerscript/filename-spec.s | 13 ++++++++++---
3 files changed, 42 insertions(+), 7 deletions(-)
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 7d24c6750b0d10..0d528343aa6cb9 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -406,12 +406,25 @@ static inline StringRef getFilename(const InputFile *file) {
return file ? file->getNameForScript() : StringRef();
}
+static inline StringRef getArchiveName(const InputFile *file) {
+ return file ? static_cast<StringRef>(file->archiveName) : StringRef();
+}
+
bool InputSectionDescription::matchesFile(const InputFile *file) const {
if (filePat.isTrivialMatchAll())
return true;
- if (!matchesFileCache || matchesFileCache->first != file)
- matchesFileCache.emplace(file, filePat.match(getFilename(file)));
+ if (!matchesFileCache || matchesFileCache->first != file) {
+ if (matchType == MatchType::WholeArchive) {
+ matchesFileCache.emplace(file, filePat.match(getArchiveName(file)));
+ } else {
+ if (matchType == MatchType::ArchivesExcluded && file &&
+ !file->archiveName.empty())
+ matchesFileCache.emplace(file, false);
+ else
+ matchesFileCache.emplace(file, filePat.match(getFilename(file)));
+ }
+ }
return matchesFileCache->second;
}
diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h
index 328368fd3b4333..8d64b326abf7be 100644
--- a/lld/ELF/LinkerScript.h
+++ b/lld/ELF/LinkerScript.h
@@ -194,6 +194,7 @@ class SectionPattern {
};
class InputSectionDescription : public SectionCommand {
+ enum class MatchType { Trivial, WholeArchive, ArchivesExcluded } matchType;
SingleStringMatcher filePat;
// Cache of the most recent input argument and result of matchesFile().
@@ -202,10 +203,24 @@ class InputSectionDescription : public SectionCommand {
public:
InputSectionDescription(StringRef filePattern, uint64_t withFlags = 0,
uint64_t withoutFlags = 0, StringRef classRef = {})
- : SectionCommand(InputSectionKind), filePat(filePattern),
- classRef(classRef), withFlags(withFlags), withoutFlags(withoutFlags) {
+ : SectionCommand(InputSectionKind), matchType(MatchType::Trivial),
+ filePat(filePattern), classRef(classRef), withFlags(withFlags),
+ withoutFlags(withoutFlags) {
assert((filePattern.empty() || classRef.empty()) &&
"file pattern and class reference are mutually exclusive");
+
+ // The matching syntax for whole archives and files outside of an archive
+ // can't be handled by SingleStringMatcher, and instead are handled
+ // manually within matchesFile()
+ if (!filePattern.empty()) {
+ if (filePattern.back() == ':') {
+ matchType = MatchType::WholeArchive;
+ filePat = filePattern.drop_back();
+ } else if (filePattern.front() == ':') {
+ matchType = MatchType::ArchivesExcluded;
+ filePat = filePattern.drop_front();
+ }
+ }
}
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..a6953ec2a0f97c 100644
--- a/lld/test/ELF/linkerscript/filename-spec.s
+++ b/lld/test/ELF/linkerscript/filename-spec.s
@@ -4,7 +4,7 @@
# RUN: llvm-mc -filetype=obj -triple=x86_64 tx.s -o tx.o
# RUN: llvm-mc -filetype=obj -triple=x86_64 ty.s -o ty.o
-# RUN: echo 'SECTIONS{.foo :{ KEEP(*x.o(.foo)) KEEP(*y.o(.foo)) }}' > 1.t
+# RUN: echo 'SECTIONS{.foo :{ KEEP(:*x.o(.foo)) KEEP(*y.o(.foo)) }}' > 1.t
# RUN: ld.lld -o 1 -T 1.t tx.o ty.o
# RUN: llvm-objdump -s 1 | FileCheck --check-prefix=FIRSTY %s
# FIRSTY: Contents of section .foo:
@@ -18,7 +18,7 @@
## Now the same tests but without KEEP. Checking that file name inside
## KEEP is parsed fine.
-# RUN: echo 'SECTIONS{.foo :{ *x.o(.foo) *y.o(.foo) }}' > 3.t
+# RUN: echo 'SECTIONS{.foo :{ :*x.o(.foo) *y.o(.foo) }}' > 3.t
# RUN: ld.lld -o 3 -T 3.t tx.o ty.o
# RUN: llvm-objdump -s 3 | FileCheck --check-prefix=FIRSTY %s
@@ -41,6 +41,7 @@
# RUN: cp ty.o dir2/filename-spec2.o
# RUN: llvm-ar rc dir1/lib1.a dir1/filename-spec1.o
# RUN: llvm-ar rc dir2/lib2.a dir2/filename-spec2.o
+# RUN: llvm-ar rc combined.a tx.o ty.o
## Verify matching of archive library names.
# RUN: echo 'SECTIONS{.foo :{ *lib2*(.foo) *lib1*(.foo) }}' > 7.t
@@ -55,7 +56,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
@@ -72,6 +73,12 @@
# RUN: ld.lld -o 11 -T 11.t --whole-archive 'lib1().a' dir2/lib2.a
# RUN: llvm-objdump -s 11 | FileCheck --check-prefix=SECONDFIRST %s
+## Verify that matching files excluded from an archive doesn't match files within one
+# RUN: echo 'SECTIONS{.foo :{ KEEP(:*x.o(.foo)) KEEP(*y.o(.foo)) KEEP(*x.o(.foo)) }}' > 12.t
+# RUN: ld.lld -o 12 -T 12.t --whole-archive \
+# RUN: combined.a
+# RUN: llvm-objdump -s 12 | FileCheck --check-prefix=SECONDFIRST %s
+
#--- tx.s
.global _start
_start:
>From e0f5e1866d1f70b45db25cf41e593a9442951a63 Mon Sep 17 00:00:00 2001
From: Avery Mosher <amosher at nvidia.com>
Date: Tue, 17 Dec 2024 20:44:43 +0000
Subject: [PATCH 2/2] [lld][ELF] Remove InputFile pointer sanitization
functions
---
lld/ELF/LinkerScript.cpp | 15 ++++-----------
1 file changed, 4 insertions(+), 11 deletions(-)
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 0d528343aa6cb9..5da5556a7e59c9 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -402,27 +402,19 @@ void LinkerScript::assignSymbol(SymbolAssignment *cmd, bool inSec) {
cmd->sym->type = v.type;
}
-static inline StringRef getFilename(const InputFile *file) {
- return file ? file->getNameForScript() : StringRef();
-}
-
-static inline StringRef getArchiveName(const InputFile *file) {
- return file ? static_cast<StringRef>(file->archiveName) : StringRef();
-}
-
bool InputSectionDescription::matchesFile(const InputFile *file) const {
if (filePat.isTrivialMatchAll())
return true;
if (!matchesFileCache || matchesFileCache->first != file) {
if (matchType == MatchType::WholeArchive) {
- matchesFileCache.emplace(file, filePat.match(getArchiveName(file)));
+ matchesFileCache.emplace(file, filePat.match(file->archiveName));
} else {
if (matchType == MatchType::ArchivesExcluded && file &&
!file->archiveName.empty())
matchesFileCache.emplace(file, false);
else
- matchesFileCache.emplace(file, filePat.match(getFilename(file)));
+ matchesFileCache.emplace(file, filePat.match(file->getNameForScript()));
}
}
@@ -434,7 +426,8 @@ bool SectionPattern::excludesFile(const InputFile *file) const {
return false;
if (!excludesFileCache || excludesFileCache->first != file)
- excludesFileCache.emplace(file, excludedFilePat.match(getFilename(file)));
+ excludesFileCache.emplace(file,
+ excludedFilePat.match(file->getNameForScript()));
return excludesFileCache->second;
}
More information about the llvm-commits
mailing list