diff options
| author | George Rimar <grimar@accesssoftek.com> | 2016-09-16 17:42:10 +0000 |
|---|---|---|
| committer | George Rimar <grimar@accesssoftek.com> | 2016-09-16 17:42:10 +0000 |
| commit | 395281cfc3ff0e76c68501b040cb43b830d974ea (patch) | |
| tree | 90d72c9bb6e93ce593b379b4eeca4e470e3c9da5 | |
| parent | e5d4a6c7087c9f6c424794b4996cdf84176eb54f (diff) | |
| download | bcm5719-llvm-395281cfc3ff0e76c68501b040cb43b830d974ea.tar.gz bcm5719-llvm-395281cfc3ff0e76c68501b040cb43b830d974ea.zip | |
Recommit r281721 "[ELF] - Linkerscript: implement EXCLUDE_FILE in the middle of a input section description."
With fix for 2 bots. Details about the fix performed is on a review page.
Initial commit message:
This is PR30387:
From PR description:
We fail to parse
SECTIONS
{
foo :
{
*(sec0 EXCLUDE_FILE (zed1.o) sec1 EXCLUDE_FILE (zed2.o) sec2 )
}
}
The semantics according to bfd are:
Include sec1 from every file but zed1.o
Include sec2 from every file but zed2.o
Include sec0 from every file
Patch implements the support.
Differential revision: https://reviews.llvm.org/D24650
llvm-svn: 281754
| -rw-r--r-- | lld/ELF/LinkerScript.cpp | 77 | ||||
| -rw-r--r-- | lld/ELF/LinkerScript.h | 5 | ||||
| -rw-r--r-- | lld/test/ELF/linkerscript/Inputs/exclude-multiple1.s | 8 | ||||
| -rw-r--r-- | lld/test/ELF/linkerscript/Inputs/exclude-multiple2.s | 8 | ||||
| -rw-r--r-- | lld/test/ELF/linkerscript/exclude-multiple.s | 28 |
5 files changed, 100 insertions, 26 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 175ec5f668c..d676d38c4c1 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -109,10 +109,10 @@ bool LinkerScript<ELFT>::shouldKeep(InputSectionBase<ELFT> *S) { return false; } -static bool fileMatches(const InputSectionDescription *Desc, - StringRef Filename) { - return const_cast<Regex &>(Desc->FileRe).match(Filename) && - !const_cast<Regex &>(Desc->ExcludedFileRe).match(Filename); +static bool fileMatches(const llvm::Regex &FileRe, + const llvm::Regex &ExcludedFileRe, StringRef Filename) { + return const_cast<Regex &>(FileRe).match(Filename) && + !const_cast<Regex &>(ExcludedFileRe).match(Filename); } static bool comparePriority(InputSectionData *A, InputSectionData *B) { @@ -161,16 +161,19 @@ static bool matchConstraints(ArrayRef<InputSectionData *> Sections, template <class ELFT> void LinkerScript<ELFT>::computeInputSections(InputSectionDescription *I, ConstraintKind Constraint) { - const Regex &Re = I->SectionRe; - for (ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles()) - if (fileMatches(I, sys::path::filename(F->getName()))) - for (InputSectionBase<ELFT> *S : F->getSections()) - if (!isDiscarded(S) && !S->OutSec && - const_cast<Regex &>(Re).match(S->Name)) - I->Sections.push_back(S); - - if (const_cast<Regex &>(Re).match("COMMON")) - I->Sections.push_back(CommonInputSection<ELFT>::X); + for (const std::pair<llvm::Regex, llvm::Regex> &V : I->SectionsVec) { + for (ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles()) { + if (fileMatches(I->FileRe, V.first, sys::path::filename(F->getName()))) { + Regex &Re = const_cast<Regex &>(V.second); + for (InputSectionBase<ELFT> *S : F->getSections()) + if (!isDiscarded(S) && !S->OutSec && Re.match(S->Name)) + I->Sections.push_back(S); + + if (Re.match("COMMON")) + I->Sections.push_back(CommonInputSection<ELFT>::X); + } + } + } if (!matchConstraints<ELFT>(I->Sections, Constraint)) { I->Sections.clear(); @@ -698,6 +701,7 @@ private: std::vector<StringRef> readOutputSectionPhdrs(); InputSectionDescription *readInputSectionDescription(StringRef Tok); Regex readFilePatterns(); + void readSectionExcludes(InputSectionDescription *Cmd); InputSectionDescription *readInputSectionRules(StringRef FilePattern); unsigned readPhdrType(); SortKind readSortKind(); @@ -991,17 +995,41 @@ SortKind ScriptParser::readSortKind() { return SortNone; } +// Method reads a list of sequence of excluded files and section globs given in +// a following form: ((EXCLUDE_FILE(file_pattern+))? section_pattern+)+ +// Example: *(.foo.1 EXCLUDE_FILE (*a.o) .foo.2 EXCLUDE_FILE (*b.o) .foo.3) +void ScriptParser::readSectionExcludes(InputSectionDescription *Cmd) { + llvm::Regex ExcludeFileRe; + std::vector<StringRef> V; + + while (!Error) { + if (skip(")")) { + Cmd->SectionsVec.push_back( + {std::move(ExcludeFileRe), compileGlobPatterns(V)}); + return; + } + + if (skip("EXCLUDE_FILE")) { + if (!V.empty()) { + Cmd->SectionsVec.push_back( + {std::move(ExcludeFileRe), compileGlobPatterns(V)}); + V.clear(); + } + + expect("("); + ExcludeFileRe = readFilePatterns(); + continue; + } + + V.push_back(next()); + } +} + InputSectionDescription * ScriptParser::readInputSectionRules(StringRef FilePattern) { auto *Cmd = new InputSectionDescription(FilePattern); expect("("); - // Read EXCLUDE_FILE(). - if (skip("EXCLUDE_FILE")) { - expect("("); - Cmd->ExcludedFileRe = readFilePatterns(); - } - // Read SORT(). if (SortKind K1 = readSortKind()) { Cmd->SortOuter = K1; @@ -1009,16 +1037,16 @@ ScriptParser::readInputSectionRules(StringRef FilePattern) { if (SortKind K2 = readSortKind()) { Cmd->SortInner = K2; expect("("); - Cmd->SectionRe = readFilePatterns(); + Cmd->SectionsVec.push_back({llvm::Regex(), readFilePatterns()}); expect(")"); } else { - Cmd->SectionRe = readFilePatterns(); + Cmd->SectionsVec.push_back({llvm::Regex(), readFilePatterns()}); } expect(")"); return Cmd; } - Cmd->SectionRe = readFilePatterns(); + readSectionExcludes(Cmd); return Cmd; } @@ -1031,7 +1059,8 @@ ScriptParser::readInputSectionDescription(StringRef Tok) { StringRef FilePattern = next(); InputSectionDescription *Cmd = readInputSectionRules(FilePattern); expect(")"); - Opt.KeptSections.push_back(&Cmd->SectionRe); + for (std::pair<llvm::Regex, llvm::Regex> &Regex : Cmd->SectionsVec) + Opt.KeptSections.push_back(&Regex.second); return Cmd; } return readInputSectionRules(Tok); diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h index d9fc1175fce..159cac3f9f0 100644 --- a/lld/ELF/LinkerScript.h +++ b/lld/ELF/LinkerScript.h @@ -20,6 +20,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Regex.h" #include <functional> +#include <list> namespace lld { namespace elf { @@ -106,8 +107,8 @@ struct InputSectionDescription : BaseCommand { llvm::Regex FileRe; SortKind SortOuter = SortNone; SortKind SortInner = SortNone; - llvm::Regex ExcludedFileRe; - llvm::Regex SectionRe; + // Pairs of section regex and files excluded. + std::list<std::pair<llvm::Regex, llvm::Regex>> SectionsVec; std::vector<InputSectionData *> Sections; }; diff --git a/lld/test/ELF/linkerscript/Inputs/exclude-multiple1.s b/lld/test/ELF/linkerscript/Inputs/exclude-multiple1.s new file mode 100644 index 00000000000..1e0f741df40 --- /dev/null +++ b/lld/test/ELF/linkerscript/Inputs/exclude-multiple1.s @@ -0,0 +1,8 @@ +.section .foo.1,"a" + .quad 4 + +.section .foo.2,"a" + .quad 5 + +.section .foo.3,"a" + .quad 6 diff --git a/lld/test/ELF/linkerscript/Inputs/exclude-multiple2.s b/lld/test/ELF/linkerscript/Inputs/exclude-multiple2.s new file mode 100644 index 00000000000..60f790fa235 --- /dev/null +++ b/lld/test/ELF/linkerscript/Inputs/exclude-multiple2.s @@ -0,0 +1,8 @@ +.section .foo.1,"a" + .quad 7 + +.section .foo.2,"a" + .quad 8 + +.section .foo.3,"a" + .quad 9 diff --git a/lld/test/ELF/linkerscript/exclude-multiple.s b/lld/test/ELF/linkerscript/exclude-multiple.s new file mode 100644 index 00000000000..24c7f2faeea --- /dev/null +++ b/lld/test/ELF/linkerscript/exclude-multiple.s @@ -0,0 +1,28 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %tfile1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/exclude-multiple1.s -o %tfile2.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/exclude-multiple2.s -o %tfile3.o +# RUN: echo "SECTIONS { \ +# RUN: .foo : { *(.foo.1 EXCLUDE_FILE (*file1.o) .foo.2 EXCLUDE_FILE (*file2.o) .foo.3) } \ +# RUN: }" > %t1.script +# RUN: ld.lld -script %t1.script %tfile1.o %tfile2.o %tfile3.o -o %t1.o +# RUN: llvm-objdump -s %t1.o | FileCheck %s + +# CHECK: Contents of section .foo: +# CHECK-NEXT: 0120 01000000 00000000 04000000 00000000 +# CHECK-NEXT: 0130 07000000 00000000 05000000 00000000 +# CHECK-NEXT: 0140 08000000 00000000 03000000 00000000 +# CHECK-NEXT: 0150 09000000 00000000 +# CHECK-NEXT: Contents of section .foo.2: +# CHECK-NEXT: 0158 02000000 00000000 +# CHECK-NEXT: Contents of section .foo.3: +# CHECK-NEXT: 0160 06000000 00000000 + +.section .foo.1,"a" + .quad 1 + +.section .foo.2,"a" + .quad 2 + +.section .foo.3,"a" + .quad 3 |

