forked from OSchip/llvm-project
[ELF] - Implement INSERT BEFORE.
This finishes PR35877. INSERT BEFORE used similar to INSERT AFTER, it inserts sections before the given target section. Differential revision: https://reviews.llvm.org/D44380 llvm-svn: 327378
This commit is contained in:
parent
ebc1d1fdde
commit
796684b451
|
@ -207,18 +207,26 @@ static void declareSymbol(SymbolAssignment *Cmd) {
|
|||
// the list of script commands to mix sections inserted into.
|
||||
void LinkerScript::processInsertCommands() {
|
||||
std::vector<BaseCommand *> V;
|
||||
auto Insert = [&](std::vector<BaseCommand *> &From) {
|
||||
V.insert(V.end(), From.begin(), From.end());
|
||||
From.clear();
|
||||
};
|
||||
|
||||
for (BaseCommand *Base : SectionCommands) {
|
||||
V.push_back(Base);
|
||||
if (auto *Cmd = dyn_cast<OutputSection>(Base)) {
|
||||
std::vector<BaseCommand *> &W = InsertAfterCommands[Cmd->Name];
|
||||
V.insert(V.end(), W.begin(), W.end());
|
||||
W.clear();
|
||||
if (auto *OS = dyn_cast<OutputSection>(Base)) {
|
||||
Insert(InsertBeforeCommands[OS->Name]);
|
||||
V.push_back(Base);
|
||||
Insert(InsertAfterCommands[OS->Name]);
|
||||
continue;
|
||||
}
|
||||
V.push_back(Base);
|
||||
}
|
||||
for (std::pair<StringRef, std::vector<BaseCommand *>> &P :
|
||||
InsertAfterCommands)
|
||||
if (!P.second.empty())
|
||||
error("unable to INSERT AFTER " + P.first + ": section not defined");
|
||||
|
||||
for (auto &Cmds : {InsertBeforeCommands, InsertAfterCommands})
|
||||
for (const std::pair<StringRef, std::vector<BaseCommand *>> &P : Cmds)
|
||||
if (!P.second.empty())
|
||||
error("unable to INSERT AFTER/BEFORE " + P.first +
|
||||
": section not defined");
|
||||
|
||||
SectionCommands = std::move(V);
|
||||
}
|
||||
|
|
|
@ -289,9 +289,10 @@ public:
|
|||
// A list of symbols referenced by the script.
|
||||
std::vector<llvm::StringRef> ReferencedSymbols;
|
||||
|
||||
// Used to implement INSERT AFTER. Contains commands that need
|
||||
// Used to implement INSERT [AFTER|BEFORE]. Contains commands that need
|
||||
// to be inserted into SECTIONS commands list.
|
||||
llvm::DenseMap<StringRef, std::vector<BaseCommand *>> InsertAfterCommands;
|
||||
llvm::DenseMap<StringRef, std::vector<BaseCommand *>> InsertBeforeCommands;
|
||||
};
|
||||
|
||||
extern LinkerScript *Script;
|
||||
|
|
|
@ -450,9 +450,15 @@ void ScriptParser::readSections() {
|
|||
}
|
||||
|
||||
if (!atEOF() && consume("INSERT")) {
|
||||
expect("AFTER");
|
||||
std::vector<BaseCommand *> &Dest = Script->InsertAfterCommands[next()];
|
||||
Dest.insert(Dest.end(), V.begin(), V.end());
|
||||
std::vector<BaseCommand *> *Dest = nullptr;
|
||||
if (consume("AFTER"))
|
||||
Dest = &Script->InsertAfterCommands[next()];
|
||||
else if (consume("BEFORE"))
|
||||
Dest = &Script->InsertBeforeCommands[next()];
|
||||
else
|
||||
setError("expected AFTER/BEFORE, but got '" + next() + "'");
|
||||
if (Dest)
|
||||
Dest->insert(Dest->end(), V.begin(), V.end());
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,5 +25,5 @@ SECTIONS {
|
|||
|
||||
# RUN: not ld.lld %t1.o -o %t1 --script %s 2>&1 \
|
||||
# RUN: | FileCheck %s --check-prefix=ERR
|
||||
# ERR-DAG: error: unable to INSERT AFTER .text: section not defined
|
||||
# ERR-DAG: error: unable to INSERT AFTER .data: section not defined
|
||||
# ERR-DAG: error: unable to INSERT AFTER/BEFORE .text: section not defined
|
||||
# ERR-DAG: error: unable to INSERT AFTER/BEFORE .data: section not defined
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
# REQUIRES: x86
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/insert-after.s -o %t1.o
|
||||
|
||||
## Main linker script contains .text and .data sections. Here
|
||||
## we check that can use INSERT BEFORE to insert sections .foo.data
|
||||
## and .foo.text at the right places.
|
||||
|
||||
SECTIONS {
|
||||
.foo.data : { *(.foo.data) }
|
||||
} INSERT BEFORE .data;
|
||||
|
||||
SECTIONS {
|
||||
.foo.text : { *(.foo.text) }
|
||||
} INSERT BEFORE .text;
|
||||
|
||||
# RUN: ld.lld %t1.o -o %t1 --script %p/Inputs/insert-after.script --script %s
|
||||
# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
|
||||
# CHECK: Sections:
|
||||
# CHECK-NEXT: Idx Name Size Address Type
|
||||
# CHECK-NEXT: 0 00000000 0000000000000000
|
||||
# CHECK-NEXT: 1 .foo.text 00000008 0000000000000000 TEXT DATA
|
||||
# CHECK-NEXT: 2 .text 00000008 0000000000000008 TEXT DATA
|
||||
# CHECK-NEXT: 3 .foo.data 00000008 0000000000000010 DATA
|
||||
# CHECK-NEXT: 4 .data 00000008 0000000000000018 DATA
|
||||
|
||||
# RUN: not ld.lld %t1.o -o %t1 --script %s 2>&1 \
|
||||
# RUN: | FileCheck %s --check-prefix=ERR
|
||||
# ERR-DAG: error: unable to INSERT AFTER/BEFORE .text: section not defined
|
||||
# ERR-DAG: error: unable to INSERT AFTER/BEFORE .data: section not defined
|
|
@ -3,4 +3,4 @@ SECTIONS {
|
|||
} INSERT .data;
|
||||
|
||||
# RUN: not ld.lld -o %t1 --script %s 2>&1 | FileCheck %s
|
||||
# CHECK: {{.*}}:3: AFTER expected, but got .data
|
||||
# CHECK: {{.*}}:3: expected AFTER/BEFORE, but got '.data'
|
||||
|
|
Loading…
Reference in New Issue