brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.3 KiB · bb9d86c Raw
100 lines · plain
1--warn-backrefs2===============3 4``--warn-backrefs`` gives a warning when an undefined symbol reference is5resolved by a definition in an archive to the left of it on the command line.6 7A linker such as GNU ld makes a single pass over the input files from left to8right maintaining the set of undefined symbol references from the files loaded9so far. When encountering an archive or an object file surrounded by10``--start-lib`` and ``--end-lib`` that archive will be searched for resolving11symbol definitions; this may result in input files being loaded, updating the12set of undefined symbol references. When all resolving definitions have been13loaded from the archive, the linker moves on the next file and will not return14to it.  This means that if an input file to the right of an archive cannot have15an undefined symbol resolved by an archive to the left of it. For example:16 17    ld def.a ref.o18 19will result in an ``undefined reference`` error. If there are no cyclic20references, the archives can be ordered in such a way that there are no21backward references. If there are cyclic references then the ``--start-group``22and ``--end-group`` options can be used, or the same archive can be placed on23the command line twice.24 25LLD remembers the symbol table of archives that it has previously seen, so if26there is a reference from an input file to the right of an archive, LLD will27still search that archive for resolving any undefined references. This means28that an archive only needs to be included once on the command line and the29``--start-group`` and ``--end-group`` options are redundant.30 31A consequence of the differing archive searching semantics is that the same32linker command line can result in different outcomes. A link may succeed with33LLD that will fail with GNU ld, or even worse both links succeed but they have34selected different objects from different archives that both define the same35symbols.36 37The ``warn-backrefs`` option provides information that helps identify cases38where LLD and GNU ld archive selection may differ.39 40    | % ld.lld --warn-backrefs ... -lB -lA41    | ld.lld: warning: backward reference detected: system in A.a(a.o) refers to B.a(b.o)42 43    | % ld.lld --warn-backrefs ... --start-lib B/b.o --end-lib --start-lib A/a.o --end-lib44    | ld.lld: warning: backward reference detected: system in A/a.o refers to B/b.o45 46    # To suppress the warning, you can specify --warn-backrefs-exclude=<glob> to match B/b.o or B.a(b.o)47 48The ``--warn-backrefs`` option can also provide a check to enforce a49topological order of archives, which can be useful to detect layering50violations (albeit unable to catch all cases). There are two cases where GNU ld51will result in an ``undefined reference`` error:52 53* If adding the dependency does not form a cycle: conceptually ``A`` is higher54  level library while ``B`` is at a lower level. When you are developing an55  application ``P`` which depends on ``A``, but does not directly depend on56  ``B``, your link may fail surprisingly with ``undefined symbol:57  symbol_defined_in_B`` if the used/linked part of ``A`` happens to need some58  components of ``B``. It is inappropriate for ``P`` to add a dependency on59  ``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 the62  highest level. When you are developing ``C_test`` testing ``C``, your link may63  fail surprisingly with ``undefined symbol`` if there is somehow a dependency on64  some components of ``B``. You could fix the issue by adding the missing65  dependency (``B``), however, then every test (``A_test``, ``B_test``,66  ``C_test``) will link against every library. This breaks the motivation67  of splitting ``B``, ``C`` and ``A`` into separate libraries and makes binaries68  unnecessarily large. Moreover, the layering violation makes lower-level69  libraries (e.g. ``A``) vulnerable to changes to higher-level libraries (e.g.70  ``B``, ``C``).71 72Resolution:73 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 multiple77  libraries like ``B``.  Consider linking ``B`` with object semantics by78  surrounding it with ``--whole-archive`` and ``--no-whole-archive``.79* In the case of circular dependency, sometimes merging the libraries are the best.80 81There are two cases like a library sandwich where GNU ld will select a82different object.83 84* ``A.a B A2.so``: ``A.a`` may be used as an interceptor (e.g. it provides some85  optimized libc functions and ``A2`` is libc).  ``B`` does not need to know86  about ``A.a``, and ``A.a`` may be pulled into the link by other part of the87  program. For linker portability, consider ``--whole-archive`` and88  ``--no-whole-archive``.89 90* ``A.a B A2.a``: similar to the above case but ``--warn-backrefs`` does not91  flag the problem, because ``A2.a`` may be a replicate of ``A.a``, which is92  redundant but benign. In some cases ``A.a`` and ``B`` should be surrounded by93  a pair of ``--start-group`` and ``--end-group``. This is especially common94  among system libraries (e.g.  ``-lc __isnanl references -lm``, ``-lc95  _IO_funlockfile references -lpthread``, ``-lc __gcc_personality_v0 references96  -lgcc_eh``, and ``-lpthread _Unwind_GetCFA references -lunwind``).97 98  In C++, this is likely an ODR violation. We probably need a dedicated option99  for ODR detection.100