https://sourceware.org/bugzilla/show_bug.cgi?id=26404
Bug ID: 26404 Summary: ld: INSERT [AFTER|BEFORE] variant for extension purposes Product: binutils Version: unspecified Status: UNCONFIRMED Severity: normal Priority: P2 Component: ld Assignee: unassigned at sourceware dot org Reporter: i at maskray dot me Target Milestone: --- `SECTIONS { ... } INSERT [AFTER|BEFORE]` complements the internal linker script. This is nice: because in many cases the internal one works quite well and the user does not want to reset the internal linker script. Users tend to leverage this property to provide extensions to the internal linker script. However, the section anchor after [AFTER|BEFORE] makes extensions somewhat cumbersome: there may not be a suitable anchor or the user just does not want to set an anchor. The default orphan placement works well. On one occasion, I've seen a user who wants to write: .note.gnu.build-id : { PROVIDE_HIDDEN (__build_id_start = . + 16); *(.note.gnu.build-id) PROVIDE_HIDDEN (__build_id_end = .); } // __build_id_start / __build_id_end delimiters the build ID payload (16 is // the size of the note header) On another occasion, a user wants to assign some sections KEEP semantics (https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep) but does not want to provide an external linker script. I have sympathy with both feature requests but cannot convince myself that the use cases are beyond the ad-hoc category. A natural generalization is that we can have a syntax similar to INSERT [AFTER|BEFORE] but does not require an anchor. About the syntax, * Suggestion (a) EXTEND SECTIONS { // another keyword can be used, e.g. OVERRIDE .foo : { KEEP(*(.foo)) } .bar : { KEEP(*(.bar)) } sym = .; // symbol assignments are disallowed } // What if the internal linker script defines .foo as well? * Suggestion (b) SECTIONS { .foo : { KEEP(*(.foo)) } .bar : { KEEP(*(.bar)) } sym = .; // symbol assignments are disallowed } EXTEND; * Suggestion (c) SECTIONS { .foo : { KEEP(*(.foo)) } .bar : { KEEP(*(.bar)) } } REPLACE .data; // If the internal linker script defines .data, replace it with the content in // the braces. Otherwise, treat .foo and .bar as orphans? --- Some properties and edge cases need thoughts, e.g. * It had better not interfere with normal orphan placement. * When an output section is described by both the internal linker script and the external one, what should happen? For INSERT, the interaction is currently undocumented. It seems that the internal one is applied first, followed by the description from INSERT AFTER|BEFORE, e.g. SECTIONS { .data : { data_begin = .; *(.data) }} INSERT BEFORE .bss; // place .data.* into .data because the internal description does so. SECTIONS { .data : { data_begin = .; *(.data) *(.data1) }} INSERT BEFORE .bss; // place .data1 into .data --- For the two feature requests, I think they don't need to define semantics when there is a collision. The important thing is to have a syntax (not getting in the way in the future). The collision cases can be considered "undefined behaviors" for now. -- You are receiving this mail because: You are on the CC list for the bug.