ld: Question about the string merging feature

Ludwig Rydberg ludwig.rydberg@gaisler.com
Thu Jun 13 10:59:48 GMT 2024


Dear maintainers,

I have a question about the string merging feature of the GNU linker 
which seems to be doing things a bit differently since the 2.41 release.

When I specify multiple inputs (including text,data,rodata) in an output
section the order seems not to be considered/preserved for the mergeable
strings. Instead all mergeable strings are written into the first 
matching section.

Here follows an example that explains what I see.

main.c:
extern const char* foo_str;
extern const char* bar_str1;
extern const char* bar_str2;
extern const char* baz_str1;

int run()
{
     return 0;
}

foo.c
const char *foo_str = "FOO_STR1";

bar1.c:
const char *bar_str1 = "BAR_STR1";

bar2.c:
const char *bar_str2 = "BAR_STR2";

baz.c:
const char *baz_str = "BAZ_STR";

link.lds:
ENTRY(run)
SECTIONS {
   .my_section (READONLY) : {
       *foo*.o(.*data*);
       *foo*.o(.text);

       *bar*.o(.text);
       *bar*.o(.*data*);

       *(.text);
       *(.*data*);
   }
   .bss : { *(.bss); *(.bss.*) }
}

The files are compiled (using gcc 11.4 with -fmerge-constants enabled) 
and linked:

gcc -fmerge-constants -c *.c
ld foo.o bar1.o bar2.o main.o baz.o -T link.lds

The output of the section looks like this before 2.41:

Contents of section .my_section:
  0000 08000000 00000000 464f4f5f 53545231  ........FOO_STR1
  0010 000f1f80 00000000 20000000 00000000  ........ .......
  0020 4241525f 53545231 000f1f80 00000000  BAR_STR1........
  0030 38000000 00000000 4241525f 53545232  8.......BAR_STR2
  0040 00554889 e5b80000 00005dc3 0f1f4000  .UH.......]...@.
  0050 58000000 00000000 42415a5f 53545231  X.......BAZ_STR1
  0060 00

Here we see that the sections and strings are written in the order as
specified in the linker script (i.e first *data* and then *text* from foo).

 From 2.41 (and newer) it looks like this:

Contents of section .my_section:
  0000 08000000 00000000 464f4f5f 53545231  ........FOO_STR1
  0010 00424152 5f535452 31004241 525f5354  .BAR_STR1.BAR_ST
  0020 52320042 415a5f53 54523100 0f1f4000  R2.BAZ_STR1...@.
  0030 11000000 00000000 1a000000 00000000  ................
  0040 554889e5 b8000000 005dc30f 1f440000  UH.......]...D..
  0050 23000000 00000000                    #.......

Now all strings from all inputs are merged and written at the same 
location. Hence, the order of the inputs (as they are stated in the 
linker script) seems not to be considered.

By bisecting the source I found that this was changed by the following 
commit: 1a528d3ef07f ("Faster string merging")

My question is what to expect here? Was this change intended and part of 
the work with the "Faster string merging" feature?

Best regards,
// Ludwig



More information about the Binutils mailing list