@@ -304,6 +304,9 @@ getChangedSymbolAssignment(const SymbolAssignmentMap &oldValues) {
304304void LinkerScript::processInsertCommands () {
305305 SmallVector<OutputDesc *, 0 > moves;
306306 for (const InsertCommand &cmd : insertCommands) {
307+ if (config->enableNonContiguousRegions )
308+ error (" INSERT cannot be used with --enable-non-contiguous-regions" );
309+
307310 for (StringRef name : cmd.names ) {
308311 // If base is empty, it may have been discarded by
309312 // adjustOutputSections(). We do not handle such output sections.
@@ -486,10 +489,12 @@ static void sortInputSections(MutableArrayRef<InputSectionBase *> vec,
486489// Compute and remember which sections the InputSectionDescription matches.
487490SmallVector<InputSectionBase *, 0 >
488491LinkerScript::computeInputSections (const InputSectionDescription *cmd,
489- ArrayRef<InputSectionBase *> sections) {
492+ ArrayRef<InputSectionBase *> sections,
493+ const OutputSection &outCmd) {
490494 SmallVector<InputSectionBase *, 0 > ret;
491495 SmallVector<size_t , 0 > indexes;
492496 DenseSet<size_t > seen;
497+ DenseSet<InputSectionBase *> spills;
493498 auto sortByPositionThenCommandLine = [&](size_t begin, size_t end) {
494499 llvm::sort (MutableArrayRef<size_t >(indexes).slice (begin, end - begin));
495500 for (size_t i = begin; i != end; ++i)
@@ -505,12 +510,33 @@ LinkerScript::computeInputSections(const InputSectionDescription *cmd,
505510 size_t sizeBeforeCurrPat = ret.size ();
506511
507512 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 .
510515 InputSectionBase *sec = sections[i];
511- if (!sec->isLive () || sec-> parent || seen.contains (i))
516+ if (!sec->isLive () || seen.contains (i))
512517 continue ;
513518
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+
514540 // For --emit-relocs we have to ignore entries like
515541 // .rela.dyn : { *(.rela.data) }
516542 // which are common because they are in the default bfd script.
@@ -530,6 +556,8 @@ LinkerScript::computeInputSections(const InputSectionDescription *cmd,
530556 continue ;
531557
532558 ret.push_back (sec);
559+ if (sec->parent )
560+ spills.insert (sec);
533561 indexes.push_back (i);
534562 seen.insert (i);
535563 }
@@ -555,6 +583,28 @@ LinkerScript::computeInputSections(const InputSectionDescription *cmd,
555583 // Matched sections after the last SORT* are sorted by (--sort-alignment,
556584 // input order).
557585 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+
558608 return ret;
559609}
560610
@@ -577,7 +627,7 @@ void LinkerScript::discardSynthetic(OutputSection &outCmd) {
577627 part.armExidx ->exidxSections .end ());
578628 for (SectionCommand *cmd : outCmd.commands )
579629 if (auto *isd = dyn_cast<InputSectionDescription>(cmd))
580- for (InputSectionBase *s : computeInputSections (isd, secs))
630+ for (InputSectionBase *s : computeInputSections (isd, secs, outCmd ))
581631 discard (*s);
582632 }
583633}
@@ -588,7 +638,7 @@ LinkerScript::createInputSectionList(OutputSection &outCmd) {
588638
589639 for (SectionCommand *cmd : outCmd.commands ) {
590640 if (auto *isd = dyn_cast<InputSectionDescription>(cmd)) {
591- isd->sectionBases = computeInputSections (isd, ctx.inputSections );
641+ isd->sectionBases = computeInputSections (isd, ctx.inputSections , outCmd );
592642 for (InputSectionBase *s : isd->sectionBases )
593643 s->parent = &outCmd;
594644 ret.insert (ret.end (), isd->sectionBases .begin (), isd->sectionBases .end ());
@@ -644,6 +694,9 @@ void LinkerScript::processSectionCommands() {
644694
645695 // Process OVERWRITE_SECTIONS first so that it can overwrite the main script
646696 // or orphans.
697+ if (config->enableNonContiguousRegions && !overwriteSections.empty ())
698+ error (" OVERWRITE_SECTIONS cannot be used with "
699+ " --enable-non-contiguous-regions" );
647700 DenseMap<CachedHashStringRef, OutputDesc *> map;
648701 size_t i = 0 ;
649702 for (OutputDesc *osd : overwriteSections) {
@@ -911,6 +964,13 @@ void LinkerScript::diagnoseMissingSGSectionAddress() const {
911964 error (" no address assigned to the veneers output section " + sec->name );
912965}
913966
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+
914974// This function searches for a memory region to place the given output
915975// section in. If found, a pointer to the appropriate memory region is
916976// returned in the first member of the pair. Otherwise, a nullptr is returned.
@@ -1066,8 +1126,16 @@ void LinkerScript::assignOffsets(OutputSection *sec) {
10661126 // Handle a single input section description command.
10671127 // It calculates and assigns the offsets for each section and also
10681128 // 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) {
10701133 assert (isec->getParent () == sec);
1134+
1135+ // Skip all possible spills.
1136+ if (isa<SpillInputSection>(isec))
1137+ continue ;
1138+
10711139 const uint64_t pos = dot;
10721140 dot = alignToPowerOf2 (dot, isec->addralign );
10731141 isec->outSecOff = dot - sec->addr ;
@@ -1364,6 +1432,107 @@ const Defined *LinkerScript::assignAddresses() {
13641432 return getChangedSymbolAssignment (oldValues);
13651433}
13661434
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+
13671536// Creates program headers as instructed by PHDRS linker script command.
13681537SmallVector<PhdrEntry *, 0 > LinkerScript::createPhdrs () {
13691538 SmallVector<PhdrEntry *, 0 > ret;
0 commit comments