Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -55,25 +55,29 @@ return I < J ? -1 : 1; } -// Returns true if S matches T. S may contain a meta character '*' -// which matches zero or more occurrences of any character. -static bool matchStr(StringRef S, StringRef T) { +// Returns true if wildcard pattern W matches T. +// W may contain next meta characters: +// '*' which matches zero or more occurrences of any character. +// '?' matches any single character. +// Ex: matchStr(".sec*", ".sec.1") == true +// Ex: matchStr("crtbegin?.o", "crtbeginS.o") == true +static bool matchStr(StringRef W, StringRef T) { for (;;) { - if (S.empty()) + if (W.empty()) return T.empty(); - if (S[0] == '*') { - S = S.substr(1); - if (S.empty()) + if (W[0] == '*') { + W = W.substr(1); + if (W.empty()) // Fast path. If a pattern is '*', it matches anything. return true; for (size_t I = 0, E = T.size(); I < E; ++I) - if (matchStr(S, T.substr(I))) + if (matchStr(W, T.substr(I))) return true; return false; } - if (T.empty() || S[0] != T[0]) + if (T.empty() || (W[0] != T[0] && W[0] != '?')) return false; - S = S.substr(1); + W = W.substr(1); T = T.substr(1); } } Index: test/ELF/wildcards.s =================================================================== --- test/ELF/wildcards.s +++ test/ELF/wildcards.s @@ -0,0 +1,53 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +## Default case: foo and boo included in text. +# RUN: echo "SECTIONS { \ +# RUN: .text : { *(.abc .abx) } }" > %t.script +# RUN: ld.lld -o %t.out --script %t.script %t +# RUN: llvm-objdump -section-headers %t.out | \ +# RUN: FileCheck -check-prefix=SEC-DEFAULT %s +# SEC-DEFAULT: Sections: +# SEC-DEFAULT-NEXT: Idx Name Size Address Type +# SEC-DEFAULT-NEXT: 0 00000000 0000000000000000 +# SEC-DEFAULT-NEXT: 1 .text 00000008 0000000000011000 TEXT DATA +# SEC-DEFAULT-NEXT: 2 .abcd 00000004 0000000000011008 TEXT DATA +# SEC-DEFAULT-NEXT: 3 .symtab 00000030 0000000000000000 +# SEC-DEFAULT-NEXT: 4 .shstrtab 00000027 0000000000000000 +# SEC-DEFAULT-NEXT: 5 .strtab 00000008 0000000000000000 + +## Now replace the symbol with '?' and check that results are the same. +# RUN: echo "SECTIONS { \ +# RUN: .text : { *(.abc .ab?) } }" > %t.script +# RUN: ld.lld -o %t.out --script %t.script %t +# RUN: llvm-objdump -section-headers %t.out | \ +# RUN: FileCheck -check-prefix=SEC-DEFAULT %s + +## Now see how replacing '?' with '*' will consume whole abcd. +# RUN: echo "SECTIONS { \ +# RUN: .text : { *(.abc .ab*) } }" > %t.script +# RUN: ld.lld -o %t.out --script %t.script %t +# RUN: llvm-objdump -section-headers %t.out | \ +# RUN: FileCheck -check-prefix=SEC-ALL %s +# SEC-ALL: Sections: +# SEC-ALL-NEXT: Idx Name Size Address Type +# SEC-ALL-NEXT: 0 00000000 0000000000000000 +# SEC-ALL-NEXT: 1 .text 0000000c 0000000000011000 TEXT DATA +# SEC-ALL-NEXT: 2 .symtab 00000030 0000000000000000 +# SEC-ALL-NEXT: 3 .shstrtab 00000021 0000000000000000 +# SEC-ALL-NEXT: 4 .strtab 00000008 0000000000000000 + +.text +.section .abc,"ax",@progbits +.long 0 + +.text +.section .abx,"ax",@progbits +.long 0 + +.text +.section .abcd,"ax",@progbits +.long 0 + +.globl _start +_start: