From a4f5fede523f3b26b94a35970a99792612e15052 Mon Sep 17 00:00:00 2001 From: Parth Arora Date: Mon, 29 Dec 2025 12:16:16 -0800 Subject: [PATCH] Fix parsing of `"archive:mem"` input section description pattern This commit fixes the parsing / interpretation of `"archive:mem"` file pattern. Previously, it was getting incorrectly stored because we were not properly handling quotes when a single quoted token in the linker script (`"archive:member"`) is stored as two separate patterns in the linker implementation. Resolves #680 Signed-off-by: Parth Arora --- lib/ScriptParser/ScriptParser.cpp | 4 ++++ .../QuotedArchiveMemberPattern/Inputs/1.c | 2 ++ .../QuotedArchiveMemberPattern/Inputs/main.c | 3 +++ .../Inputs/script.t | 4 ++++ .../QuotedArchiveMemberPattern.test | 19 +++++++++++++++++++ 5 files changed, 32 insertions(+) create mode 100644 test/Common/standalone/linkerscript/QuotedArchiveMemberPattern/Inputs/1.c create mode 100644 test/Common/standalone/linkerscript/QuotedArchiveMemberPattern/Inputs/main.c create mode 100644 test/Common/standalone/linkerscript/QuotedArchiveMemberPattern/Inputs/script.t create mode 100644 test/Common/standalone/linkerscript/QuotedArchiveMemberPattern/QuotedArchiveMemberPattern.test diff --git a/lib/ScriptParser/ScriptParser.cpp b/lib/ScriptParser/ScriptParser.cpp index 126a84056..9511cb7ba 100644 --- a/lib/ScriptParser/ScriptParser.cpp +++ b/lib/ScriptParser/ScriptParser.cpp @@ -661,6 +661,10 @@ InputSectDesc::Spec ScriptParser::readInputSectionDescSpec(StringRef Tok) { if (!Tok.contains(':')) FilePat = createAndRegisterWildcardPattern(Tok); else { + // We cannot store the original quote information because we represent + // the single token "archive:mem" in the linker script as two separate + // patterns in the linker codebase. + Tok = unquote(Tok); std::pair Split = Tok.split(':'); FilePat = createAndRegisterWildcardPattern(Split.first); if (!Split.second.empty()) { diff --git a/test/Common/standalone/linkerscript/QuotedArchiveMemberPattern/Inputs/1.c b/test/Common/standalone/linkerscript/QuotedArchiveMemberPattern/Inputs/1.c new file mode 100644 index 000000000..3a5d6d0d7 --- /dev/null +++ b/test/Common/standalone/linkerscript/QuotedArchiveMemberPattern/Inputs/1.c @@ -0,0 +1,2 @@ +int foo() { return 1; } + diff --git a/test/Common/standalone/linkerscript/QuotedArchiveMemberPattern/Inputs/main.c b/test/Common/standalone/linkerscript/QuotedArchiveMemberPattern/Inputs/main.c new file mode 100644 index 000000000..68b721fe2 --- /dev/null +++ b/test/Common/standalone/linkerscript/QuotedArchiveMemberPattern/Inputs/main.c @@ -0,0 +1,3 @@ +int foo(); +int main() { return foo(); } + diff --git a/test/Common/standalone/linkerscript/QuotedArchiveMemberPattern/Inputs/script.t b/test/Common/standalone/linkerscript/QuotedArchiveMemberPattern/Inputs/script.t new file mode 100644 index 000000000..f235ca1f3 --- /dev/null +++ b/test/Common/standalone/linkerscript/QuotedArchiveMemberPattern/Inputs/script.t @@ -0,0 +1,4 @@ +SECTIONS { + .foo : { "*lib1.a:*1.o"(.text*) } + .text : { *(.text*) } +} diff --git a/test/Common/standalone/linkerscript/QuotedArchiveMemberPattern/QuotedArchiveMemberPattern.test b/test/Common/standalone/linkerscript/QuotedArchiveMemberPattern/QuotedArchiveMemberPattern.test new file mode 100644 index 000000000..993d2d287 --- /dev/null +++ b/test/Common/standalone/linkerscript/QuotedArchiveMemberPattern/QuotedArchiveMemberPattern.test @@ -0,0 +1,19 @@ +#---QuotedArchiveMemberPattern.test--------------------- Executable ------------------# +#BEGIN_COMMENT +# Validates that a quoted archive:member file pattern in an input section +# description is interpreted correctly. +#END_COMMENT +RUN: %clang %clangopts -o %t1.1.o %p/Inputs/1.c -c -ffunction-sections +RUN: %clang %clangopts -o %t1.main.o %p/Inputs/main.c -c -ffunction-sections +RUN: %ar cr %t1.lib1.a %t1.1.o +RUN: %link %linkopts -o %t1.main.out %t1.main.o %t1.lib1.a -MapStyle txt -T %p/Inputs/script.t -Map %t1.main.map.txt +RUN: %filecheck %s --check-prefix MAP < %t1.main.map.txt +RUN: %readelf -S %t1.main.out | %filecheck %s --check-prefix SECT + +MAP: .foo {{.*}} # Offset +MAP: *lib1.a:*1.o +MAP: .text.foo +MAP: foo +MAP: .text {{.*}} # Offset + +SECT: .foo PROGBITS