Re: [patch] AVR: Sort .text.* input sections by their name.

Alan Modra <[email protected]> Tue, 21 Jul 2026 20:29:13 +0930
Newsgroups gmane.comp.gnu.binutils
Message-ID <[email protected]>
On Tue, Jul 21, 2026 at 10:26:37AM +0200, Georg-Johann Lay wrote:
> 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?

Conceptually the linker iterates over sections in each input file in
the order they appear in the file, with input files in the order they
appear on the command line (or are extracted from archives), placing
sections at the first input section statement match in the linker
script.  If there is no match (an orphan section) it is placed in an
output section of the same name as the input, with ld choosing a
reasonable place for that output section if it doesn't already exist.

One of the reasons you might not want to put .text.A sections together
is when compiling commonly named functions with -ffunction-sections.
For example, a static setup() function might occur in many input
files.  If all .text.setup sections were mashed together then some
would be placed far away from their callers.

> 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))

-- 
Alan Modra