Re: [patch] AVR: Sort .text.* input sections by their name.
Georg-Johann Lay via Binutils <[email protected]> Tue, 21 Jul 2026 10:26:37 +0200
| Newsgroups | gmane.comp.gnu.binutils |
|---|---|
| Message-ID | <[email protected]> |
Am 21.07.26 um 07:46 schrieb Alan Modra:
> On Mon, Jul 20, 2026 at 08:44:51PM +0200, Georg-Johann Lay via Binutils wrote:
>> This patch sorts the .text.* input sections by their name
>> in order to increase code locality, e.g. for code from
>> libgcc and AVR-LibC. For example, libgcc puts their
>> multiplications and helpers in .text.libgcc.mul, but
>> without SORT the linker may locate functions related by
>> their input section far apart, inserting function from
>> unrelated input sections in between them.
>
> While you may have found one particular case where sorting by name
> helps, I suspect this is generally not a good idea. I believe in
> general you will make -ffunction-sections code locality worse by using
> this patch. Consider an object file with lots of small functions,
> calls mostly within that object file. You don't want to sort them
> such that functions from other object files separate them.
What really confused me is that LD my locate objects in the /same/
input section /not/ together, like with the
*(.text.*)
pattern from the current default linker scripts may result in
locations like:
0x200 funcA1 // in .text.A
0x300 funcB // in .text.B
0x400 funcA2 // in .text.A
so that funcB separates funcA1 and funcA2. Libs like libc and libgcc
usually have one function per object module and use sections like
.text.libgcc.mul for related stuff like mul helpers in the assumption
that stuff in the same input section will be close together.
Why aren't funcA1 and funcA2 put into one contiguous "block" of code?
The order of funvA1 and funcA2 doesn't really matter, some for the
placement of .text.A relative to .text.B. But stuff in the /same/
input section should be put together, no?
What's the locator algorithm? As far as I know it just spits out
the stuff as it iterates over a hash table of objects?
Or does it try to minimize lengths in a dependency graph?
Like when there is a reference between fun1 and fun2 and
one between fun2 and fun3 but none between fun1 and fun3,
then minimizing web distance would be an allocation like
fun1, fun2, fun3 or fun3, fun2, fun1. But optimizing that
would be expensive.
>> PR ld/34415
>> ld/
>> * scripttempl/avr.sc (text): SORT *(.text.*) input sections.
>> by their name.
>>
>> diff --git a/ld/scripttempl/avr.sc b/ld/scripttempl/avr.sc
>> index b3cf421a78b..e918181700b 100644
>> --- a/ld/scripttempl/avr.sc
>> +++ b/ld/scripttempl/avr.sc
>> @@ -248,7 +248,7 @@ cat <<EOF
>> KEEP (*(.init9))}
>> *(.text)
>> ${RELOCATING+. = ALIGN(2);
>> - *(.text.*)
>> + *(SORT(.text.*))
>> . = ALIGN(2);
>> *(.fini9) /* _exit() starts here. */
>> KEEP (*(.fini9))