13. Linker Image Size Optimizations
13.1. Merging constants
ELD can merge identical constant data in mergeable, non-string input sections.
These sections are commonly emitted as .rodata.cst* sections with the
SHF_MERGE flag. Constant merging reduces duplicate bytes in .rodata and
related mergeable constant sections while preserving references to the data.
At a high level, ELD:
identifies identical constant payloads,
respects merge semantics such as entry size and alignment,
keeps one canonical constant payload, and
retargets eligible merge-kind relocations to that canonical payload.
13.1.1. Alignment compatibility
An identical payload is merged only when its input offset and section
alignment can satisfy the same output address. For an input offset O in a
section aligned to A, the output address X must satisfy:
X = O (mod A)
Two occurrences are compatible only when:
(O1 - O2) is divisible by gcd(A1, A2)
For example, a 4-byte constant at offset 0 in an 8-byte-aligned section and
the same constant at offset 4 in a 16-byte-aligned section cannot be merged:
b.o: X = 0 (mod 8)
c.o: X = 4 (mod 16)
Here, gcd(8, 16) = 8, but 0 - 4 is not divisible by 8. The first
occurrence requires an 8-byte-aligned address, while the second requires an
address 4 bytes past a 16-byte boundary, so ELD keeps both copies. In
contrast, offsets 0 and 8 with the same section alignments are compatible
and may share one output address.
13.1.2. Interaction with garbage collection
Garbage collection runs before constant merging in the normal final-link flow.
Consequently, discarded input sections do not contribute candidates, and only
live sections participate in canonicalization. Enabling --gc-sections can
therefore reduce both the direct data size and the set of constants available
for merging.
13.1.3. Map-file representation
In text map files, merged constants are represented by a surviving canonical input-section entry followed by comment lines for merged contributors. For example:
.rodata.cst4 <out_off> <size> <file2.o> #SHT_PROGBITS,SHF_ALLOC|SHF_MERGE,4
# .rodata.cst4 0x0 <file1.o>
The non-comment line identifies the canonical contributor retained in the layout. Comment-prefixed entries identify input sections merged into that storage. See linker map files for general map-file navigation.
13.1.4. Disabling constant merging
Use --no-merge-constants to disable canonicalization of mergeable constant
data. This can be useful when debugging layout or address-sensitive issues, or
when measuring the size contribution of constant merging independently.
Example A/B comparison:
ld.eld foo.o bar.o -o app.default.elf
ld.eld --no-merge-constants foo.o bar.o -o app.nomergeconst.elf
readelf -S -W app.default.elf app.nomergeconst.elf