Symbol related
--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 |
File related
--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 |
Archive related
--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]
Cross references
--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:
- the information is independent from other pieces of
-Map
- both pieces of information has large amount of output. Merging them makes the link action slower if the user just needs one piece of information
--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=-
.
Statistics
--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 |