[NFC] Fixed indentation issue (#116942)
[llvm-project.git] / llvm-libgcc / docs / LLVMLibgcc.rst
blob22dae7afaa6cfc8046e52478cb312e42a81566ff
1 .. llvm-libgcc:
3 ===========
4 llvm-libgcc
5 ===========
7 .. contents::
8   :local:
10 **Note that these instructions assume a Linux and bash-friendly environment.
11 YMMV if you’re on a non Linux-based platform.**
13 .. _introduction:
15 Motivation
16 ============
18 Enabling libunwind as a replacement for libgcc on Linux has proven to be
19 challenging since libgcc_s.so is a required dependency in the [Linux standard
20 base][5]. Some software is transitively dependent on libgcc because glibc makes
21 hardcoded calls to functions in libgcc_s. For example, the function
22 ``__GI___backtrace`` eventually makes its way to a [hardcoded dlopen to libgcc_s'
23 _Unwind_Backtrace][1]. Since libgcc_{eh.a,s.so} and libunwind have the same ABI,
24 but different implementations, the two libraries end up [cross-talking, which
25 ultimately results in a segfault][2].
27 To solve this problem, libunwind needs libgcc "front" that is, link the
28 necessary functions from compiler-rt and libunwind into an archive and shared
29 object that advertise themselves as ``libgcc.a``, ``libgcc_eh.a``, and
30 ``libgcc_s.so``, so that glibc’s baked calls are diverted to the correct objects
31 in memory. Fortunately for us, compiler-rt and libunwind use the same ABI as the
32 libgcc family, so the problem is solvable at the llvm-project configuration
33 level: no program source needs to be edited. Thus, the end result is for a
34 distro manager to configure their LLVM build with a flag that indicates they
35 want to archive compiler-rt/unwind as libgcc. We achieve this by compiling
36 libunwind with all the symbols necessary for compiler-rt to emulate the libgcc
37 family, and then generate symlinks named for our "libgcc" that point to their
38 corresponding libunwind counterparts.
40 .. _alternatives
42 Alternatives
43 ============
45 We alternatively considered patching glibc so that the source doesn't directly
46 refer to libgcc, but rather _defaults_ to libgcc, so that a system preferring
47 compiler-rt/libunwind can point to these libraries at the config stage instead.
48 Even if we modified the Linux standard base, this alternative won't work because
49 binaries that are built using libgcc will still end up having cross-talk between
50 the differing implementations.
52 .. _target audience:
54 Target audience
55 ===============
57 llvm-libgcc is not for the casual LLVM user. It is intended to be used by distro
58 managers who want to replace libgcc with compiler-rt and libunwind, but cannot
59 fully abandon the libgcc family (e.g. because they are dependent on glibc). Such
60 managers must have worked out their compatibility requirements ahead of using
61 llvm-libgcc.
63 .. _cmake options:
65 CMake options
66 =============
68 .. option:: `LLVM_LIBGCC_EXPLICIT_OPT_IN`
70   **Required**
72   Since llvm-libgcc is such a fundamental, low-level component, we have made it
73   difficult to accidentally build, by requiring you to set an opt-in flag.
75 .. _Building llvm-libgcc
77 Building llvm-libgcc
78 --------------------
80 The first build tree is a mostly conventional build tree and gets you a Clang
81 build with these compiler-rt symbols exposed.
83 .. code-block:: bash
84   # Assumes $(PWD) is /path/to/llvm-project
85   $ cmake -GNinja -S llvm -B build-primary                    \
86       -DCMAKE_BUILD_TYPE=Release                              \
87       -DCMAKE_CROSSCOMPILING=On                               \
88       -DCMAKE_INSTALL_PREFIX=/tmp/aarch64-unknown-linux-gnu   \
89       -DLLVM_ENABLE_PROJECTS='clang'                          \
90       -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;llvm-libgcc"   \
91       -DLLVM_TARGETS_TO_BUILD=AArch64                         \
92       -DLLVM_DEFAULT_TARGET_TRIPLE=aarch64-unknown-linux-gnu  \
93       -DLLVM_LIBGCC_EXPLICIT_OPT_IN=Yes
94   $ ninja -C build-primary install
96 It's very important to notice that neither ``compiler-rt``, nor ``libunwind``,
97 are listed in ``LLVM_ENABLE_RUNTIMES``. llvm-libgcc makes these subprojects, and
98 adding them to this list will cause you problems due to there being duplicate
99 targets. As such, configuring the runtimes build will reject explicitly mentioning
100 either project with ``llvm-libgcc``.
102 To avoid issues when building with ``-DLLVM_ENABLE_RUNTIMES=all``, ``llvm-libgcc``
103 is not included, and all runtimes targets must be manually listed.
105 ## Verifying your results
107 This gets you a copy of libunwind with the libgcc symbols. You can verify this
108 using ``readelf``.
110 .. code-block:: bash
112   $ llvm-readelf -W --dyn-syms "${LLVM_LIBGCC_SYSROOT}/lib/libunwind.so" | grep FUNC | grep GCC_3.0
115 Roughly sixty symbols should appear, all suffixed with ``@@GCC_3.0``. You can
116 replace ``GCC_3.0`` with any of the supported version names in the version
117 script you’re exporting to verify that the symbols are exported.
120 .. _supported platforms:
122 Supported platforms
123 ===================
125 llvm-libgcc currently supports the following target triples:
127 * ``aarch64-*-*-*``
128 * ``armv7a-*-*-gnueabihf``
129 * ``i386-*-*-*``
130 * ``x86_64-*-*-*``
132 If you would like to support another triple (e.g. ``powerpc64-*-*-*``), you'll
133 need to generate a new version script, and then edit ``lib/gcc_s.ver``.
135 .. _Generating a new version script
137 Generating a new version script
138 -------------------------------
140 To generate a new version script, we need to generate the list of symbols that
141 exist in the set (``clang-builtins.a`` ∪ ``libunwind.a``) ∩ ``libgcc_s.so.1``.
142 The prerequisites for generating a version script are a binaries for the three
143 aforementioned libraries targeting your architecture (without having built
144 llvm-libgcc).
146 Once these libraries are in place, to generate a new version script, run the
147 following command.
149 .. code-block:: bash
151   /path/to/llvm-project
152   $ export ARCH=powerpc64
153   $ llvm/tools/llvm-libgcc/generate_version_script.py       \
154       --compiler_rt=/path/to/libclang_rt.builtins-${ARCH}.a \
155       --libunwind=/path/to/libunwind.a                      \
156       --libgcc_s=/path/to/libgcc_s.so.1                     \
157       --output=${ARCH}
159 This will generate a new version script a la
160 ``/path/to/llvm-project/llvm/tools/llvm-libgcc/gcc_s-${ARCH}.ver``, which we use
161 in the next section.
163 .. _Editing ``lib/gcc_s.ver``
165 Editing ``lib/gcc_s.ver``
166 -------------------------
168 Our freshly generated version script is unique to the specific architecture that
169 it was generated for, but a lot of the symbols are shared among many platforms.
170 As such, we don't check in unique version scripts, but rather have a single
171 version script that's run through the C preprocessor to prune symbols we won't
172 be using in ``lib/gcc_s.ver``.
174 Working out which symbols are common is largely a manual process at the moment,
175 because some symbols may be shared across different architectures, but not in
176 the same versions of libgcc. As such, a symbol appearing in ``lib/gcc_s.ver``
177 doesn't guarantee that the symbol is available for our new architecture: we need
178 to verify that the versions are the same, and if they're not, add the symbol to
179 the new version section, with the appropriate include guards.
181 There are a few macros that aim to improve readability.
183 * ``ARM_GNUEABIHF``, which targets exactly ``arm-*-*-gnueabihf``.
184 * ``GLOBAL_X86``, which should be used to target both x86 and x86_64, regardless
185   of the triple.
186 * ``GLOBAL_32BIT``, which is be used to target 32-bit platforms.
187 * ``GLOBAL_64BIT``, which is be used to target 64-bit platforms.