Mapping symbol optimization: implicit one at section beginning

Fangrui Song i@maskray.me
Mon Jul 29 07:55:50 GMT 2024


On Mon, Jul 22, 2024 at 11:24 PM Jan Beulich <jbeulich@suse.com> wrote:
>
> On 22.07.2024 20:37, Fangrui Song wrote:
> > I have written a detailed analysis at
> > https://maskray.me/blog/2024-07-21-mapping-symbols-rethinking-for-efficiency
> > and proposed an alternative scheme to address the size concern:
> >
> > * Text sections: Assume an implicit $x at offset 0. Add an ending $x
> > if the final data isn't instructions.
> > * Non-text sections: Assume an implicit $d at offset 0. Add an ending
> > $d only if the final data isn't data commands.
> >
> > This approach eliminates most mapping symbols while ensuring correct
> > disassembly. Here is an illustrated assembler example:
> >
> > .section .text.f0,"ax"
> >   ret
> > // emit $d
> >   .long 42
> > // emit $x. Without this, .text.f1 might be interpreted as data.
>
> I don't understand this. Whether such a $x would apply to ...
>
> > .section .text.f1,"ax"
> >   ret
>
> ... the section following in source code is entirely unknown until
> linking time. And that $x doesn't help ...

Thanks for the response!

The $x works for the common case where this text section is followed
by another text section (instead of data section) that starts with
instructions.
The combined result will make sense even without a smart linker.

> > However, omitting a mapping symbol at offset 0 for sections with
> > instructions is currently non-conformant for Arm. An ABI update has
> > been requested to address this
> > (https://github.com/ARM-software/abi-aa/issues/274). RISC-V ABI
> > doesn't have the requirement.
> >
> > **While some interoperability concerns might arise, they're unlikely
> > to impact a majority of users.**
> >
> > For instance, if a text section with trailing data is assembled using
> > the traditional behavior, the last mapping symbol will be $d. When
> > linked with another text section assembled using the new behavior
> > (lacking an initial $x), disassemblers might misinterpret the start of
> > the latter section as data.
> >
> > Similarly, linker scripts that combine non-text and text sections
> > could lead to text sections appearing in a data state.
>
> ... with this situation at all. It may need to be the linker to insert
> such mapping symbols when there's none at the start of a section, and
> the "exit state" of the earlier one doesn't match default state for
> that following section.
>
> However, it may be that with ...

Right. There are interoperability concerns for a few scenarios that
unlikely impact a majority of users.

* "if a text section with trailing data is assembled using the
traditional behavior, the last mapping symbol will be $d. When linked
with another text section assembled using the new behavior (lacking an
initial $x),"
* "linker scripts that combine non-text and text sections"
* "A text section may rarely start with data directives" (also
discussed here:
https://github.com/ARM-software/abi-aa/issues/274#issuecomment-2246782514)

> > Ultimately, the proposed alternative scheme effectively addresses
> > symbol table bloat, but requires careful consideration for compliance
> > and interoperability.
> > I have thought about **an assembler option
> > --[no-]optimize-mapping-symbols**, which can be enabled by GCC as
> > -Wa,--optimize-mapping-symbols.
> > With this optimization enabled, most mapping symbols will be
> > eliminated for architectures that don't often place constant
> > pools/jump tables in text sections.
> > This optimization works well when there is a single code state (e.g.
> > AArch64) and can be extended when there are more states.
>
> ... this proposal you really mean to leave the choice to the programmer,
> in the hope that they're fully overseeing how objects are going to be
> linked (which imo isn't always the case, especially when thinking about
> library code).

Right. This programmer choice would work well for build systems with
(nearly) all relocatable files under control

> Just one remark on the suggested command line option itself: I consider
> it overly long. Would you foresee any ambiguity when reducing to e.g.
> --optimize-mapsyms?

--optimize-mapsyms works for me :)

> > RISC-V $x<isa> poses some challenges:
> > https://maskray.me/blog/2024-07-21-mapping-symbols-rethinking-for-efficiency#risc-v-isa-extension
>
> I don't think these can be optimized away when at the start of a
> section. Unless there was an object-file-wide indication of the "base"
> ISA, which the linker could then use to determine where to synthesize
> mapping symbols at section boundaries.

Right. gas's riscv port currently emits something like
`$xrv64i2p0_m2p0_a2p0_f2p0_d2p0_zmmul1p0`, which could not be
eliminated without a base ISA indication.
LLVM integrated assembler currently emits `$x`, which could use the
proposed AArch64 optimization technique.
My mentioning RISC-V ISA is to raise awareness that this is
significant code size bloat from overly describing things...


More information about the Binutils mailing list