[all-commits] [llvm/llvm-project] a954bb: [ELF] Add --why-extract= to query why archive memb...
Fangrui Song via All-commits
all-commits at lists.llvm.org
Mon Sep 20 09:52:43 PDT 2021
Branch: refs/heads/main
Home: https://github.com/llvm/llvm-project
Commit: a954bb18b14363e133217e7f19aa95fbde2c7488
https://github.com/llvm/llvm-project/commit/a954bb18b14363e133217e7f19aa95fbde2c7488
Author: Fangrui Song <i at maskray.me>
Date: 2021-09-20 (Mon, 20 Sep 2021)
Changed paths:
M lld/ELF/Config.h
M lld/ELF/Driver.cpp
M lld/ELF/MapFile.cpp
M lld/ELF/MapFile.h
M lld/ELF/Options.td
M lld/ELF/Symbols.cpp
M lld/ELF/Symbols.h
M lld/ELF/Writer.cpp
M lld/docs/ReleaseNotes.rst
M lld/docs/ld.lld.1
A lld/test/ELF/why-extract.s
Log Message:
-----------
[ELF] Add --why-extract= to query why archive members/lazy object files are extracted
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 -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 ` `)
Differential Revision: https://reviews.llvm.org/D109572
More information about the All-commits
mailing list