--trace-symbol=<sym>
Alias: -y sym
Print files which define or reference the specified non-local symbol. There are three types of definitions: definition in a relocatable object file, definition in a shared object, definition in a lazy object file/archive.
1 | % ld.lld -y foo a1.a a.o a2.so |
--trace
Alias: -t
Print processed files: relocatable object files, shared objects, and extracted lazy object files/archive members. Note that unextracted lazy object files/archive members are not printed.
The GNU ld behavior is a bit strange. You need to specify -t
twice to get both the archive name and the member name.
1 | % ld.lld -t a.o b.so c.a |
--print-archive-stats=<file>
gold introduced --print-symbol-counts=<file>
in 2008-06. The output includes the member count and extracted member count for each archive. I added --print-archive-stats=<file>
to ld.lld to dump the archive information, but in a tab-separated format.
1 | % ld.lld a.o aweak.a a1.a a1.a --print-archive-stats=- |
--why-extract=<file>
Print why each archive member/lazy object file is extracted. I added the option to ld.lld 14. The output is in a tab-separated format.
1 | % ld.lld main.o a_b.a b_c.a c.a -o /dev/null --why-extract=- | tee stdout |
It is easy to track a chain of references to one archive member: 1
2
3
4% ruby -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
ld64 has a similar option named -why_load
.
-Map=<file>
Print a link map to the file. To print to stdout, use -M
.
The output includes output sections addresses, file offsets, input section to output section mapping, and symbol assignments.
GNU ld prints additional information: Archive member included to satisfy reference by file (symbol)
, Discarded input sections
(similar to --print-gc-sections
), Allocating common symbols
, Memory Configuration
(related to memory regions), and Linker script and memory map
(similar to -t
).
If the option value is a directory or a name with %
, the map filename will be constructed from the output filename. 1
2
3
4
5
6
7
8
9
10-o foo.exe -Map=bar [Creates ./bar]
-o ../dir/foo.exe -Map=bar [Creates ./bar]
-o foo.exe -Map=../dir [Creates ../dir/foo.exe.map]
-o ../dir2/foo.exe -Map=../dir [Creates ../dir/foo.exe.map]
-o foo.exe -Map=% [Creates ./foo.exe.map]
-o ../dir/foo.exe -Map=% [Creates ../dir/foo.exe.map]
-o foo.exe -Map=%.bar [Creates ./foo.exe.bar]
-o ../dir/foo.exe -Map=%.bar [Creates ../dir/foo.exe.bar]
-o ../dir2/foo.exe -Map=../dir/% [Creates ../dir/../dir2/foo.exe.map]
-o ../dir2/foo.exe -Map=../dir/%.bar [Creates ../dir/../dir2/foo.exe.bar]
--cref
Print a cross reference table. For each non-local defined or shared symbol, print the defined file on the first line and and referencing files in subsequent lines. The format is a bit wasteful because there are 50 bytes before the File
column.
1 | % ld.lld --cref a1.so a2.o a3.o a.a |
If -Map
is specified, print along with the link map to the file. I find this behavior a bit unfortunate, because:
-Map
--print-dependencies
mold recently added the option in an alternative format to --cref
.
1 | # This is an output of the mold linker's --print-dependencies=full option. |
-why_live sym
ld64 manpage says: Logs a chain of references to symbol_name. Only applicable with -dead_strip . It can help debug why something that you think should be dead strip removed is not removed.
This can usually be approximated by ld.lld --why-extract=-
.
--stats
1 | % ld.bfd @response.txt --stats |
--time-trace
1 | % ld.lld @response.txt --time-trace -o clang |
mold --perf
1 | % mold @response.txt --perf |