This is interesting; I hadn't thought of breaking out tagging into its own construct. I do like the name SECTION_CLASS; it makes it clear that elements from that section could be placed there, and the only plausible meaning for multiple references to the same class would be to allow them to spill. This also slightly increases the power of regular matching, since you could catch a group of sections earlier in a linker script and place them later, perhaps to avoid a broad wildcard needed for output sections that should appear earlier in a memory region. E.g. ``` SECTIONS { SECTION_CLASS(specific) { *(.specific) } .first_output { *(*) } >m1 .second_output { SECTION_CLASS(specific) } >m1 } ``` On the down side, it would make it harder to port existing linker scripts. To spill a wildcard match inside an output section with strong ordering requirements, you would need to define classes for anything that precedes it. Without spilling: ``` SECTIONS { .foo { *(.foo.first.*) . = . < 0xc000 ? 0xc000 : .; /* or something similarly horrible */ *(.foo.second.*) /* Excludes .foo.first.* and .foo.second.* by virtue of ordering */ *(.foo.*) }>m1 } ``` With spilling: ```SECTIONS { /* A whole collection now needs to be broken out of the output section to preserve its semantics */ SECTION_CLASS(foo_first) { *(.foo.first.*) } SECTION_CLASS(foo_second) { *(.foo.second.*) } /* If only this section class were defined, then it would unintentionally capture .foo.first and .foo.second */ SECTION_CLASS(foo_rest) { *(.foo.*) } .foo { SECTION_CLASS(foo_first) . = . < 0xc000 ? 0xc000 : .; SECTION_CLASS(foo_second) SECTION_CLASS(foo_rest) }>m1 .foo_alt { /* foo_rest is the only desirable spill, but it forces sweeping changes to the linker script */ SECTION_CLASS(foo_rest) }>m2 } ``` Progressive enhancement of existing scripts is essential for this to be useful in practice. As far as I can see, since linker script semantics are so imperative, that requires section classes to be nameable in the same place as existing wildcards. That being said, as mentioned earlier, naming outside output sections also adds power, so it might be useful too, but it seems like it would need to be judged on merit of the extra power added. On Tue, Feb 6, 2024 at 4:33 PM Roland McGrath wrote: > ``` > SECTIONS { /* New syntax that is not an output section clause: */ > SECTION_CLASS(class1) { *(.input2) } > > /* Output section clause referring to SECTION_CLASS: */ > .output2 { > *(.input3) /* normal section wildcard */ > > SECTION_CLASS(class1) /* reference to previously defined class */ > > *(.input4) /* normal section wildcard */ > } > .output4 { > /* reference to remainder not in .output[23], sorting applied to them > */ > SORT_BY_NAME(SECTION_CLASS(class1)) > } > } > ``` > Where they do appear, they can appear inside the SORT_* to have that > sorting applied to the subset. I'm not sure it's actually meaningful to > select a subset and then sort within that subset, so perhaps it would be > better to only support the SORT_* modifiers in the usual way on the input > section wildcards in the defining `SECTION_CLASS` clause, and then every > reference has to always just draw in order from that sorted list. > I would expect SECTION_CLASS uses in output sections to be referentially transparent with the exception of the packing behavior and the ordering of section "consumption". They should broadly behave as if the named wildcards had actually appeared in order in the corresponding location; that should allow providing a set of allowed and disallowed SORT_x family specifications to match the current behavior. That would support using SECTION_CLASS to break out an existing wildcard to run it earlier, since it would provide some assurance that this wouldn't change the behavior beyond that which was intended. -- Daniel Thornburgh | dthorn@google.com