[Patch] ld: Fix string merging origin symbol address
Michael Matz
matz@suse.de
Tue Apr 8 12:52:35 GMT 2025
Hello,
On Mon, 7 Apr 2025, Guillaume VACHERIAS - foss wrote:
> What I wanted to point out was not a problem on the resolved address in
> the final binary itself, which is correct, but rather on the information
> that the map file generates. After the optimization of string merging
> contributions (1a528d3ef07fc6084fc51759c1b2f8abb5c8127e), the
> information generated by the map file is less precise.
Ah, I see. IIRC, I alluded to that somewhat in my mail for that patch.
FWIW, I don't consider it a good tradeoff to use a pointer entry for each
string pointing back to the original section info it came from just for
generating a different Map file. These entries tend to become fairly
large on bigger testcases.
Also, does it even work in the current state? Emitting only strings from
a certain input section like you do in sec_merge_emit requires that they
are also sorted primarily in that way. That logic seems to partly come
from before my patch and that whole dealing with individual secinfos gave
me headaches already back then. I wholeheartedly suggest to not
re-introduce it again, and if possible rather get rid of more of their use
(some of the asserts I added point into that direction, though I haven't
followed through with that).
> More specifically, the map file can no longer provide the address where
> a string from an input section .rodata is in the final binary.
And it generally can't in the case of merged sections. I think it's
futile to try and give the impression that it could when it really cannot.
> Taking the testcase that I've added as an example. The only mergeable
> string would be "i" since it is the suffix of "ghi" and everything else
> is different. However, when we run the testcase with current string
> merge, it results in the following map file:
>
> .rodata 0x00000000 0xc
> *(.rodata*)
> .rodata.foo.str1.1
> 0x00000000 0xc tmpdir/rodata-merge-map-address1.o
> 0x4 (size before relaxing)
> .rodata.bar.str1.1
> 0x0000000c 0x4 tmpdir/rodata-merge-map-address2.o
> .rodata.baz.str1.1
> 0x0000000c 0x6 tmpdir/rodata-merge-map-address3.o
>
> The string merging mechanism makes it as the very first object file
> contains all strings, the .rodata.foo.str1.1 indicates that its length
> is 0xc where it was supposed to be only 0x4 as it only contributes
> "abc". This results in that the other 2 sections .rodata.bar.str1.1 and
> .rodata.bar.str1.1 seems to be placed at the end of of the .rodata
> section.
Well, that is what conceptually happens. As the original sections
contents are completely mixed up in the final blob, including being
arbitrarily reordered, completely removed, or tucked somewhere into the
middle, the original sections aren't placed anywhere specifically. We
could say "merged into ..." or something like that, but saying it has an
address A and size S in the final result is always wrong except in the
simplest testcases that don't merge much or anything. Claiming it has an
address and a size means claiming that its contents are consecutive in the
result, which isn't generally true.
That the whole blob is regarded as belonging to the first of mergable
sections is a wart, but that's what the bfd linker generally does: even
linker generated sections "belong" to the first input file in many cases.
The only thing that I think would be left to improve in the above Mapfile
output is the size after relaxing of the other input sections:
make them all zero. Then the given information in the map file adds up
and it correctly captures the concept of all sections contents to be going
through a special process and be completely subsumed by it.
> The correct map file information that used to be generated which also
> indicates that "i" has been merged is:
>
> .rodata 0x00000000 0xc
> *(.rodata*)
> .rodata.foo.str1.1
> 0x00000000 0x4 .*rodata-merge-map-address1.o
> .rodata.bar.str1.1
> 0x00000004 0x4 .*rodata-merge-map-address2.o
> .rodata.baz.str1.1
> 0x00000008 0x4 .*rodata-merge-map-address3.o
> 0x6 (size before relaxing)
I think its only superficially "more correct".
Can I ask you why you want that info in the Map file to be better? What
do you do with it, and how comes that whatever that is doesn't break in
more complicated testcases that do merge a number of meaningful entries?
Ciao,
Michael.
More information about the Binutils
mailing list