Similar to D69607 but for archive member extraction unrelated to GC. This patch adds --why-extract=.
Prior art:
GNU ld -M prints
Archive member included to satisfy reference by file (symbol) a.a(a.o) main.o (a) b.a(b.o) (b())
-M is mainly for input section/symbol assignment <-> output section mapping
(often huge output) and the information may appear ad-hoc.
Apple ld64
__Z1bv forced load of b.a(b.o) _a forced load of a.a(a.o)
It doesn't say the reference file.
Arm's proprietary linker
Selecting member vsnprintf.o(c_wfu.l) to define vsnprintf. ... Loading member vsnprintf.o from c_wfu.l. definition: vsnprintf reference : _printf_a
--why-extract= gives the user the full data (which is much shorter than GNU ld
-Map). It is easy to track a chain of references to one archive member with a
one-liner, e.g.
% ld.lld main.o a_b.a b_c.a c.a -o /dev/null --why-extract=- | tee stdout reference extracted symbol main.o a_b.a(a_b.o) a a_b.a(a_b.o) b_c.a(b_c.o) b() b_c.a(b_c.o) c.a(c.o) c() % ruby -F'\t' -ane 'BEGIN{p={}}; p[$F[1]]=[$F[0],$F[2]] if $.>1; END{x="c.a(c.o)"; while y=p[x]; puts "#{y[0]} extracts #{x} to resolve #{y[1]}"; x=y[0] end}' stdout b_c.a(b_c.o) extracts c.a(c.o) to resolve c() a_b.a(a_b.o) extracts b_c.a(b_c.o) to resolve b() main.o extracts a_b.a(a_b.o) to resolve a
Archive member extraction happens before --gc-sections, so this may not be a live path
under --gc-sections, but I think it is a good approximation in practice.
- Specifying a file avoids output interleaving with --verbose.
- Required = prevents accidental overwrite of an input if the user forgets =. (Most of compiler drivers' long options accept = but not )
We should consider adding an equivalent check to this area for the new file, for the same reason as the other cases.