File tree 7 files changed +87
-1
lines changed
7 files changed +87
-1
lines changed Original file line number Diff line number Diff line change @@ -1087,6 +1087,10 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
1087
1087
if (errorCount ())
1088
1088
return ;
1089
1089
1090
+ // Now when we read all script files, we want to finalize order of linker
1091
+ // script commands, which can be not yet final because of INSERT commands.
1092
+ Script->processInsertCommands ();
1093
+
1090
1094
// We want to declare linker script's symbols early,
1091
1095
// so that we can version them.
1092
1096
// They also might be exported if referenced by DSOs.
Original file line number Diff line number Diff line change @@ -203,6 +203,26 @@ static void declareSymbol(SymbolAssignment *Cmd) {
203
203
Cmd->Provide = false ;
204
204
}
205
205
206
+ // This method is used to handle INSERT AFTER statement. Here we rebuild
207
+ // the list of script commands to mix sections inserted into.
208
+ void LinkerScript::processInsertCommands () {
209
+ std::vector<BaseCommand *> V;
210
+ for (BaseCommand *Base : SectionCommands) {
211
+ V.push_back (Base);
212
+ if (auto *Cmd = dyn_cast<OutputSection>(Base)) {
213
+ std::vector<BaseCommand *> &W = InsertAfterCommands[Cmd->Name ];
214
+ V.insert (V.end (), W.begin (), W.end ());
215
+ W.clear ();
216
+ }
217
+ }
218
+ for (std::pair<StringRef, std::vector<BaseCommand *>> &P :
219
+ InsertAfterCommands)
220
+ if (!P.second .empty ())
221
+ error (" unable to INSERT AFTER " + P.first + " : section not defined" );
222
+
223
+ SectionCommands = std::move (V);
224
+ }
225
+
206
226
// Symbols defined in script should not be inlined by LTO. At the same time
207
227
// we don't know their final values until late stages of link. Here we scan
208
228
// over symbol assignment commands and create placeholder symbols if needed.
Original file line number Diff line number Diff line change @@ -267,6 +267,9 @@ class LinkerScript final {
267
267
void processSectionCommands ();
268
268
void declareSymbols ();
269
269
270
+ // Used to handle INSERT AFTER statements.
271
+ void processInsertCommands ();
272
+
270
273
// SECTIONS command list.
271
274
std::vector<BaseCommand *> SectionCommands;
272
275
@@ -285,6 +288,10 @@ class LinkerScript final {
285
288
286
289
// A list of symbols referenced by the script.
287
290
std::vector<llvm::StringRef> ReferencedSymbols;
291
+
292
+ // Used to implement INSERT AFTER. Contains commands that need
293
+ // to be inserted into SECTIONS commands list.
294
+ llvm::DenseMap<StringRef, std::vector<BaseCommand *>> InsertAfterCommands;
288
295
};
289
296
290
297
extern LinkerScript *Script;
Original file line number Diff line number Diff line change @@ -436,6 +436,7 @@ void ScriptParser::readSections() {
436
436
Config->SingleRoRx = true ;
437
437
438
438
expect (" {" );
439
+ std::vector<BaseCommand *> V;
439
440
while (!errorCount () && !consume (" }" )) {
440
441
StringRef Tok = next ();
441
442
BaseCommand *Cmd = readProvideOrAssignment (Tok);
@@ -445,8 +446,18 @@ void ScriptParser::readSections() {
445
446
else
446
447
Cmd = readOutputSectionDescription (Tok);
447
448
}
448
- Script-> SectionCommands .push_back (Cmd);
449
+ V .push_back (Cmd);
449
450
}
451
+
452
+ if (!atEOF () && consume (" INSERT" )) {
453
+ consume (" AFTER" );
454
+ std::vector<BaseCommand *> &Dest = Script->InsertAfterCommands [next ()];
455
+ Dest.insert (Dest.end (), V.begin (), V.end ());
456
+ return ;
457
+ }
458
+
459
+ Script->SectionCommands .insert (Script->SectionCommands .end (), V.begin (),
460
+ V.end ());
450
461
}
451
462
452
463
static int precedence (StringRef Op) {
Original file line number Diff line number Diff line change
1
+ .section .foo.text,"ax"
2
+ .quad 0
3
+
4
+ .section .foo.data,"aw"
5
+ .quad 0
6
+
7
+ .section .text .1 ,"ax"
8
+ .quad 0
9
+
10
+ .section .data .1 ,"aw"
11
+ .quad 0
Original file line number Diff line number Diff line change
1
+ SECTIONS {
2
+ .text : { *(.text.*) }
3
+ .data : { *(.data.*) }
4
+ }
Original file line number Diff line number Diff line change
1
+ # REQUIRES: x86
2
+ # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/insert-after.s -o %t1.o
3
+
4
+ ## Main linker script contains .text and .data sections. Here
5
+ ## we check that can use INSERT AFTER to insert sections .foo.data
6
+ ## and .foo.text at the right places.
7
+
8
+ SECTIONS {
9
+ .foo.data : { *(.foo.data) }
10
+ } INSERT AFTER .data;
11
+
12
+ SECTIONS {
13
+ .foo.text : { *(.foo.text) }
14
+ } INSERT AFTER .text;
15
+
16
+ # RUN: ld.lld %t1.o -o %t1 --script %p/Inputs/insert-after.script --script %s
17
+ # RUN: llvm-objdump -section-headers %t1 | FileCheck %s
18
+ # CHECK: Sections:
19
+ # CHECK-NEXT: Idx Name Size Address Type
20
+ # CHECK-NEXT: 0 00000000 0000000000000000
21
+ # CHECK-NEXT: 1 .text 00000008 0000000000000000 TEXT DATA
22
+ # CHECK-NEXT: 2 .foo.text 00000008 0000000000000008 TEXT DATA
23
+ # CHECK-NEXT: 3 .data 00000008 0000000000000010 DATA
24
+ # CHECK-NEXT: 4 .foo.data 00000008 0000000000000018 DATA
25
+
26
+ # RUN: not ld.lld %t1.o -o %t1 --script %s 2>&1 \
27
+ # RUN: | FileCheck %s --check-prefix=ERR
28
+ # ERR-DAG: error: unable to INSERT AFTER .text: section not defined
29
+ # ERR-DAG: error: unable to INSERT AFTER .data: section not defined
You can’t perform that action at this time.
0 commit comments