]>
Commit | Line | Data |
---|---|---|
c63539ff ML |
1 | .. |
2 | Copyright 1988-2022 Free Software Foundation, Inc. | |
3 | This is part of the GCC manual. | |
4 | For copying conditions, see the copyright.rst file. | |
5 | ||
6 | .. _whopr: | |
7 | ||
8 | Whole program assumptions, linker plugin and symbol visibilities | |
9 | **************************************************************** | |
10 | ||
11 | Link-time optimization gives relatively minor benefits when used | |
12 | alone. The problem is that propagation of inter-procedural | |
13 | information does not work well across functions and variables | |
14 | that are called or referenced by other compilation units (such as | |
15 | from a dynamically linked library). We say that such functions | |
16 | and variables are *externally visible*. | |
17 | ||
18 | To make the situation even more difficult, many applications | |
19 | organize themselves as a set of shared libraries, and the default | |
20 | ELF visibility rules allow one to overwrite any externally | |
21 | visible symbol with a different symbol at runtime. This | |
22 | basically disables any optimizations across such functions and | |
23 | variables, because the compiler cannot be sure that the function | |
24 | body it is seeing is the same function body that will be used at | |
25 | runtime. Any function or variable not declared ``static`` in | |
26 | the sources degrades the quality of inter-procedural | |
27 | optimization. | |
28 | ||
29 | To avoid this problem the compiler must assume that it sees the | |
30 | whole program when doing link-time optimization. Strictly | |
31 | speaking, the whole program is rarely visible even at link-time. | |
32 | Standard system libraries are usually linked dynamically or not | |
33 | provided with the link-time information. In GCC, the whole | |
34 | program option (:option:`-fwhole-program`) asserts that every | |
35 | function and variable defined in the current compilation | |
36 | unit is static, except for function ``main`` (note: at | |
37 | link time, the current unit is the union of all objects compiled | |
38 | with LTO). Since some functions and variables need to | |
39 | be referenced externally, for example by another DSO or from an | |
40 | assembler file, GCC also provides the function and variable | |
41 | attribute ``externally_visible`` which can be used to disable | |
42 | the effect of :option:`-fwhole-program` on a specific symbol. | |
43 | ||
44 | The whole program mode assumptions are slightly more complex in | |
45 | C++, where inline functions in headers are put into *COMDAT* | |
46 | sections. COMDAT function and variables can be defined by | |
47 | multiple object files and their bodies are unified at link-time | |
48 | and dynamic link-time. COMDAT functions are changed to local only | |
49 | when their address is not taken and thus un-sharing them with a | |
50 | library is not harmful. COMDAT variables always remain externally | |
51 | visible, however for readonly variables it is assumed that their | |
52 | initializers cannot be overwritten by a different value. | |
53 | ||
54 | GCC provides the function and variable attribute | |
55 | ``visibility`` that can be used to specify the visibility of | |
56 | externally visible symbols (or alternatively an | |
57 | :option:`-fdefault-visibility` command line option). ELF defines | |
58 | the ``default``, ``protected``, ``hidden`` and | |
59 | ``internal`` visibilities. | |
60 | ||
61 | The most commonly used is visibility is ``hidden``. It | |
62 | specifies that the symbol cannot be referenced from outside of | |
63 | the current shared library. Unfortunately, this information | |
64 | cannot be used directly by the link-time optimization in the | |
65 | compiler since the whole shared library also might contain | |
66 | non-LTO objects and those are not visible to the compiler. | |
67 | ||
68 | GCC solves this problem using linker plugins. A *linker | |
69 | plugin* is an interface to the linker that allows an external | |
70 | program to claim the ownership of a given object file. The linker | |
71 | then performs the linking procedure by querying the plugin about | |
72 | the symbol table of the claimed objects and once the linking | |
73 | decisions are complete, the plugin is allowed to provide the | |
74 | final object file before the actual linking is made. The linker | |
75 | plugin obtains the symbol resolution information which specifies | |
76 | which symbols provided by the claimed objects are bound from the | |
77 | rest of a binary being linked. | |
78 | ||
79 | GCC is designed to be independent of the rest of the toolchain | |
80 | and aims to support linkers without plugin support. For this | |
81 | reason it does not use the linker plugin by default. Instead, | |
82 | the object files are examined by :command:`collect2` before being | |
83 | passed to the linker and objects found to have LTO sections are | |
84 | passed to :command:`lto1` first. This mode does not work for | |
85 | library archives. The decision on what object files from the | |
86 | archive are needed depends on the actual linking and thus GCC | |
87 | would have to implement the linker itself. The resolution | |
88 | information is missing too and thus GCC needs to make an educated | |
89 | guess based on :option:`-fwhole-program`. Without the linker | |
90 | plugin GCC also assumes that symbols are declared ``hidden`` | |
3ed1b4ce | 91 | and not referred by non-LTO code by default. |