RFC: Closing memory leaks to reduce the BFD linker's memory profile
Nick Clifton
nickc@redhat.com
Fri Jan 9 15:39:48 GMT 2026
Hi Guys,
One of the problems with the BFD linker is that it uses a lot of
memory. Especially when compared to other linkers. This issue came
to light recently in an unexpected way when the Envoy Proxy project
discovered that they could not switch from ld.gold to ld.bfd because
the CI system used by GitHub uses instances with a restricted amount
of memory and these instances were crashing during testing.
So I have been investigating the memory usage of the linker, looking
for easy ways to reduce the memory profile. One thought that did come
to mind is that the linker leaks a lot of memory. If this memory
could be released as soon as it was no longer needed then there is a
good chance that the overall memory profile of the linker would be
reduced.
A quick check with valgrind showed that one of the largest leaks comes
from the wildcard matching code in ldlang.c:
==1431789== 88,703,000 bytes in 88,703 blocks are still reachable in loss record 117 of 118
==1431789== at 0x49C3B26: malloc (vg_replace_malloc.c:447)
==1431789== by 0x4AD93C3: xmalloc (xmalloc.c:149)
==1431789== by 0x4051E26: call_chunkfun (obstack.c:94)
==1431789== by 0x4051E26: _obstack_newchunk (obstack.c:206)
==1431789== by 0x400EF42: stat_alloc (ldlang.c:189)
==1431789== by 0x4020D1D: new_statement (ldlang.c:1186)
==1431789== by 0x4020D1D: add_matching_section (ldlang.c:460)
==1431789== by 0x4020D1D: walk_wild_section_match (ldlang.c:543)
==1431789== by 0x4020D1D: resolve_wild_sections.part.0.lto_priv.0 (ldlang.c:1024)
==1431789== by 0x400D524: resolve_wild_sections (ldlang.c:1008)
==1431789== by 0x400D524: resolve_wilds.lto_priv.0 (ldlang.c:1047)
==1431789== by 0x401EA48: lang_process (ldlang.c:8555)
==1431789== by 0x400382D: main (ldmain.c:882)
(This result comes from linking Clang's llc executable. A nice big
test...)
So I created a patch that frees the memory when it is no longer
needed. (See attached in case you are interested). Since freeing the
memory involves walking over lists of section patterns however, and
the BFD linker is already the slowest of them all, I decided that the
new code should only be enabled when --reduce-memory-overheads is in
operation.
With this patch in place the leak is closed and the memory use as
reported by valgrind goes from:
in use at exit: 481,834,373 bytes in 3,572,602 blocks
to:
in use at exit: 336,141,893 bytes in 27,250 blocks
However the total amount of memory allocations jumps by a huge amount:
total heap usage: 10,491,826 allocs, 6,919,224 frees, 17,986,487,171 bytes allocated
to:
total heap usage: 13,225,597 allocs, 13,198,347 frees, 793,738,870,333 bytes allocated
And the time taken for the compilation goes from:
Time spent in user mode (CPU seconds) : 323.386
to:
Time spent in user mode (CPU seconds) : 3887.720
Some this is presumably because other effects caused by using the
--reduce-memory-overheads command line option to enable the leak
closure. But overall I am wondering whether this is actually a useful
exercise or if I should be looking elsewhere for memory savings.
Cheers
Nick
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ld.lang.memory.leak.patch
Type: text/x-patch
Size: 2662 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/binutils/attachments/20260109/35af2b08/attachment-0001.bin>
More information about the Binutils
mailing list