forked from OSchip/llvm-project
[ELF/LinkerScript] Support EXCLUDE_FILE inside KEEP.
Differential Revision: https://reviews.llvm.org/D22795 llvm-svn: 276825
This commit is contained in:
parent
f990fa5f7b
commit
e7282797aa
|
@ -79,15 +79,15 @@ static bool match(ArrayRef<StringRef> Patterns, StringRef S) {
|
|||
// input sections start with ".foo." or ".bar." should be added to
|
||||
// ".text" section.
|
||||
template <class ELFT>
|
||||
std::vector<std::pair<StringRef, ArrayRef<StringRef>>>
|
||||
std::vector<std::pair<StringRef, const InputSectionDescription *>>
|
||||
LinkerScript<ELFT>::getSectionMap() {
|
||||
std::vector<std::pair<StringRef, ArrayRef<StringRef>>> Ret;
|
||||
std::vector<std::pair<StringRef, const InputSectionDescription *>> Ret;
|
||||
|
||||
for (const std::unique_ptr<BaseCommand> &Base1 : Opt.Commands)
|
||||
if (auto *Cmd1 = dyn_cast<OutputSectionCommand>(Base1.get()))
|
||||
for (const std::unique_ptr<BaseCommand> &Base2 : Cmd1->Commands)
|
||||
if (auto *Cmd2 = dyn_cast<InputSectionDescription>(Base2.get()))
|
||||
Ret.emplace_back(Cmd1->Name, Cmd2->Patterns);
|
||||
Ret.emplace_back(Cmd1->Name, Cmd2);
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
@ -95,13 +95,17 @@ LinkerScript<ELFT>::getSectionMap() {
|
|||
// Returns input sections filtered by given glob patterns.
|
||||
template <class ELFT>
|
||||
std::vector<InputSectionBase<ELFT> *>
|
||||
LinkerScript<ELFT>::getInputSections(ArrayRef<StringRef> Patterns) {
|
||||
LinkerScript<ELFT>::getInputSections(const InputSectionDescription *I) {
|
||||
ArrayRef<StringRef> Patterns = I->Patterns;
|
||||
ArrayRef<StringRef> ExcludedFiles = I->ExcludedFiles;
|
||||
std::vector<InputSectionBase<ELFT> *> Ret;
|
||||
for (const std::unique_ptr<ObjectFile<ELFT>> &F :
|
||||
Symtab<ELFT>::X->getObjectFiles())
|
||||
for (InputSectionBase<ELFT> *S : F->getSections())
|
||||
if (!isDiscarded(S) && !S->OutSec && match(Patterns, S->getSectionName()))
|
||||
Ret.push_back(S);
|
||||
if (ExcludedFiles.empty() ||
|
||||
!match(ExcludedFiles, sys::path::filename(F->getName())))
|
||||
Ret.push_back(S);
|
||||
return Ret;
|
||||
}
|
||||
|
||||
|
@ -123,8 +127,8 @@ LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
|
|||
|
||||
for (auto &P : getSectionMap()) {
|
||||
StringRef OutputName = P.first;
|
||||
ArrayRef<StringRef> InputPatterns = P.second;
|
||||
for (InputSectionBase<ELFT> *S : getInputSections(InputPatterns)) {
|
||||
const InputSectionDescription *I = P.second;
|
||||
for (InputSectionBase<ELFT> *S : getInputSections(I)) {
|
||||
if (OutputName == "/DISCARD/") {
|
||||
S->Live = false;
|
||||
reportDiscarded(S);
|
||||
|
@ -420,6 +424,7 @@ private:
|
|||
void readAsNeeded();
|
||||
void readEntry();
|
||||
void readExtern();
|
||||
std::unique_ptr<InputSectionDescription> readFilePattern();
|
||||
void readGroup();
|
||||
void readKeep(OutputSectionCommand *Cmd);
|
||||
void readInclude();
|
||||
|
@ -662,16 +667,31 @@ static int precedence(StringRef Op) {
|
|||
.Default(-1);
|
||||
}
|
||||
|
||||
void ScriptParser::readKeep(OutputSectionCommand *Cmd) {
|
||||
expect("(");
|
||||
std::unique_ptr<InputSectionDescription> ScriptParser::readFilePattern() {
|
||||
expect("*");
|
||||
expect("(");
|
||||
auto *InCmd = new InputSectionDescription();
|
||||
Cmd->Commands.emplace_back(InCmd);
|
||||
while (!Error && !skip(")")) {
|
||||
Opt.KeptSections.push_back(peek());
|
||||
|
||||
auto InCmd = llvm::make_unique<InputSectionDescription>();
|
||||
|
||||
if (skip("EXCLUDE_FILE")) {
|
||||
expect("(");
|
||||
while (!Error && !skip(")"))
|
||||
InCmd->ExcludedFiles.push_back(next());
|
||||
InCmd->Patterns.push_back(next());
|
||||
expect(")");
|
||||
} else {
|
||||
while (!Error && !skip(")"))
|
||||
InCmd->Patterns.push_back(next());
|
||||
}
|
||||
return InCmd;
|
||||
}
|
||||
|
||||
void ScriptParser::readKeep(OutputSectionCommand *Cmd) {
|
||||
expect("(");
|
||||
std::unique_ptr<InputSectionDescription> InCmd = readFilePattern();
|
||||
Opt.KeptSections.insert(Opt.KeptSections.end(), InCmd->Patterns.begin(),
|
||||
InCmd->Patterns.end());
|
||||
Cmd->Commands.push_back(std::move(InCmd));
|
||||
expect(")");
|
||||
}
|
||||
|
||||
|
|
|
@ -83,6 +83,7 @@ struct OutputSectionCommand : BaseCommand {
|
|||
struct InputSectionDescription : BaseCommand {
|
||||
InputSectionDescription() : BaseCommand(InputSectionKind) {}
|
||||
static bool classof(const BaseCommand *C);
|
||||
std::vector<StringRef> ExcludedFiles;
|
||||
std::vector<StringRef> Patterns;
|
||||
};
|
||||
|
||||
|
@ -132,10 +133,11 @@ public:
|
|||
bool hasPhdrsCommands();
|
||||
|
||||
private:
|
||||
std::vector<std::pair<StringRef, ArrayRef<StringRef>>> getSectionMap();
|
||||
std::vector<std::pair<StringRef, const InputSectionDescription *>>
|
||||
getSectionMap();
|
||||
|
||||
std::vector<InputSectionBase<ELFT> *>
|
||||
getInputSections(ArrayRef<StringRef> Patterns);
|
||||
getInputSections(const InputSectionDescription *);
|
||||
|
||||
// "ScriptConfig" is a bit too long, so define a short name for it.
|
||||
ScriptConfiguration &Opt = *ScriptConfig;
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
.section .text
|
||||
.globl _potato
|
||||
_potato:
|
||||
nop
|
||||
nop
|
|
@ -0,0 +1,4 @@
|
|||
.section .text
|
||||
.globl tomato
|
||||
tomato:
|
||||
movl $1, %eax
|
|
@ -0,0 +1,48 @@
|
|||
# REQUIRES: x86
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
|
||||
# RUN: %p/Inputs/include.s -o %t2
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
|
||||
# RUN: %p/Inputs/notinclude.s -o %t3.notinclude
|
||||
|
||||
# RUN: echo "SECTIONS {} " > %t.script
|
||||
# RUN: ld.lld -o %t --script %t.script %t1 %t2 %t3.notinclude
|
||||
# RUN: llvm-objdump -d %t | \
|
||||
# RUN: FileCheck %s
|
||||
|
||||
# CHECK: Disassembly of section .text:
|
||||
# CHECK: _start:
|
||||
# CHECK: 120: 48 c7 c0 3c 00 00 00 movq $60, %rax
|
||||
# CHECK: 127: 48 c7 c7 2a 00 00 00 movq $42, %rdi
|
||||
# CHECK: 12e: 00 00 addb %al, (%rax)
|
||||
# CHECK: _potato:
|
||||
# CHECK: 130: 90 nop
|
||||
# CHECK: 131: 90 nop
|
||||
# CHECK: 132: 00 00 addb %al, (%rax)
|
||||
# CHECK: tomato:
|
||||
# CHECK: 134: b8 01 00 00 00 movl $1, %eax
|
||||
|
||||
# RUN: echo "SECTIONS { .patatino : \
|
||||
# RUN: { KEEP(*(EXCLUDE_FILE(*notinclude) .text)) } }" \
|
||||
# RUN: > %t.script
|
||||
# RUN: ld.lld -o %t2 --script %t.script %t1 %t2 %t3.notinclude
|
||||
# RUN: llvm-objdump -d %t2 | \
|
||||
# RUN: FileCheck %s --check-prefix=EXCLUDE
|
||||
|
||||
# EXCLUDE: Disassembly of section .patatino:
|
||||
# EXCLUDE: _start:
|
||||
# EXCLUDE: 120: 48 c7 c0 3c 00 00 00 movq $60, %rax
|
||||
# EXCLUDE: 127: 48 c7 c7 2a 00 00 00 movq $42, %rdi
|
||||
# EXCLUDE: 12e: 00 00 addb %al, (%rax)
|
||||
# EXCLUDE: _potato:
|
||||
# EXCLUDE: 130: 90 nop
|
||||
# EXCLUDE: 131: 90 nop
|
||||
# EXCLUDE: Disassembly of section .text:
|
||||
# EXCLUDE: tomato:
|
||||
# EXCLUDE: 134: b8 01 00 00 00 movl $1, %eax
|
||||
|
||||
.section .text
|
||||
.globl _start
|
||||
_start:
|
||||
mov $60, %rax
|
||||
mov $42, %rdi
|
Loading…
Reference in New Issue