diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -646,19 +646,25 @@ std::vector ret; while (!errorCount() && peek() != ")") { StringMatcher excludeFilePat; + bool excludeFile = false; if (consume("EXCLUDE_FILE")) { expect("("); excludeFilePat = readFilePatterns(); + excludeFile = true; } StringMatcher SectionMatcher; - while (!errorCount() && peek() != ")" && peek() != "EXCLUDE_FILE") + // peek2() is used to detect EXCLUDE_FILE( or SORT( (e.g. *(.foo + // SORT(.bar))) where we should break the loop. + while (!errorCount() && peek() != ")" && peek2() != "(") SectionMatcher.addPattern(unquote(next())); if (!SectionMatcher.empty()) ret.push_back({std::move(excludeFilePat), std::move(SectionMatcher)}); - else + else if (excludeFile) setError("section pattern is expected"); + else + break; } return ret; } diff --git a/lld/test/ELF/linkerscript/sort2.s b/lld/test/ELF/linkerscript/sort2.s --- a/lld/test/ELF/linkerscript/sort2.s +++ b/lld/test/ELF/linkerscript/sort2.s @@ -1,39 +1,36 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %tfile1.o -# RUN: echo "SECTIONS { .abc : { *(SORT(.foo.*) .bar.*) } }" > %t1.script +# RUN: echo "SECTIONS { .abc : { *(SORT(.foo.*) .a* .a* SORT(.bar.*) .b*) } }" > %t1.script # RUN: ld.lld -o %t1 --script %t1.script %tfile1.o -# RUN: llvm-objdump -s %t1 | FileCheck %s +# RUN: llvm-readelf -x .abc %t1 | FileCheck %s -# CHECK: Contents of section .abc: -# CHECK: 01000000 00000000 02000000 00000000 -# CHECK: 03000000 00000000 04000000 00000000 -# CHECK: 06000000 00000000 05000000 00000000 +## FIXME Some input sections are duplicated in .abc and their second occurrences are zeros. +# CHECK: Hex dump of section '.abc' +# CHECK-NEXT: 0x00000000 01020306 05040000 00070908 0b0c0a # RUN: echo "SECTIONS { \ -# RUN: .abc : { *(SORT(.foo.* EXCLUDE_FILE (*file1.o) .bar.*) .bar.*) } \ +# RUN: .abc : { *(SORT(.foo.* EXCLUDE_FILE (*file1.o) .bar.*) .a* SORT(.bar.*) .b*) } \ # RUN: }" > %t2.script # RUN: ld.lld -o %t2 --script %t2.script %tfile1.o -# RUN: llvm-objdump -s %t2 | FileCheck %s +# RUN: llvm-readelf -x .abc %t2 | FileCheck %s .text .globl _start _start: -.section .foo.2,"a" - .quad 2 +.section .foo.2,"a"; .byte 2 +.section .foo.3,"a"; .byte 3 +.section .foo.1,"a"; .byte 1 -.section .foo.3,"a" - .quad 3 +.section .a6,"a"; .byte 6 +.section .a5,"a"; .byte 5 +.section .a4,"a"; .byte 4 -.section .foo.1,"a" - .quad 1 +.section .bar.7,"a"; .byte 7 +.section .bar.9,"a"; .byte 9 +.section .bar.8,"a"; .byte 8 -.section .bar.4,"a" - .quad 4 - -.section .bar.6,"a" - .quad 6 - -.section .bar.5,"a" - .quad 5 +.section .b11,"a"; .byte 11 +.section .b12,"a"; .byte 12 +.section .b10,"a"; .byte 10