@@ -304,6 +304,9 @@ getChangedSymbolAssignment(const SymbolAssignmentMap &oldValues) {
304
304
void LinkerScript::processInsertCommands () {
305
305
SmallVector<OutputDesc *, 0 > moves;
306
306
for (const InsertCommand &cmd : insertCommands) {
307
+ if (config->enableNonContiguousRegions )
308
+ error (" INSERT cannot be used with --enable-non-contiguous-regions" );
309
+
307
310
for (StringRef name : cmd.names ) {
308
311
// If base is empty, it may have been discarded by
309
312
// adjustOutputSections(). We do not handle such output sections.
@@ -486,10 +489,12 @@ static void sortInputSections(MutableArrayRef<InputSectionBase *> vec,
486
489
// Compute and remember which sections the InputSectionDescription matches.
487
490
SmallVector<InputSectionBase *, 0 >
488
491
LinkerScript::computeInputSections (const InputSectionDescription *cmd,
489
- ArrayRef<InputSectionBase *> sections) {
492
+ ArrayRef<InputSectionBase *> sections,
493
+ const OutputSection &outCmd) {
490
494
SmallVector<InputSectionBase *, 0 > ret;
491
495
SmallVector<size_t , 0 > indexes;
492
496
DenseSet<size_t > seen;
497
+ DenseSet<InputSectionBase *> spills;
493
498
auto sortByPositionThenCommandLine = [&](size_t begin, size_t end) {
494
499
llvm::sort (MutableArrayRef<size_t >(indexes).slice (begin, end - begin));
495
500
for (size_t i = begin; i != end; ++i)
@@ -505,12 +510,33 @@ LinkerScript::computeInputSections(const InputSectionDescription *cmd,
505
510
size_t sizeBeforeCurrPat = ret.size ();
506
511
507
512
for (size_t i = 0 , e = sections.size (); i != e; ++i) {
508
- // Skip if the section is dead or has been matched by a previous input
509
- // section description or a previous pattern .
513
+ // Skip if the section is dead or has been matched by a previous pattern
514
+ // in this input section description .
510
515
InputSectionBase *sec = sections[i];
511
- if (!sec->isLive () || sec-> parent || seen.contains (i))
516
+ if (!sec->isLive () || seen.contains (i))
512
517
continue ;
513
518
519
+ if (sec->parent ) {
520
+ // Skip if not allowing multiple matches.
521
+ if (!config->enableNonContiguousRegions )
522
+ continue ;
523
+
524
+ // Disallow spilling into /DISCARD/; special handling would be needed
525
+ // for this in address assignment, and the semantics are nebulous.
526
+ if (outCmd.name == " /DISCARD/" )
527
+ continue ;
528
+
529
+ // Skip if the section's first match was /DISCARD/; such sections are
530
+ // always discarded.
531
+ if (sec->parent ->name == " /DISCARD/" )
532
+ continue ;
533
+
534
+ // Skip if the section was already matched by a different input section
535
+ // description within this output section.
536
+ if (sec->parent == &outCmd)
537
+ continue ;
538
+ }
539
+
514
540
// For --emit-relocs we have to ignore entries like
515
541
// .rela.dyn : { *(.rela.data) }
516
542
// which are common because they are in the default bfd script.
@@ -530,6 +556,8 @@ LinkerScript::computeInputSections(const InputSectionDescription *cmd,
530
556
continue ;
531
557
532
558
ret.push_back (sec);
559
+ if (sec->parent )
560
+ spills.insert (sec);
533
561
indexes.push_back (i);
534
562
seen.insert (i);
535
563
}
@@ -555,6 +583,28 @@ LinkerScript::computeInputSections(const InputSectionDescription *cmd,
555
583
// Matched sections after the last SORT* are sorted by (--sort-alignment,
556
584
// input order).
557
585
sortByPositionThenCommandLine (sizeAfterPrevSort, ret.size ());
586
+
587
+ // Replace matches after the first with potential spill sections.
588
+ if (!spills.empty ()) {
589
+ for (InputSectionBase *&sec : ret) {
590
+ if (!spills.contains (sec))
591
+ continue ;
592
+
593
+ SpillInputSection *sis = make<SpillInputSection>(
594
+ sec, const_cast <InputSectionDescription *>(cmd));
595
+
596
+ // Append the spill input section to the list for the input section,
597
+ // creating it if necessary.
598
+ auto res = spillLists.try_emplace (sec, SpillList{sis, sis});
599
+ if (!res.second ) {
600
+ SpillInputSection *&tail = res.first ->second .tail ;
601
+ tail = tail->next = sis;
602
+ }
603
+
604
+ sec = sis;
605
+ }
606
+ }
607
+
558
608
return ret;
559
609
}
560
610
@@ -577,7 +627,7 @@ void LinkerScript::discardSynthetic(OutputSection &outCmd) {
577
627
part.armExidx ->exidxSections .end ());
578
628
for (SectionCommand *cmd : outCmd.commands )
579
629
if (auto *isd = dyn_cast<InputSectionDescription>(cmd))
580
- for (InputSectionBase *s : computeInputSections (isd, secs))
630
+ for (InputSectionBase *s : computeInputSections (isd, secs, outCmd ))
581
631
discard (*s);
582
632
}
583
633
}
@@ -588,7 +638,7 @@ LinkerScript::createInputSectionList(OutputSection &outCmd) {
588
638
589
639
for (SectionCommand *cmd : outCmd.commands ) {
590
640
if (auto *isd = dyn_cast<InputSectionDescription>(cmd)) {
591
- isd->sectionBases = computeInputSections (isd, ctx.inputSections );
641
+ isd->sectionBases = computeInputSections (isd, ctx.inputSections , outCmd );
592
642
for (InputSectionBase *s : isd->sectionBases )
593
643
s->parent = &outCmd;
594
644
ret.insert (ret.end (), isd->sectionBases .begin (), isd->sectionBases .end ());
@@ -644,6 +694,9 @@ void LinkerScript::processSectionCommands() {
644
694
645
695
// Process OVERWRITE_SECTIONS first so that it can overwrite the main script
646
696
// or orphans.
697
+ if (config->enableNonContiguousRegions && !overwriteSections.empty ())
698
+ error (" OVERWRITE_SECTIONS cannot be used with "
699
+ " --enable-non-contiguous-regions" );
647
700
DenseMap<CachedHashStringRef, OutputDesc *> map;
648
701
size_t i = 0 ;
649
702
for (OutputDesc *osd : overwriteSections) {
@@ -911,6 +964,13 @@ void LinkerScript::diagnoseMissingSGSectionAddress() const {
911
964
error (" no address assigned to the veneers output section " + sec->name );
912
965
}
913
966
967
+ void LinkerScript::copySpillList (InputSectionBase *dst, InputSectionBase *src) {
968
+ auto i = spillLists.find (src);
969
+ if (i == spillLists.end ())
970
+ return ;
971
+ spillLists.try_emplace (dst, i->second );
972
+ }
973
+
914
974
// This function searches for a memory region to place the given output
915
975
// section in. If found, a pointer to the appropriate memory region is
916
976
// returned in the first member of the pair. Otherwise, a nullptr is returned.
@@ -1066,8 +1126,16 @@ void LinkerScript::assignOffsets(OutputSection *sec) {
1066
1126
// Handle a single input section description command.
1067
1127
// It calculates and assigns the offsets for each section and also
1068
1128
// updates the output section size.
1069
- for (InputSection *isec : cast<InputSectionDescription>(cmd)->sections ) {
1129
+
1130
+ DenseSet<InputSection *> spills;
1131
+ auto §ions = cast<InputSectionDescription>(cmd)->sections ;
1132
+ for (InputSection *isec : sections) {
1070
1133
assert (isec->getParent () == sec);
1134
+
1135
+ // Skip all possible spills.
1136
+ if (isa<SpillInputSection>(isec))
1137
+ continue ;
1138
+
1071
1139
const uint64_t pos = dot;
1072
1140
dot = alignToPowerOf2 (dot, isec->addralign );
1073
1141
isec->outSecOff = dot - sec->addr ;
@@ -1364,6 +1432,107 @@ const Defined *LinkerScript::assignAddresses() {
1364
1432
return getChangedSymbolAssignment (oldValues);
1365
1433
}
1366
1434
1435
+ static bool isRegionOverflowed (MemoryRegion *mr) {
1436
+ if (!mr)
1437
+ return false ;
1438
+ return mr->curPos - mr->getOrigin () > mr->getLength ();
1439
+ }
1440
+
1441
+ // Spill input sections in reverse order of address assignment to (potentially)
1442
+ // bring memory regions out of overflow. The size savings of a spill can only be
1443
+ // estimated, since general linker script arithmetic may occur afterwards.
1444
+ // Under-estimates may cause unnecessary spills, but over-estimates can always
1445
+ // be corrected on the next pass.
1446
+ bool LinkerScript::spillSections () {
1447
+ if (!config->enableNonContiguousRegions )
1448
+ return false ;
1449
+
1450
+ bool spilled = false ;
1451
+ for (SectionCommand *cmd : reverse (sectionCommands)) {
1452
+ auto *od = dyn_cast<OutputDesc>(cmd);
1453
+ if (!od)
1454
+ continue ;
1455
+ OutputSection *osec = &od->osec ;
1456
+ if (!osec->size || !osec->memRegion )
1457
+ continue ;
1458
+
1459
+ DenseSet<InputSection *> spills;
1460
+ for (SectionCommand *cmd : reverse (osec->commands )) {
1461
+ if (!isRegionOverflowed (osec->memRegion ) &&
1462
+ !isRegionOverflowed (osec->lmaRegion ))
1463
+ break ;
1464
+
1465
+ auto *is = dyn_cast<InputSectionDescription>(cmd);
1466
+ if (!is)
1467
+ continue ;
1468
+ for (InputSection *isec : reverse (is->sections )) {
1469
+ // Potential spill locations cannot be spilled.
1470
+ if (isa<SpillInputSection>(isec))
1471
+ continue ;
1472
+
1473
+ // Find the next spill location.
1474
+ auto it = spillLists.find (isec);
1475
+ if (it == spillLists.end ())
1476
+ continue ;
1477
+
1478
+ spilled = true ;
1479
+ SpillList &list = it->second ;
1480
+
1481
+ SpillInputSection *spill = list.head ;
1482
+ if (!spill->next )
1483
+ spillLists.erase (isec);
1484
+ else
1485
+ list.head = spill->next ;
1486
+
1487
+ spills.insert (isec);
1488
+
1489
+ // Replace the next spill location with the spilled section and adjust
1490
+ // its properties to match the new location.
1491
+ *llvm::find (spill->isd ->sections , spill) = isec;
1492
+ isec->parent = spill->parent ;
1493
+ // The alignment of the spill section may have diverged from the
1494
+ // original, but correct assignment requires the spill's alignment,
1495
+ // not the original.
1496
+ isec->addralign = spill->addralign ;
1497
+
1498
+ // Record the reduction in overage.
1499
+ osec->memRegion ->curPos -= isec->getSize ();
1500
+ if (osec->lmaRegion )
1501
+ osec->lmaRegion ->curPos -= isec->getSize ();
1502
+ if (!isRegionOverflowed (osec->memRegion ) &&
1503
+ !isRegionOverflowed (osec->lmaRegion ))
1504
+ break ;
1505
+ }
1506
+ // Remove any spilled sections.
1507
+ if (!spills.empty ())
1508
+ llvm::erase_if (is->sections , [&](InputSection *isec) {
1509
+ return spills.contains (isec);
1510
+ });
1511
+ }
1512
+ }
1513
+
1514
+ return spilled;
1515
+ }
1516
+
1517
+ // Erase any potential spill sections that were not used.
1518
+ void LinkerScript::eraseSpillSections () {
1519
+ if (spillLists.empty ())
1520
+ return ;
1521
+
1522
+ // Collect the set of input section descriptions that contain potential
1523
+ // spills.
1524
+ DenseSet<InputSectionDescription *> isds;
1525
+ for (const auto &[_, list] : spillLists)
1526
+ for (SpillInputSection *s = list.head ; s; s = s->next )
1527
+ isds.insert (s->isd );
1528
+
1529
+ for (InputSectionDescription *isd : isds)
1530
+ llvm::erase_if (isd->sections ,
1531
+ [](InputSection *s) { return isa<SpillInputSection>(s); });
1532
+
1533
+ spillLists.clear ();
1534
+ }
1535
+
1367
1536
// Creates program headers as instructed by PHDRS linker script command.
1368
1537
SmallVector<PhdrEntry *, 0 > LinkerScript::createPhdrs () {
1369
1538
SmallVector<PhdrEntry *, 0 > ret;
0 commit comments