forked from OSchip/llvm-project
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
This commit is contained in:
parent
e5d4a6c708
commit
395281cfc3
|
@ -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 (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 &&
|
||||
const_cast<Regex &>(Re).match(S->Name))
|
||||
if (!isDiscarded(S) && !S->OutSec && Re.match(S->Name))
|
||||
I->Sections.push_back(S);
|
||||
|
||||
if (const_cast<Regex &>(Re).match("COMMON"))
|
||||
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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
.section .foo.1,"a"
|
||||
.quad 4
|
||||
|
||||
.section .foo.2,"a"
|
||||
.quad 5
|
||||
|
||||
.section .foo.3,"a"
|
||||
.quad 6
|
|
@ -0,0 +1,8 @@
|
|||
.section .foo.1,"a"
|
||||
.quad 7
|
||||
|
||||
.section .foo.2,"a"
|
||||
.quad 8
|
||||
|
||||
.section .foo.3,"a"
|
||||
.quad 9
|
|
@ -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
|
Loading…
Reference in New Issue