[lld] [LLD] Add CLASS syntax to SECTIONS (PR #95323)

Daniel Thornburgh via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 30 14:54:22 PDT 2024


================
@@ -717,14 +752,66 @@ void LinkerScript::processSectionCommands() {
       } else if (process(osec)) {
         osec->sectionIndex = i++;
       }
+    } else if (auto *sc = dyn_cast<SectionClassDesc>(base)) {
+      for (InputSectionDescription *isd : sc->sc.commands) {
+        isd->sectionBases =
+            computeInputSections(isd, ctx.inputSections, sc->sc);
+        for (InputSectionBase *s : isd->sectionBases) {
+          // Section classes with --enable-non-contiguous-regions may contain
+          // parented classes; spills for these are generated on reference.
+          if (!s->parent)
+            s->parent = &sc->sc;
+        }
+      }
+      sc->sc.assigned = true;
+    }
+  }
+
+  // Check that input sections cannot spill into or out of INSERT,
+  // since the semantics are nebulous. This is also true for OVERWRITE_SECTIONS,
+  // but no check is needed, since the order of processing ensures they cannot
+  // legally reference classes.
+  if (!potentialSpillLists.empty()) {
+    DenseSet<StringRef> insertNames;
+    for (InsertCommand &ic : insertCommands)
+      insertNames.insert(ic.names.begin(), ic.names.end());
+    for (SectionCommand *&base : sectionCommands) {
+      auto *osd = dyn_cast<OutputDesc>(base);
+      if (!osd)
+        continue;
+      OutputSection *os = &osd->osec;
+      if (!insertNames.contains(os->name))
+        continue;
+      for (SectionCommand *sc : os->commands) {
+        auto *isd = dyn_cast<InputSectionDescription>(sc);
+        if (!isd)
+          continue;
+        for (InputSectionBase *isec : isd->sectionBases)
+          if (isa<PotentialSpillSection>(isec) ||
+              potentialSpillLists.contains(isec))
+            errorOrWarn("section '" + isec->name +
+                        "' cannot spill from/to INSERT section '" + os->name +
+                        "'");
+      }
     }
+  }
 
   // If an OVERWRITE_SECTIONS specified output section is not in
   // sectionCommands, append it to the end. The section will be inserted by
   // orphan placement.
   for (OutputDesc *osd : overwriteSections)
     if (osd->osec.partition == 1 && osd->osec.sectionIndex == UINT32_MAX)
       sectionCommands.push_back(osd);
+
+  // Input sections cannot have a section class parent past this point; they
+  // must have been assigned to an output section.
+  for (const auto &[_, sc] : sectionClasses)
+    for (InputSectionDescription *isd : sc->sc.commands)
+      for (InputSectionBase *sec : isd->sectionBases)
+        if (sec->parent && isa<SectionClass>(sec->parent))
+          errorOrWarn("section '" + sec->name + "' assigned to class '" +
----------------
mysterymath wrote:

Simplified the comment along these lines and made it only report once per class.

https://github.com/llvm/llvm-project/pull/95323


More information about the llvm-commits mailing list