[WebAssembly] Fix asan issue from https://reviews.llvm.org/D121349
[llvm-project.git] / lld / docs / ELF / warn_backrefs.rst
blobfac2145cc0c0ee92a14c0176411f0cdfcdebfe2d
1 --warn-backrefs
2 ===============
4 ``--warn-backrefs`` gives a warning when an undefined symbol reference is
5 resolved by a definition in an archive to the left of it on the command line.
7 A linker such as GNU ld makes a single pass over the input files from left to
8 right maintaining the set of undefined symbol references from the files loaded
9 so far. When encountering an archive or an object file surrounded by
10 ``--start-lib`` and ``--end-lib`` that archive will be searched for resolving
11 symbol definitions; this may result in input files being loaded, updating the
12 set of undefined symbol references. When all resolving definitions have been
13 loaded from the archive, the linker moves on the next file and will not return
14 to it.  This means that if an input file to the right of a archive cannot have
15 an undefined symbol resolved by a archive to the left of it. For example:
17     ld def.a ref.o
19 will result in an ``undefined reference`` error. If there are no cyclic
20 references, the archives can be ordered in such a way that there are no
21 backward references. If there are cyclic references then the ``--start-group``
22 and ``--end-group`` options can be used, or the same archive can be placed on
23 the command line twice.
25 LLD remembers the symbol table of archives that it has previously seen, so if
26 there is a reference from an input file to the right of an archive, LLD will
27 still search that archive for resolving any undefined references. This means
28 that an archive only needs to be included once on the command line and the
29 ``--start-group`` and ``--end-group`` options are redundant.
31 A consequence of the differing archive searching semantics is that the same
32 linker command line can result in different outcomes. A link may succeed with
33 LLD that will fail with GNU ld, or even worse both links succeed but they have
34 selected different objects from different archives that both define the same
35 symbols.
37 The ``warn-backrefs`` option provides information that helps identify cases
38 where LLD and GNU ld archive selection may differ.
40     | % ld.lld --warn-backrefs ... -lB -lA
41     | ld.lld: warning: backward reference detected: system in A.a(a.o) refers to B.a(b.o)
43     | % ld.lld --warn-backrefs ... --start-lib B/b.o --end-lib --start-lib A/a.o --end-lib
44     | ld.lld: warning: backward reference detected: system in A/a.o refers to B/b.o
46     # To suppress the warning, you can specify --warn-backrefs-exclude=<glob> to match B/b.o or B.a(b.o)
48 The ``--warn-backrefs`` option can also provide a check to enforce a
49 topological order of archives, which can be useful to detect layering
50 violations (albeit unable to catch all cases). There are two cases where GNU ld
51 will result in an ``undefined reference`` error:
53 * If adding the dependency does not form a cycle: conceptually ``A`` is higher
54   level library while ``B`` is at a lower level. When you are developing an
55   application ``P`` which depends on ``A``, but does not directly depend on
56   ``B``, your link may fail surprisingly with ``undefined symbol:
57   symbol_defined_in_B`` if the used/linked part of ``A`` happens to need some
58   components of ``B``. It is inappropriate for ``P`` to add a dependency on
59   ``B`` since ``P`` does not use ``B`` directly.
60 * If adding the dependency forms a cycle, e.g. ``B->C->A ~> B``. ``A``
61   is supposed to be at the lowest level while ``B`` is supposed to be at the
62   highest level. When you are developing ``C_test`` testing ``C``, your link may
63   fail surprisingly with ``undefined symbol`` if there is somehow a dependency on
64   some components of ``B``. You could fix the issue by adding the missing
65   dependency (``B``), however, then every test (``A_test``, ``B_test``,
66   ``C_test``) will link against every library. This breaks the motivation
67   of splitting ``B``, ``C`` and ``A`` into separate libraries and makes binaries
68   unnecessarily large. Moreover, the layering violation makes lower-level
69   libraries (e.g. ``A``) vulnerable to changes to higher-level libraries (e.g.
70   ``B``, ``C``).
72 Resolution:
74 * Add a dependency from ``A`` to ``B``.
75 * The reference may be unintended and can be removed.
76 * The dependency may be intentionally omitted because there are multiple
77   libraries like ``B``.  Consider linking ``B`` with object semantics by
78   surrounding it with ``--whole-archive`` and ``--no-whole-archive``.
79 * In the case of circular dependency, sometimes merging the libraries are the best.
81 There are two cases like a library sandwich where GNU ld will select a
82 different object.
84 * ``A.a B A2.so``: ``A.a`` may be used as an interceptor (e.g. it provides some
85   optimized libc functions and ``A2`` is libc).  ``B`` does not need to know
86   about ``A.a``, and ``A.a`` may be pulled into the link by other part of the
87   program. For linker portability, consider ``--whole-archive`` and
88   ``--no-whole-archive``.
90 * ``A.a B A2.a``: similar to the above case but ``--warn-backrefs`` does not
91   flag the problem, because ``A2.a`` may be a replicate of ``A.a``, which is
92   redundant but benign. In some cases ``A.a`` and ``B`` should be surrounded by
93   a pair of ``--start-group`` and ``--end-group``. This is especially common
94   among system libraries (e.g.  ``-lc __isnanl references -lm``, ``-lc
95   _IO_funlockfile references -lpthread``, ``-lc __gcc_personality_v0 references
96   -lgcc_eh``, and ``-lpthread _Unwind_GetCFA references -lunwind``).
98   In C++, this is likely an ODR violation. We probably need a dedicated option
99   for ODR detection.