[docs] Rewrite LLD docs to Markdown (#209897)
Tracking issue: #201242 This is a stacked PR based on #209894 , which will be a standalone commit that renames *.rst -> *.md before this PR lands for history preservation purposes. See the [migration guide] for more information. [migration guide]: https://llvm.org/docs/SphinxQuickstartTemplate.html#markdown-migration-guidelines This was prepared with rst2myst plus LLM-assisted cleanup. I paged through all the generated HTML looking for migration artifacts, and all of the differences I could find appear to be formatting error corrections. Please spot check my work and approve if it looks good.
This commit is contained in:
parent
f8107f6283
commit
ab35099249
15 changed files with 716 additions and 760 deletions
|
|
@ -1,83 +1,81 @@
|
|||
Integrated Distributed ThinLTO (DTLTO)
|
||||
======================================
|
||||
# Integrated Distributed ThinLTO (DTLTO)
|
||||
|
||||
Integrated Distributed ThinLTO (DTLTO) enables the distribution of backend
|
||||
ThinLTO compilations via external distribution systems, such as Incredibuild,
|
||||
during the traditional link step.
|
||||
|
||||
The implementation is documented here: https://llvm.org/docs/DTLTO.html.
|
||||
The implementation is documented here: <https://llvm.org/docs/DTLTO.html>.
|
||||
|
||||
Currently, DTLTO is only supported in ELF and COFF LLD.
|
||||
|
||||
ELF LLD
|
||||
-------
|
||||
## ELF LLD
|
||||
|
||||
The command-line interface is as follows:
|
||||
|
||||
- ``--thinlto-distributor=<path>``
|
||||
- `--thinlto-distributor=<path>`
|
||||
Specifies the file to execute as the distributor process. If specified,
|
||||
ThinLTO backend compilations will be distributed.
|
||||
|
||||
- ``--thinlto-remote-compiler=<path>``
|
||||
- `--thinlto-remote-compiler=<path>`
|
||||
Specifies the path to the compiler that the distributor process will use for
|
||||
backend compilations. The compiler invoked must match the version of LLD.
|
||||
|
||||
- ``--thinlto-distributor-arg=<arg>``
|
||||
Specifies ``<arg>`` on the command line when invoking the distributor.
|
||||
- `--thinlto-distributor-arg=<arg>`
|
||||
Specifies `<arg>` on the command line when invoking the distributor.
|
||||
Can be specified multiple times.
|
||||
|
||||
- ``--thinlto-remote-compiler-prepend-arg=<arg>``
|
||||
Prepends ``<arg>`` to the remote compiler's command line.
|
||||
- `--thinlto-remote-compiler-prepend-arg=<arg>`
|
||||
Prepends `<arg>` to the remote compiler's command line.
|
||||
Can be specified multiple times.
|
||||
|
||||
- ``--thinlto-remote-compiler-arg=<arg>``
|
||||
Appends ``<arg>`` to the remote compiler's command line.
|
||||
- `--thinlto-remote-compiler-arg=<arg>`
|
||||
Appends `<arg>` to the remote compiler's command line.
|
||||
Can be specified multiple times.
|
||||
|
||||
Options that introduce extra input/output files may cause miscompilation if
|
||||
the distribution system does not automatically handle pushing/fetching them to
|
||||
remote nodes. In such cases, configure the distributor - possibly using
|
||||
``--thinlto-distributor-arg=`` - to manage these dependencies. See the
|
||||
`--thinlto-distributor-arg=` - to manage these dependencies. See the
|
||||
distributor documentation for details.
|
||||
|
||||
Some LLD LTO options (e.g., ``--lto-sample-profile=<file>``) are supported.
|
||||
Some LLD LTO options (e.g., `--lto-sample-profile=<file>`) are supported.
|
||||
Currently, other options are silently accepted but do not have the intended
|
||||
effect. Support for such options will be expanded in the future.
|
||||
|
||||
COFF LLD
|
||||
--------
|
||||
## COFF LLD
|
||||
|
||||
The command-line interface is as follows:
|
||||
|
||||
- ``/thinlto-distributor:<path>``
|
||||
- `/thinlto-distributor:<path>`
|
||||
Specifies the file to execute as the distributor process. If specified,
|
||||
ThinLTO backend compilations will be distributed.
|
||||
|
||||
- ``/thinlto-remote-compiler:<path>``
|
||||
- `/thinlto-remote-compiler:<path>`
|
||||
Specifies the path to the compiler that the distributor process will use for
|
||||
backend compilations. The compiler invoked must match the version of LLD.
|
||||
|
||||
- ``/thinlto-distributor-arg:<arg>``
|
||||
Specifies ``<arg>`` on the command line when invoking the distributor.
|
||||
- `/thinlto-distributor-arg:<arg>`
|
||||
Specifies `<arg>` on the command line when invoking the distributor.
|
||||
Can be specified multiple times.
|
||||
|
||||
- ``/thinlto-remote-compiler-prepend-arg:<arg>``
|
||||
Prepends ``<arg>`` to the remote compiler's command line.
|
||||
- `/thinlto-remote-compiler-prepend-arg:<arg>`
|
||||
Prepends `<arg>` to the remote compiler's command line.
|
||||
Can be specified multiple times.
|
||||
|
||||
- ``/thinlto-remote-compiler-arg:<arg>``
|
||||
Appends ``<arg>`` to the remote compiler's command line.
|
||||
- `/thinlto-remote-compiler-arg:<arg>`
|
||||
Appends `<arg>` to the remote compiler's command line.
|
||||
Can be specified multiple times.
|
||||
|
||||
Options that introduce extra input/output files may cause miscompilation if
|
||||
the distribution system does not automatically handle pushing/fetching them to
|
||||
remote nodes. In such cases, configure the distributor - possibly using
|
||||
``/thinlto-distributor-arg:`` - to manage these dependencies. See the
|
||||
`/thinlto-distributor-arg:` - to manage these dependencies. See the
|
||||
distributor documentation for details.
|
||||
|
||||
Some LLD LTO options (e.g., ``/lto-sample-profile:<file>``) are supported.
|
||||
Some LLD LTO options (e.g., `/lto-sample-profile:<file>`) are supported.
|
||||
Currently, other options are silently accepted but do not have the intended
|
||||
effect. Support for such options could be expanded in the future.
|
||||
|
||||
Currently, there is no DTLTO command line interface supplied for ``clang-cl``,
|
||||
Currently, there is no DTLTO command line interface supplied for `clang-cl`,
|
||||
as users are expected to invoke LLD directly.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
Large data sections
|
||||
===================
|
||||
# Large data sections
|
||||
|
||||
When linking very large binaries, lld may report relocation overflows like
|
||||
|
||||
::
|
||||
|
||||
relocation R_X86_64_PC32 out of range: 2158227201 is not in [-2147483648, 2147483647]
|
||||
```
|
||||
relocation R_X86_64_PC32 out of range: 2158227201 is not in [-2147483648, 2147483647]
|
||||
```
|
||||
|
||||
This happens when running into architectural limitations. For example, in x86-64
|
||||
PIC code, a reference to a static global variable is typically done with a
|
||||
``R_X86_64_PC32`` relocation, which is a 32-bit signed offset from the PC. That
|
||||
`R_X86_64_PC32` relocation, which is a 32-bit signed offset from the PC. That
|
||||
means if the global variable is laid out further than 2GB (2^31 bytes) from the
|
||||
instruction referencing it, we run into a relocation overflow.
|
||||
|
||||
lld normally lays out sections as follows:
|
||||
|
||||
.. image:: section_layout.png
|
||||
```{image} section_layout.png
|
||||
```
|
||||
|
||||
The largest relocation pressure is usually from ``.text`` to the beginning of
|
||||
``.rodata`` or ``.text`` to the end of ``.bss``.
|
||||
The largest relocation pressure is usually from `.text` to the beginning of
|
||||
`.rodata` or `.text` to the end of `.bss`.
|
||||
|
||||
Some code models offer a tradeoff between relocation pressure and performance.
|
||||
For example, x86-64's medium code model splits global variables into small and
|
||||
|
|
@ -27,26 +27,29 @@ globals are placed further away from text and we use 64-bit references to refer
|
|||
to them.
|
||||
|
||||
Large globals are placed in separate sections from small globals, and those
|
||||
sections have a "large" section flag, e.g. ``SHF_X86_64_LARGE`` for x86-64. The
|
||||
sections have a "large" section flag, e.g. `SHF_X86_64_LARGE` for x86-64. The
|
||||
linker places large sections on the outer edges of the binary, making sure they
|
||||
do not affect the distance of small globals to text. The large versions
|
||||
of ``.rodata``, ``.bss``, and ``.data`` are ``.lrodata``, ``.lbss``, and
|
||||
``.ldata``, and they are laid out as follows:
|
||||
of `.rodata`, `.bss`, and `.data` are `.lrodata`, `.lbss`, and
|
||||
`.ldata`, and they are laid out as follows:
|
||||
|
||||
.. image:: large_section_layout_pic.png
|
||||
```{image} large_section_layout_pic.png
|
||||
```
|
||||
|
||||
We try to keep the number of ``PT_LOAD`` segments to a minimum, so we place
|
||||
We try to keep the number of `PT_LOAD` segments to a minimum, so we place
|
||||
large sections next to the small sections with the same RWX permissions when
|
||||
possible.
|
||||
|
||||
``.lbss`` is right after ``.bss`` so that they are merged together and we
|
||||
minimize the number of segments with ``p_memsz > p_filesz``.
|
||||
`.lbss` is right after `.bss` so that they are merged together and we
|
||||
minimize the number of segments with `p_memsz > p_filesz`.
|
||||
|
||||
Note that the above applies to PIC code. For less common non-PIC code with
|
||||
absolute relocations instead of relative relocations, 32-bit relocations
|
||||
typically assume that symbols are in the lower 2GB of the address space. So for
|
||||
non-PIC code, large sections should be placed after all small sections to avoid
|
||||
``.lrodata`` pushing small symbols out of the lower 2GB of the address space.
|
||||
``-z lrodata-after-bss`` changes the layout to be:
|
||||
`.lrodata` pushing small symbols out of the lower 2GB of the address space.
|
||||
`-z lrodata-after-bss` changes the layout to be:
|
||||
|
||||
```{image} large_section_layout_nopic.png
|
||||
```
|
||||
|
||||
.. image:: large_section_layout_nopic.png
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
Linker Script implementation notes and policy
|
||||
=============================================
|
||||
# Linker Script implementation notes and policy
|
||||
|
||||
LLD implements a large subset of the GNU ld linker script notation. The LLD
|
||||
implementation policy is to implement linker script features as they are
|
||||
documented in the ld `manual <https://sourceware.org/binutils/docs/ld/Scripts.html>`_
|
||||
documented in the ld [manual](https://sourceware.org/binutils/docs/ld/Scripts.html)
|
||||
We consider it a bug if the lld implementation does not agree with the manual
|
||||
and it is not mentioned in the exceptions below.
|
||||
|
||||
|
|
@ -17,231 +16,220 @@ possible. We reserve the right to make different implementation choices where
|
|||
it is appropriate for LLD. Intentional deviations will be documented in this
|
||||
file.
|
||||
|
||||
Linker Script Specification
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
## Linker Script Specification
|
||||
|
||||
There are two lld options related to setting the linker script,
|
||||
`--script=<file>` and `--default-script=<file>`. The usage are illustrated below.
|
||||
|
||||
::
|
||||
```
|
||||
# `-T` is the alias for `--script` option.
|
||||
lld -T linker_script.lds
|
||||
|
||||
# `-T` is the alias for `--script` option.
|
||||
lld -T linker_script.lds
|
||||
|
||||
# `-dT` is the alias for `--default-script` option.
|
||||
lld -dT linker_script.lds
|
||||
# `-dT` is the alias for `--default-script` option.
|
||||
lld -dT linker_script.lds
|
||||
```
|
||||
|
||||
When both options are given, `--script=<file>` takes precedence.
|
||||
The intended use case of `--default-script` is to be used by toolchain
|
||||
configurations, and users can override the script by specifying `--script` if
|
||||
needed.
|
||||
|
||||
Symbol assignment
|
||||
~~~~~~~~~~~~~~~~~
|
||||
## Symbol assignment
|
||||
|
||||
A symbol assignment looks like:
|
||||
|
||||
::
|
||||
```
|
||||
symbol = expression;
|
||||
symbol += expression;
|
||||
```
|
||||
|
||||
symbol = expression;
|
||||
symbol += expression;
|
||||
The first form defines `symbol`. If `symbol` is already defined, it will be
|
||||
overridden. The other form requires `symbol` to be already defined.
|
||||
|
||||
The first form defines ``symbol``. If ``symbol`` is already defined, it will be
|
||||
overridden. The other form requires ``symbol`` to be already defined.
|
||||
For a simple assignment like `alias = aliasee;`, the `st_type` field is
|
||||
copied from the original symbol. Any arithmetic operation (e.g. `+ 0` will
|
||||
reset `st_type` to `STT_NOTYPE`.
|
||||
|
||||
For a simple assignment like ``alias = aliasee;``, the ``st_type`` field is
|
||||
copied from the original symbol. Any arithmetic operation (e.g. ``+ 0`` will
|
||||
reset ``st_type`` to ``STT_NOTYPE``.
|
||||
The `st_size` field is set to 0.
|
||||
|
||||
The ``st_size`` field is set to 0.
|
||||
## SECTIONS command
|
||||
|
||||
SECTIONS command
|
||||
~~~~~~~~~~~~~~~~
|
||||
A `SECTIONS` command looks like:
|
||||
|
||||
A ``SECTIONS`` command looks like:
|
||||
|
||||
::
|
||||
|
||||
SECTIONS {
|
||||
section-command
|
||||
section-command
|
||||
...
|
||||
} [INSERT [AFTER|BEFORE] anchor_section;]
|
||||
```
|
||||
SECTIONS {
|
||||
section-command
|
||||
section-command
|
||||
...
|
||||
} [INSERT [AFTER|BEFORE] anchor_section;]
|
||||
```
|
||||
|
||||
Each section-command can be a symbol assignment, an output section description,
|
||||
or an overlay description.
|
||||
|
||||
When the ``INSERT`` keyword is present, the ``SECTIONS`` command describes some
|
||||
When the `INSERT` keyword is present, the `SECTIONS` command describes some
|
||||
output sections which should be inserted after or before the specified anchor
|
||||
section. The insertion occurs after input sections have been mapped to output
|
||||
sections but before orphan sections have been processed.
|
||||
|
||||
In the case where no linker script has been provided or every ``SECTIONS``
|
||||
command is followed by ``INSERT``, LLD applies built-in rules which are similar
|
||||
In the case where no linker script has been provided or every `SECTIONS`
|
||||
command is followed by `INSERT`, LLD applies built-in rules which are similar
|
||||
to GNU ld's internal linker scripts.
|
||||
|
||||
- Align the first section in a ``PT_LOAD`` segment according to
|
||||
``-z noseparate-code``, ``-z separate-code``, or
|
||||
``-z separate-loadable-segments``
|
||||
- Define ``__bss_start``, ``end``, ``_end``, ``etext``, ``_etext``, ``edata``,
|
||||
``_edata``
|
||||
- Sort ``.ctors.*``/``.dtors.*``/``.init_array.*``/``.fini_array.*`` and
|
||||
PowerPC64 specific ``.toc``
|
||||
- Place input ``.text.*`` into output ``.text``, and handle certain variants
|
||||
(``.text.hot.``, ``.text.unknown.``, ``.text.unlikely.``, etc) in the
|
||||
presence of ``-z keep-text-section-prefix``.
|
||||
- Align the first section in a `PT_LOAD` segment according to
|
||||
`-z noseparate-code`, `-z separate-code`, or
|
||||
`-z separate-loadable-segments`
|
||||
- Define `__bss_start`, `end`, `_end`, `etext`, `_etext`, `edata`,
|
||||
`_edata`
|
||||
- Sort `.ctors.*`/`.dtors.*`/`.init_array.*`/`.fini_array.*` and
|
||||
PowerPC64 specific `.toc`
|
||||
- Place input `.text.*` into output `.text`, and handle certain variants
|
||||
(`.text.hot.`, `.text.unknown.`, `.text.unlikely.`, etc) in the
|
||||
presence of `-z keep-text-section-prefix`.
|
||||
|
||||
Output section description
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
## Output section description
|
||||
|
||||
The description of an output section looks like:
|
||||
|
||||
::
|
||||
```
|
||||
section [address] [(type)] : [AT(lma)] [ALIGN(section_align)] [SUBALIGN(subsection_align)] {
|
||||
output-section-command
|
||||
...
|
||||
} [>region] [AT>lma_region] [:phdr ...] [=fillexp] [,]
|
||||
```
|
||||
|
||||
section [address] [(type)] : [AT(lma)] [ALIGN(section_align)] [SUBALIGN(subsection_align)] {
|
||||
output-section-command
|
||||
...
|
||||
} [>region] [AT>lma_region] [:phdr ...] [=fillexp] [,]
|
||||
### Output section address
|
||||
|
||||
Output section address
|
||||
----------------------
|
||||
|
||||
When an *OutputSection* *S* has ``address``, LLD will set sh_addr to ``address``.
|
||||
When an *OutputSection* *S* has `address`, LLD will set sh_addr to `address`.
|
||||
|
||||
The ELF specification says:
|
||||
|
||||
> The value of sh_addr must be congruent to 0, modulo the value of sh_addralign.
|
||||
|
||||
The presence of ``address`` can cause the condition unsatisfied. LLD will warn.
|
||||
The presence of `address` can cause the condition unsatisfied. LLD will warn.
|
||||
GNU ld from Binutils 2.35 onwards will reduce sh_addralign so that
|
||||
sh_addr=0 (modulo sh_addralign).
|
||||
|
||||
When an output section has no input section, GNU ld will eliminate it if it
|
||||
only contains symbol assignments (e.g. ``.foo { symbol = 42; }``). LLD will
|
||||
only contains symbol assignments (e.g. `.foo { symbol = 42; }`). LLD will
|
||||
retain such sections unless all the symbol assignments are unreferenced
|
||||
``PROVIDED``.
|
||||
`PROVIDED`.
|
||||
|
||||
When an output section has no input section but advances the location counter,
|
||||
GNU ld sets the ``SHF_WRITE`` flag. LLD sets the SHF_WRITE flag only if the
|
||||
GNU ld sets the `SHF_WRITE` flag. LLD sets the SHF_WRITE flag only if the
|
||||
preceding output section with non-empty input sections also has the SHF_WRITE
|
||||
flag.
|
||||
|
||||
Output section type
|
||||
-------------------
|
||||
### Output section type
|
||||
|
||||
When an *OutputSection* *S* has ``(type)``, LLD will set ``sh_type`` or
|
||||
``sh_flags`` of *S*. ``type`` is one of:
|
||||
When an *OutputSection* *S* has `(type)`, LLD will set `sh_type` or
|
||||
`sh_flags` of *S*. `type` is one of:
|
||||
|
||||
- ``NOLOAD``: set ``sh_type`` to ``SHT_NOBITS``.
|
||||
- ``COPY``, ``INFO``, ``OVERLAY``: clear the ``SHF_ALLOC`` bit in ``sh_flags``.
|
||||
- ``TYPE=<value>``: set ``sh_type`` to the specified value. ``<value>`` must be
|
||||
an integer or one of ``SHT_PROGBITS, SHT_NOTE, SHT_NOBITS, SHT_INIT_ARRAY,
|
||||
SHT_FINI_ARRAY, SHT_PREINIT_ARRAY``.
|
||||
- `NOLOAD`: set `sh_type` to `SHT_NOBITS`.
|
||||
- `COPY`, `INFO`, `OVERLAY`: clear the `SHF_ALLOC` bit in `sh_flags`.
|
||||
- `TYPE=<value>`: set `sh_type` to the specified value. `<value>` must be
|
||||
an integer or one of `SHT_PROGBITS`, `SHT_NOTE`, `SHT_NOBITS`,
|
||||
`SHT_INIT_ARRAY`, `SHT_FINI_ARRAY`, `SHT_PREINIT_ARRAY`.
|
||||
|
||||
When ``sh_type`` is specified, it is an error if an input section in *S* has a
|
||||
When `sh_type` is specified, it is an error if an input section in *S* has a
|
||||
different type.
|
||||
|
||||
Output section alignment
|
||||
------------------------
|
||||
### Output section alignment
|
||||
|
||||
sh_addralign of an *OutputSection* *S* is the maximum of
|
||||
``ALIGN(section_align)`` and the maximum alignment of the input sections in
|
||||
`ALIGN(section_align)` and the maximum alignment of the input sections in
|
||||
*S*.
|
||||
|
||||
When an *OutputSection* *S* has both ``address`` and ``ALIGN(section_align)``,
|
||||
GNU ld will set sh_addralign to ``ALIGN(section_align)``.
|
||||
When an *OutputSection* *S* has both `address` and `ALIGN(section_align)`,
|
||||
GNU ld will set sh_addralign to `ALIGN(section_align)`.
|
||||
|
||||
Output section LMA
|
||||
------------------
|
||||
### Output section LMA
|
||||
|
||||
A load address (LMA) can be specified by ``AT(lma)`` or ``AT>lma_region``.
|
||||
A load address (LMA) can be specified by `AT(lma)` or `AT>lma_region`.
|
||||
|
||||
- ``AT(lma)`` specifies the exact load address. If the linker script does not
|
||||
- `AT(lma)` specifies the exact load address. If the linker script does not
|
||||
have a PHDRS command, then a new loadable segment will be generated.
|
||||
- ``AT>lma_region`` specifies the LMA region. The lack of ``AT>lma_region``
|
||||
- `AT>lma_region` specifies the LMA region. The lack of `AT>lma_region`
|
||||
means the default region is used. Note, GNU ld propagates the previous LMA
|
||||
memory region when ``address`` is not specified. The LMA is set to the
|
||||
memory region when `address` is not specified. The LMA is set to the
|
||||
current location of the memory region aligned to the section alignment.
|
||||
If the linker script does not have a PHDRS command, then if
|
||||
``lma_region`` is different from the ``lma_region`` for
|
||||
`lma_region` is different from the `lma_region` for
|
||||
the previous OutputSection a new loadable segment will be generated.
|
||||
|
||||
The two keywords cannot be specified at the same time.
|
||||
|
||||
If neither ``AT(lma)`` nor ``AT>lma_region`` is specified:
|
||||
If neither `AT(lma)` nor `AT>lma_region` is specified:
|
||||
|
||||
- If the previous section is also in the default LMA region, and the two
|
||||
section have the same memory regions, the difference between the LMA and the
|
||||
VMA is computed to be the same as the previous difference.
|
||||
- Otherwise, the LMA is set to the VMA.
|
||||
|
||||
Overwrite sections
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
## Overwrite sections
|
||||
|
||||
An ``OVERWRITE_SECTIONS`` command looks like:
|
||||
An `OVERWRITE_SECTIONS` command looks like:
|
||||
|
||||
::
|
||||
```
|
||||
OVERWRITE_SECTIONS {
|
||||
output-section-description
|
||||
output-section-description
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
OVERWRITE_SECTIONS {
|
||||
output-section-description
|
||||
output-section-description
|
||||
...
|
||||
}
|
||||
|
||||
Unlike a ``SECTIONS`` command, ``OVERWRITE_SECTIONS`` does not specify a
|
||||
Unlike a `SECTIONS` command, `OVERWRITE_SECTIONS` does not specify a
|
||||
section order or suppress the built-in rules.
|
||||
|
||||
If a described output section description also appears in a ``SECTIONS``
|
||||
command, the ``OVERWRITE_SECTIONS`` command wins; otherwise, the output section
|
||||
If a described output section description also appears in a `SECTIONS`
|
||||
command, the `OVERWRITE_SECTIONS` command wins; otherwise, the output section
|
||||
will be added somewhere following the usual orphan section placement rules.
|
||||
|
||||
If a described output section description also appears in an ``INSERT
|
||||
[AFTER|BEFORE]`` command, the description will be provided by the
|
||||
description in the ``OVERWRITE_SECTIONS`` command while the insert command
|
||||
If a described output section description also appears in an `INSERT
|
||||
[AFTER|BEFORE]` command, the description will be provided by the
|
||||
description in the `OVERWRITE_SECTIONS` command while the insert command
|
||||
still applies (possibly after orphan section placement). It is recommended to
|
||||
leave the brace empty (i.e. ``section : {}``) for the insert command, because
|
||||
leave the brace empty (i.e. `section : {}`) for the insert command, because
|
||||
its description will be ignored anyway.
|
||||
|
||||
Built-in functions
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
## Built-in functions
|
||||
|
||||
``DATA_SEGMENT_RELRO_END(offset, exp)`` defines the end of the ``PT_GNU_RELRO``
|
||||
segment when ``-z relro`` (default) is in effect. Sections between
|
||||
``DATA_SEGMENT_ALIGN`` and ``DATA_SEGMENT_RELRO_END`` are considered RELRO.
|
||||
`DATA_SEGMENT_RELRO_END(offset, exp)` defines the end of the `PT_GNU_RELRO`
|
||||
segment when `-z relro` (default) is in effect. Sections between
|
||||
`DATA_SEGMENT_ALIGN` and `DATA_SEGMENT_RELRO_END` are considered RELRO.
|
||||
|
||||
The typical use case is ``. = DATA_SEGMENT_RELRO_END(0, .);`` followed by
|
||||
writable but non-RELRO sections. LLD ignores ``offset`` and ``exp`` and aligns
|
||||
The typical use case is `. = DATA_SEGMENT_RELRO_END(0, .);` followed by
|
||||
writable but non-RELRO sections. LLD ignores `offset` and `exp` and aligns
|
||||
the current location to a max-page-size boundary, ensuring that the next
|
||||
``PT_LOAD`` segment will not overlap with the ``PT_GNU_RELRO`` segment.
|
||||
`PT_LOAD` segment will not overlap with the `PT_GNU_RELRO` segment.
|
||||
|
||||
LLD will insert ``.relro_padding`` immediately before the symbol assignment
|
||||
using ``DATA_SEGMENT_RELRO_END``.
|
||||
LLD will insert `.relro_padding` immediately before the symbol assignment
|
||||
using `DATA_SEGMENT_RELRO_END`.
|
||||
|
||||
Section Classes
|
||||
~~~~~~~~~~~~~~~
|
||||
## Section Classes
|
||||
|
||||
The ``CLASS`` keyword inside a ``SECTIONS`` command defines classes of input
|
||||
The `CLASS` keyword inside a `SECTIONS` command defines classes of input
|
||||
sections:
|
||||
|
||||
::
|
||||
|
||||
SECTIONS {
|
||||
CLASS(class_name) {
|
||||
input-section-description
|
||||
input-section-description
|
||||
...
|
||||
}
|
||||
```
|
||||
SECTIONS {
|
||||
CLASS(class_name) {
|
||||
input-section-description
|
||||
input-section-description
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Input section descriptions refer to a class using ``CLASS(class_name)``
|
||||
Input section descriptions refer to a class using `CLASS(class_name)`
|
||||
instead of the usual filename and section name patterns. For example:
|
||||
|
||||
::
|
||||
|
||||
SECTIONS {
|
||||
CLASS(c) { *(.rodata.earlier) }
|
||||
.rodata { *(.rodata) CLASS(c) (*.rodata.later) }
|
||||
}
|
||||
```
|
||||
SECTIONS {
|
||||
CLASS(c) { *(.rodata.earlier) }
|
||||
.rodata { *(.rodata) CLASS(c) (*.rodata.later) }
|
||||
}
|
||||
```
|
||||
|
||||
Input sections that are assigned to a class are not matched by later patterns,
|
||||
just as if they had been assigned to an earlier output section. If a class is
|
||||
|
|
@ -253,16 +241,15 @@ Classes cannot reference other classes; an input section is assigned to at most
|
|||
one class.
|
||||
|
||||
Sections cannot be specified to possibly spill into or out of
|
||||
``INSERT [AFTER|BEFORE]``, ``OVERWRITE_SECTIONS``, or ``/DISCARD/``.
|
||||
`INSERT [AFTER|BEFORE]`, `OVERWRITE_SECTIONS`, or `/DISCARD/`.
|
||||
|
||||
Non-contiguous regions
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
## Non-contiguous regions
|
||||
|
||||
The flag ``--enable-non-contiguous-regions`` provides a version of the above
|
||||
The flag `--enable-non-contiguous-regions` provides a version of the above
|
||||
spilling functionality that is more compatible with GNU LD. It allows input
|
||||
sections to spill to later pattern matches. (This globally changes the behavior
|
||||
of patterns.) Unlike GNU ld, ``/DISCARD/`` only matches previously-unmatched
|
||||
of patterns.) Unlike GNU ld, `/DISCARD/` only matches previously-unmatched
|
||||
sections (i.e., the flag does not affect it). Also, if a section fails to fit
|
||||
at any of its matches, the link fails instead of discarding the section.
|
||||
Accordingly, the GNU flag ``--enable-non-contiguous-regions-warnings`` is not
|
||||
Accordingly, the GNU flag `--enable-non-contiguous-regions-warnings` is not
|
||||
implemented, as it exists to warn about such occurrences.
|
||||
|
|
|
|||
|
|
@ -1,66 +1,66 @@
|
|||
-z start-stop-gc
|
||||
================
|
||||
# -z start-stop-gc
|
||||
|
||||
If your ``-Wl,--gc-sections`` build fail with a linker error like this:
|
||||
If your `-Wl,--gc-sections` build fail with a linker error like this:
|
||||
|
||||
error: undefined symbol: __start_meta
|
||||
>>> referenced by {{.*}}
|
||||
>>> the encapsulation symbol needs to be retained under --gc-sections properly; consider -z nostart-stop-gc (see https://lld.llvm.org/start-stop-gc)
|
||||
```
|
||||
error: undefined symbol: __start_meta
|
||||
>>> referenced by {{.*}}
|
||||
>>> the encapsulation symbol needs to be retained under --gc-sections properly; consider -z nostart-stop-gc (see https://lld.llvm.org/start-stop-gc)
|
||||
```
|
||||
|
||||
it is likely your C identifier name sections are not properly annotated to
|
||||
suffice under ``--gc-sections``.
|
||||
suffice under `--gc-sections`.
|
||||
|
||||
``__start_meta`` and ``__stop_meta`` are sometimes called encapsulation
|
||||
symbols. In October 2015, GNU ld switched behavior and made a ``__start_meta``
|
||||
reference from a live section retain all ``meta`` input sections. This
|
||||
`__start_meta` and `__stop_meta` are sometimes called encapsulation
|
||||
symbols. In October 2015, GNU ld switched behavior and made a `__start_meta`
|
||||
reference from a live section retain all `meta` input sections. This
|
||||
conservative behavior works for existing code which does not take GC into fair
|
||||
consideration, but unnecessarily increases sizes for modern metadata section
|
||||
usage which desires precise GC.
|
||||
|
||||
GNU ld 2.37 added ``-z start-stop-gc`` to restore the traditional behavior
|
||||
ld.lld 13.0.0 defaults to ``-z start-stop-gc`` and supports ``-z nostart-stop-gc``
|
||||
GNU ld 2.37 added `-z start-stop-gc` to restore the traditional behavior
|
||||
ld.lld 13.0.0 defaults to `-z start-stop-gc` and supports `-z nostart-stop-gc`
|
||||
to switch to the conservative behavior.
|
||||
|
||||
The Apple ld64 linker has a similar ``section$start`` feature and always
|
||||
allowed GC (like ``-z start-stop-gc``).
|
||||
The Apple ld64 linker has a similar `section$start` feature and always
|
||||
allowed GC (like `-z start-stop-gc`).
|
||||
|
||||
Annotate C identifier name sections
|
||||
-----------------------------------
|
||||
## Annotate C identifier name sections
|
||||
|
||||
A C identifier name section (``meta``) sometimes depends on another section.
|
||||
Let that section reference ``meta`` via a relocation.
|
||||
A C identifier name section (`meta`) sometimes depends on another section.
|
||||
Let that section reference `meta` via a relocation.
|
||||
|
||||
.. code-block:: c
|
||||
```c
|
||||
asm(".pushsection .init_array,\"aw\",@init_array\n" \
|
||||
".reloc ., R_AARCH64_NONE, meta\n" \
|
||||
".popsection\n")
|
||||
```
|
||||
|
||||
asm(".pushsection .init_array,\"aw\",@init_array\n" \
|
||||
".reloc ., R_AARCH64_NONE, meta\n" \
|
||||
".popsection\n")
|
||||
|
||||
If a relocation is inconvenient, consider using ``__attribute__((retain))``
|
||||
If a relocation is inconvenient, consider using `__attribute__((retain))`
|
||||
(GCC 11 with modern binutils, Clang 13).
|
||||
|
||||
.. code-block:: c
|
||||
```c
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wattributes"
|
||||
__attribute__((retain,used,section("meta")))
|
||||
static const char dummy[0];
|
||||
#pragma GCC diagnostic pop
|
||||
```
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wattributes"
|
||||
__attribute__((retain,used,section("meta")))
|
||||
static const char dummy[0];
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
GCC before 11 and Clang before 13 do not recognize ``__attribute__((retain))``,
|
||||
so ``-Wattributes`` may need to be ignored. On ELF targets,
|
||||
``__attribute__((used))`` prevents compiler discarding, but does not affect
|
||||
linker ``--gc-sections``.
|
||||
GCC before 11 and Clang before 13 do not recognize `__attribute__((retain))`,
|
||||
so `-Wattributes` may need to be ignored. On ELF targets,
|
||||
`__attribute__((used))` prevents compiler discarding, but does not affect
|
||||
linker `--gc-sections`.
|
||||
|
||||
In a macro, you may use:
|
||||
|
||||
.. code-block:: c
|
||||
```c
|
||||
_Pragma("GCC diagnostic push")
|
||||
_Pragma("GCC diagnostic ignored \"-Wattributes\"")
|
||||
...
|
||||
_Pragma("GCC diagnostic pop")
|
||||
```
|
||||
|
||||
_Pragma("GCC diagnostic push")
|
||||
_Pragma("GCC diagnostic ignored \"-Wattributes\"")
|
||||
...
|
||||
_Pragma("GCC diagnostic pop")
|
||||
|
||||
If you use the ``SECTIONS`` command in a linker script, use
|
||||
`the ``KEEP`` keyword <https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html>`_, e.g.
|
||||
``meta : { KEEP(*(meta)) }``
|
||||
If you use the `SECTIONS` command in a linker script, use
|
||||
[the `KEEP` keyword](https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html), e.g.
|
||||
`meta : { KEEP(*(meta)) }`
|
||||
|
|
|
|||
|
|
@ -1,32 +1,31 @@
|
|||
--warn-backrefs
|
||||
===============
|
||||
# --warn-backrefs
|
||||
|
||||
``--warn-backrefs`` gives a warning when an undefined symbol reference is
|
||||
`--warn-backrefs` gives a warning when an undefined symbol reference is
|
||||
resolved by a definition in an archive to the left of it on the command line.
|
||||
|
||||
A linker such as GNU ld makes a single pass over the input files from left to
|
||||
right maintaining the set of undefined symbol references from the files loaded
|
||||
so far. When encountering an archive or an object file surrounded by
|
||||
``--start-lib`` and ``--end-lib`` that archive will be searched for resolving
|
||||
`--start-lib` and `--end-lib` that archive will be searched for resolving
|
||||
symbol definitions; this may result in input files being loaded, updating the
|
||||
set of undefined symbol references. When all resolving definitions have been
|
||||
loaded from the archive, the linker moves on the next file and will not return
|
||||
to it. This means that if an input file to the right of an archive cannot have
|
||||
to it. This means that if an input file to the right of an archive cannot have
|
||||
an undefined symbol resolved by an archive to the left of it. For example:
|
||||
|
||||
ld def.a ref.o
|
||||
> ld def.a ref.o
|
||||
|
||||
will result in an ``undefined reference`` error. If there are no cyclic
|
||||
will result in an `undefined reference` error. If there are no cyclic
|
||||
references, the archives can be ordered in such a way that there are no
|
||||
backward references. If there are cyclic references then the ``--start-group``
|
||||
and ``--end-group`` options can be used, or the same archive can be placed on
|
||||
backward references. If there are cyclic references then the `--start-group`
|
||||
and `--end-group` options can be used, or the same archive can be placed on
|
||||
the command line twice.
|
||||
|
||||
LLD remembers the symbol table of archives that it has previously seen, so if
|
||||
there is a reference from an input file to the right of an archive, LLD will
|
||||
still search that archive for resolving any undefined references. This means
|
||||
that an archive only needs to be included once on the command line and the
|
||||
``--start-group`` and ``--end-group`` options are redundant.
|
||||
`--start-group` and `--end-group` options are redundant.
|
||||
|
||||
A consequence of the differing archive searching semantics is that the same
|
||||
linker command line can result in different outcomes. A link may succeed with
|
||||
|
|
@ -34,66 +33,68 @@ LLD that will fail with GNU ld, or even worse both links succeed but they have
|
|||
selected different objects from different archives that both define the same
|
||||
symbols.
|
||||
|
||||
The ``warn-backrefs`` option provides information that helps identify cases
|
||||
The `warn-backrefs` option provides information that helps identify cases
|
||||
where LLD and GNU ld archive selection may differ.
|
||||
|
||||
| % ld.lld --warn-backrefs ... -lB -lA
|
||||
| ld.lld: warning: backward reference detected: system in A.a(a.o) refers to B.a(b.o)
|
||||
```console
|
||||
% ld.lld --warn-backrefs ... -lB -lA
|
||||
ld.lld: warning: backward reference detected: system in A.a(a.o) refers to B.a(b.o)
|
||||
|
||||
| % ld.lld --warn-backrefs ... --start-lib B/b.o --end-lib --start-lib A/a.o --end-lib
|
||||
| ld.lld: warning: backward reference detected: system in A/a.o refers to B/b.o
|
||||
% ld.lld --warn-backrefs ... --start-lib B/b.o --end-lib --start-lib A/a.o --end-lib
|
||||
ld.lld: warning: backward reference detected: system in A/a.o refers to B/b.o
|
||||
|
||||
# To suppress the warning, you can specify --warn-backrefs-exclude=<glob> to match B/b.o or B.a(b.o)
|
||||
# To suppress the warning, you can specify --warn-backrefs-exclude=<glob> to match B/b.o or B.a(b.o)
|
||||
```
|
||||
|
||||
The ``--warn-backrefs`` option can also provide a check to enforce a
|
||||
The `--warn-backrefs` option can also provide a check to enforce a
|
||||
topological order of archives, which can be useful to detect layering
|
||||
violations (albeit unable to catch all cases). There are two cases where GNU ld
|
||||
will result in an ``undefined reference`` error:
|
||||
will result in an `undefined reference` error:
|
||||
|
||||
* If adding the dependency does not form a cycle: conceptually ``A`` is higher
|
||||
level library while ``B`` is at a lower level. When you are developing an
|
||||
application ``P`` which depends on ``A``, but does not directly depend on
|
||||
``B``, your link may fail surprisingly with ``undefined symbol:
|
||||
symbol_defined_in_B`` if the used/linked part of ``A`` happens to need some
|
||||
components of ``B``. It is inappropriate for ``P`` to add a dependency on
|
||||
``B`` since ``P`` does not use ``B`` directly.
|
||||
* If adding the dependency forms a cycle, e.g. ``B->C->A ~> B``. ``A``
|
||||
is supposed to be at the lowest level while ``B`` is supposed to be at the
|
||||
highest level. When you are developing ``C_test`` testing ``C``, your link may
|
||||
fail surprisingly with ``undefined symbol`` if there is somehow a dependency on
|
||||
some components of ``B``. You could fix the issue by adding the missing
|
||||
dependency (``B``), however, then every test (``A_test``, ``B_test``,
|
||||
``C_test``) will link against every library. This breaks the motivation
|
||||
of splitting ``B``, ``C`` and ``A`` into separate libraries and makes binaries
|
||||
- If adding the dependency does not form a cycle: conceptually `A` is higher
|
||||
level library while `B` is at a lower level. When you are developing an
|
||||
application `P` which depends on `A`, but does not directly depend on
|
||||
`B`, your link may fail surprisingly with `undefined symbol:
|
||||
symbol_defined_in_B` if the used/linked part of `A` happens to need some
|
||||
components of `B`. It is inappropriate for `P` to add a dependency on
|
||||
`B` since `P` does not use `B` directly.
|
||||
- If adding the dependency forms a cycle, e.g. `B->C->A ~> B`. `A`
|
||||
is supposed to be at the lowest level while `B` is supposed to be at the
|
||||
highest level. When you are developing `C_test` testing `C`, your link may
|
||||
fail surprisingly with `undefined symbol` if there is somehow a dependency on
|
||||
some components of `B`. You could fix the issue by adding the missing
|
||||
dependency (`B`), however, then every test (`A_test`, `B_test`,
|
||||
`C_test`) will link against every library. This breaks the motivation
|
||||
of splitting `B`, `C` and `A` into separate libraries and makes binaries
|
||||
unnecessarily large. Moreover, the layering violation makes lower-level
|
||||
libraries (e.g. ``A``) vulnerable to changes to higher-level libraries (e.g.
|
||||
``B``, ``C``).
|
||||
libraries (e.g. `A`) vulnerable to changes to higher-level libraries (e.g.
|
||||
`B`, `C`).
|
||||
|
||||
Resolution:
|
||||
|
||||
* Add a dependency from ``A`` to ``B``.
|
||||
* The reference may be unintended and can be removed.
|
||||
* The dependency may be intentionally omitted because there are multiple
|
||||
libraries like ``B``. Consider linking ``B`` with object semantics by
|
||||
surrounding it with ``--whole-archive`` and ``--no-whole-archive``.
|
||||
* In the case of circular dependency, sometimes merging the libraries are the best.
|
||||
- Add a dependency from `A` to `B`.
|
||||
- The reference may be unintended and can be removed.
|
||||
- The dependency may be intentionally omitted because there are multiple
|
||||
libraries like `B`. Consider linking `B` with object semantics by
|
||||
surrounding it with `--whole-archive` and `--no-whole-archive`.
|
||||
- In the case of circular dependency, sometimes merging the libraries are the best.
|
||||
|
||||
There are two cases like a library sandwich where GNU ld will select a
|
||||
different object.
|
||||
|
||||
* ``A.a B A2.so``: ``A.a`` may be used as an interceptor (e.g. it provides some
|
||||
optimized libc functions and ``A2`` is libc). ``B`` does not need to know
|
||||
about ``A.a``, and ``A.a`` may be pulled into the link by other part of the
|
||||
program. For linker portability, consider ``--whole-archive`` and
|
||||
``--no-whole-archive``.
|
||||
- `A.a B A2.so`: `A.a` may be used as an interceptor (e.g. it provides some
|
||||
optimized libc functions and `A2` is libc). `B` does not need to know
|
||||
about `A.a`, and `A.a` may be pulled into the link by other part of the
|
||||
program. For linker portability, consider `--whole-archive` and
|
||||
`--no-whole-archive`.
|
||||
|
||||
* ``A.a B A2.a``: similar to the above case but ``--warn-backrefs`` does not
|
||||
flag the problem, because ``A2.a`` may be a replicate of ``A.a``, which is
|
||||
redundant but benign. In some cases ``A.a`` and ``B`` should be surrounded by
|
||||
a pair of ``--start-group`` and ``--end-group``. This is especially common
|
||||
among system libraries (e.g. ``-lc __isnanl references -lm``, ``-lc
|
||||
_IO_funlockfile references -lpthread``, ``-lc __gcc_personality_v0 references
|
||||
-lgcc_eh``, and ``-lpthread _Unwind_GetCFA references -lunwind``).
|
||||
- `A.a B A2.a`: similar to the above case but `--warn-backrefs` does not
|
||||
flag the problem, because `A2.a` may be a replicate of `A.a`, which is
|
||||
redundant but benign. In some cases `A.a` and `B` should be surrounded by
|
||||
a pair of `--start-group` and `--end-group`. This is especially common
|
||||
among system libraries (e.g. `-lc __isnanl references -lm`, `-lc
|
||||
_IO_funlockfile references -lpthread`, `-lc __gcc_personality_v0 references
|
||||
-lgcc_eh`, and `-lpthread _Unwind_GetCFA references -lunwind`).
|
||||
|
||||
In C++, this is likely an ODR violation. We probably need a dedicated option
|
||||
for ODR detection.
|
||||
|
|
|
|||
|
|
@ -1,62 +1,58 @@
|
|||
Mach-O LLD Port
|
||||
===============
|
||||
# Mach-O LLD Port
|
||||
|
||||
LLD is a linker from the LLVM project that is a drop-in replacement
|
||||
for system linkers and runs much faster than them. It also provides
|
||||
features that are useful for toolchain developers. This document
|
||||
will describe the Mach-O port.
|
||||
|
||||
Features
|
||||
--------
|
||||
## Features
|
||||
|
||||
- LLD is a drop-in replacement for Apple's Mach-O linker, ld64, that accepts the
|
||||
same command line arguments.
|
||||
|
||||
- LLD is very fast. When you link a large program on a multicore
|
||||
machine, you can expect that LLD runs more than twice as fast as the ld64
|
||||
linker.
|
||||
|
||||
Download
|
||||
--------
|
||||
## Download
|
||||
|
||||
LLD is available as a pre-built binary by going to the `latest release <https://github.com/llvm/llvm-project/releases>`_,
|
||||
downloading the appropriate bundle (``clang+llvm-<version>-<your architecture>-<your platform>.tar.xz``),
|
||||
decompressing it, and locating the binary at ``bin/ld64.lld``. Note
|
||||
that if ``ld64.lld`` is moved out of ``bin``, it must still be accompanied
|
||||
by its sibling file ``lld``, as ``ld64.lld`` is technically a symlink to ``lld``.
|
||||
LLD is available as a pre-built binary by going to the [latest release](https://github.com/llvm/llvm-project/releases),
|
||||
downloading the appropriate bundle (`clang+llvm-<version>-<your architecture>-<your platform>.tar.xz`),
|
||||
decompressing it, and locating the binary at `bin/ld64.lld`. Note
|
||||
that if `ld64.lld` is moved out of `bin`, it must still be accompanied
|
||||
by its sibling file `lld`, as `ld64.lld` is technically a symlink to `lld`.
|
||||
|
||||
Build
|
||||
-----
|
||||
## Build
|
||||
|
||||
The easiest way to build LLD is to
|
||||
check out the entire LLVM projects/sub-projects from a git mirror and
|
||||
build that tree. You need ``cmake`` and of course a C++ compiler.
|
||||
build that tree. You need `cmake` and of course a C++ compiler.
|
||||
|
||||
.. code-block:: console
|
||||
```console
|
||||
$ git clone https://github.com/llvm/llvm-project llvm-project
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
$ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS='lld' ../llvm-project/llvm
|
||||
$ ninja check-lld-macho
|
||||
```
|
||||
|
||||
$ git clone https://github.com/llvm/llvm-project llvm-project
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
$ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS='lld' ../llvm-project/llvm
|
||||
$ ninja check-lld-macho
|
||||
Then you can find output binary at `build/bin/ld64.lld`. Note
|
||||
that if `ld64.lld` is moved out of `bin`, it must still be accompanied
|
||||
by its sibling file `lld`, as `ld64.lld` is technically a symlink to `lld`.
|
||||
|
||||
Then you can find output binary at ``build/bin/ld64.lld``. Note
|
||||
that if ``ld64.lld`` is moved out of ``bin``, it must still be accompanied
|
||||
by its sibling file ``lld``, as ``ld64.lld`` is technically a symlink to ``lld``.
|
||||
## Using LLD
|
||||
|
||||
Using LLD
|
||||
---------
|
||||
|
||||
LLD can be used by adding ``-fuse-ld=/path/to/ld64.lld`` to the linker flags.
|
||||
LLD can be used by adding `-fuse-ld=/path/to/ld64.lld` to the linker flags.
|
||||
For Xcode, this can be done by adding it to "Other linker flags" in the build
|
||||
settings. For Bazel, this can be done with ``--linkopt`` or with
|
||||
`rules_apple_linker <https://github.com/keith/rules_apple_linker>`_.
|
||||
settings. For Bazel, this can be done with `--linkopt` or with
|
||||
[rules_apple_linker](https://github.com/keith/rules_apple_linker).
|
||||
|
||||
.. seealso::
|
||||
:::{seealso}
|
||||
{doc}`ld64-vs-lld` has more info on the differences between the two linkers.
|
||||
:::
|
||||
|
||||
:doc:`ld64-vs-lld` has more info on the differences between the two linkers.
|
||||
```{toctree}
|
||||
:hidden: true
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
ld64-vs-lld
|
||||
```
|
||||
|
||||
ld64-vs-lld
|
||||
|
|
|
|||
|
|
@ -1,45 +1,42 @@
|
|||
=================
|
||||
ld64 vs LLD-MachO
|
||||
=================
|
||||
# ld64 vs LLD-MachO
|
||||
|
||||
This doc lists all significant deliberate differences in behavior between ld64
|
||||
and LLD-MachO.
|
||||
|
||||
Dead Stripping Duplicate Symbols
|
||||
********************************
|
||||
## Dead Stripping Duplicate Symbols
|
||||
|
||||
ld64 strips dead code before reporting duplicate symbols. By default, LLD does
|
||||
the opposite. ld64's behavior hides ODR violations, so we have chosen not
|
||||
to follow it. But, to make adoption easy, LLD can mimic this behavior via
|
||||
the ``--dead-strip-duplicates`` flag. Usage of this flag is discouraged, and
|
||||
the `--dead-strip-duplicates` flag. Usage of this flag is discouraged, and
|
||||
this behavior should be fixed in the source. However, for sources that are not
|
||||
within the user's control, this will mitigate users for adoption.
|
||||
|
||||
``-no_deduplicate`` Flag
|
||||
************************
|
||||
## `-no_deduplicate` Flag
|
||||
|
||||
- ld64: This turns off ICF (deduplication pass) in the linker.
|
||||
- LLD: This turns off ICF and string merging in the linker.
|
||||
|
||||
String Alignment
|
||||
****************
|
||||
LLD is `slightly less conservative about aligning cstrings
|
||||
<https://reviews.llvm.org/D121342>`_, allowing it to pack them more compactly.
|
||||
## String Alignment
|
||||
|
||||
LLD is [slightly less conservative about aligning cstrings](https://reviews.llvm.org/D121342), allowing it to pack them more compactly.
|
||||
This should not result in any meaningful semantic difference.
|
||||
|
||||
ObjC Symbols Treatment
|
||||
**********************
|
||||
## ObjC Symbols Treatment
|
||||
|
||||
There are differences in how LLD and ld64 handle ObjC symbols loaded from
|
||||
archives.
|
||||
|
||||
- ld64:
|
||||
1. Duplicate ObjC symbols from the same archives will not raise an error.
|
||||
ld64 will pick the first one.
|
||||
2. Duplicate ObjC symbols from different archives will raise a "duplicate
|
||||
symbol" error.
|
||||
: 1. Duplicate ObjC symbols from the same archives will not raise an error.
|
||||
ld64 will pick the first one.
|
||||
2. Duplicate ObjC symbols from different archives will raise a "duplicate
|
||||
symbol" error.
|
||||
- LLD: Duplicate symbols, regardless of which archives they are from, will
|
||||
raise errors.
|
||||
|
||||
Aliases
|
||||
=======
|
||||
### Aliases
|
||||
|
||||
ld64 treats all aliases as strong extern definitions. Having two aliases of the
|
||||
same name, or an alias plus a regular extern symbol of the same name, both
|
||||
result in duplicate symbol errors. LLD does not check for duplicate aliases;
|
||||
|
|
@ -47,10 +44,11 @@ instead we perform alias resolution first, and only then do we check for
|
|||
duplicate symbols. In particular, we will not report a duplicate symbol error if
|
||||
the aliased symbols turn out to be weak definitions, but ld64 will.
|
||||
|
||||
``ZERO_AR_DATE`` enabled by default
|
||||
***********************************
|
||||
## `ZERO_AR_DATE` enabled by default
|
||||
|
||||
ld64 has a special mode where it sets some stabs modification times to 0 for
|
||||
hermetic builds, enabled by setting any value for the ``ZERO_AR_DATE``
|
||||
hermetic builds, enabled by setting any value for the `ZERO_AR_DATE`
|
||||
environment variable. LLD flips this default to prefer hermetic builds, but
|
||||
allows disabling this behavior by setting ``ZERO_AR_DATE=0``. Any other value
|
||||
of ``ZERO_AR_DATE`` will be ignored.
|
||||
allows disabling this behavior by setting `ZERO_AR_DATE=0`. Any other value
|
||||
of `ZERO_AR_DATE` will be ignored.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
The ELF, COFF and Wasm Linkers
|
||||
==============================
|
||||
# The ELF, COFF and Wasm Linkers
|
||||
|
||||
The ELF Linker as a Library
|
||||
---------------------------
|
||||
## The ELF Linker as a Library
|
||||
|
||||
You can embed LLD to your program by linking against it and calling the linker's
|
||||
entry point function ``lld::lldMain``.
|
||||
entry point function `lld::lldMain`.
|
||||
|
||||
The current policy is that it is your responsibility to give trustworthy object
|
||||
files. The function is guaranteed to return as long as you do not pass corrupted
|
||||
|
|
@ -14,13 +12,11 @@ That being said, you don't need to worry too much about it if you create object
|
|||
files in the usual way and give them to the linker. It is naturally expected to
|
||||
work, or otherwise it's a linker's bug.
|
||||
|
||||
Design
|
||||
======
|
||||
# Design
|
||||
|
||||
We will describe the design of the linkers in the rest of the document.
|
||||
|
||||
Key Concepts
|
||||
------------
|
||||
## Key Concepts
|
||||
|
||||
Linkers are fairly large pieces of software.
|
||||
There are many design choices you have to make to create a complete linker.
|
||||
|
|
@ -29,7 +25,7 @@ This is a list of design choices we've made for ELF and COFF LLD.
|
|||
We believe that these high-level design choices achieved a right balance
|
||||
between speed, simplicity and extensibility.
|
||||
|
||||
* Implement as native linkers
|
||||
- Implement as native linkers
|
||||
|
||||
We implemented the linkers as native linkers for each file format.
|
||||
|
||||
|
|
@ -37,10 +33,10 @@ between speed, simplicity and extensibility.
|
|||
Sharing code makes sense if the benefit is worth its cost.
|
||||
In our case, the object formats are different enough that we thought the layer
|
||||
to abstract the differences wouldn't be worth its complexity and run-time
|
||||
cost. Elimination of the abstract layer has greatly simplified the
|
||||
cost. Elimination of the abstract layer has greatly simplified the
|
||||
implementation.
|
||||
|
||||
* Speed by design
|
||||
- Speed by design
|
||||
|
||||
One of the most important things in achieving high performance is to
|
||||
do less rather than do it efficiently.
|
||||
|
|
@ -56,7 +52,7 @@ between speed, simplicity and extensibility.
|
|||
We obtain a handle (which is typically just a pointer to actual data)
|
||||
on the first operation and use it throughout the process.
|
||||
|
||||
* Efficient archive file handling
|
||||
- Efficient archive file handling
|
||||
|
||||
LLD's handling of archive files (the files with ".a" file extension) is
|
||||
different from the traditional Unix linkers and similar to Windows linkers.
|
||||
|
|
@ -64,28 +60,27 @@ between speed, simplicity and extensibility.
|
|||
problem is, and how LLD approached the problem.
|
||||
|
||||
The traditional Unix linker maintains a set of undefined symbols during
|
||||
linking. The linker visits each file in the order as they appeared in the
|
||||
linking. The linker visits each file in the order as they appeared in the
|
||||
command line until the set becomes empty. What the linker would do depends on
|
||||
file type.
|
||||
|
||||
- If the linker visits an object file, the linker links object files to the
|
||||
result, and undefined symbols in the object file are added to the set.
|
||||
|
||||
- If the linker visits an archive file, it checks for the archive file's
|
||||
symbol table and extracts all object files that have definitions for any
|
||||
symbols in the set.
|
||||
|
||||
This algorithm sometimes leads to a counter-intuitive behavior. If you give
|
||||
This algorithm sometimes leads to a counter-intuitive behavior. If you give
|
||||
archive files before object files, nothing will happen because when the linker
|
||||
visits archives, there are no undefined symbols in the set. As a result, no
|
||||
visits archives, there are no undefined symbols in the set. As a result, no
|
||||
files are extracted from the first archive file, and the link is done at that
|
||||
point because the set is empty after it visits one file.
|
||||
|
||||
You can fix the problem by reordering the files,
|
||||
but that cannot fix the issue of mutually-dependent archive files.
|
||||
|
||||
Linking mutually-dependent archive files is tricky. You may specify the same
|
||||
archive file multiple times to let the linker visit it more than once. Or,
|
||||
Linking mutually-dependent archive files is tricky. You may specify the same
|
||||
archive file multiple times to let the linker visit it more than once. Or,
|
||||
you may use the special command line options, `--start-group` and
|
||||
`--end-group`, to let the linker loop over the files between the options until
|
||||
no new symbols are added to the set.
|
||||
|
|
@ -93,21 +88,20 @@ between speed, simplicity and extensibility.
|
|||
Visiting the same archive files multiple times makes the linker slower.
|
||||
|
||||
Here is how LLD approaches the problem. Instead of memorizing only undefined
|
||||
symbols, we program LLD so that it memorizes all symbols. When it sees an
|
||||
symbols, we program LLD so that it memorizes all symbols. When it sees an
|
||||
undefined symbol that can be resolved by extracting an object file from an
|
||||
archive file it previously visited, it immediately extracts the file and links
|
||||
it. It is doable because LLD does not forget symbols it has seen in archive
|
||||
it. It is doable because LLD does not forget symbols it has seen in archive
|
||||
files.
|
||||
|
||||
We believe that LLD's way is efficient and easy to justify.
|
||||
|
||||
The semantics of LLD's archive handling are different from the traditional
|
||||
Unix's. You can observe it if you carefully craft archive files to exploit
|
||||
it. However, in reality, we don't know any program that cannot link with our
|
||||
Unix's. You can observe it if you carefully craft archive files to exploit
|
||||
it. However, in reality, we don't know any program that cannot link with our
|
||||
algorithm so far, so it's not going to cause trouble.
|
||||
|
||||
Numbers You Want to Know
|
||||
------------------------
|
||||
## Numbers You Want to Know
|
||||
|
||||
To give you intuition about what kinds of data the linker is mainly working on,
|
||||
I'll give you the list of objects and their numbers LLD has to read and process
|
||||
|
|
@ -136,14 +130,13 @@ it would slow down the linker by 10%. So, don't do that.
|
|||
On the other hand, you don't have to pursue efficiency
|
||||
when handling files.
|
||||
|
||||
Important Data Structures
|
||||
-------------------------
|
||||
## Important Data Structures
|
||||
|
||||
We will describe the key data structures in LLD in this section. The linker can
|
||||
be understood as the interactions between them. Once you understand their
|
||||
We will describe the key data structures in LLD in this section. The linker can
|
||||
be understood as the interactions between them. Once you understand their
|
||||
functions, the code of the linker should look obvious to you.
|
||||
|
||||
* Symbol
|
||||
- Symbol
|
||||
|
||||
This class represents a symbol.
|
||||
They are created for symbols in object files or archive files.
|
||||
|
|
@ -171,7 +164,7 @@ functions, the code of the linker should look obvious to you.
|
|||
defined symbol, because the undefined symbol the pointer pointed to will have
|
||||
been replaced by the defined symbol in-place.
|
||||
|
||||
* SymbolTable
|
||||
- SymbolTable
|
||||
|
||||
SymbolTable is basically a hash table from strings to Symbols
|
||||
with logic to resolve symbol conflicts. It resolves conflicts by symbol type.
|
||||
|
|
@ -183,7 +176,7 @@ functions, the code of the linker should look obvious to you.
|
|||
but it will also trigger the Lazy symbol to load the archive member
|
||||
to actually resolve the symbol.
|
||||
|
||||
* Chunk (COFF specific)
|
||||
- Chunk (COFF specific)
|
||||
|
||||
Chunk represents a chunk of data that will occupy space in an output.
|
||||
Each regular section becomes a chunk.
|
||||
|
|
@ -195,7 +188,7 @@ functions, the code of the linker should look obvious to you.
|
|||
Specifically, section-based chunks know how to read relocation tables
|
||||
and how to apply them.
|
||||
|
||||
* InputSection (ELF specific)
|
||||
- InputSection (ELF specific)
|
||||
|
||||
Since we have less synthesized data for ELF, we don't abstract slices of
|
||||
input files as Chunks for ELF. Instead, we directly use the input section
|
||||
|
|
@ -204,28 +197,28 @@ functions, the code of the linker should look obvious to you.
|
|||
InputSection knows about their size and how to copy themselves to
|
||||
mmap'ed outputs, just like COFF Chunks.
|
||||
|
||||
* OutputSection
|
||||
- OutputSection
|
||||
|
||||
OutputSection is a container of InputSections (ELF) or Chunks (COFF).
|
||||
An InputSection or Chunk belongs to at most one OutputSection.
|
||||
|
||||
There are mainly three actors in this linker.
|
||||
|
||||
* InputFile
|
||||
- InputFile
|
||||
|
||||
InputFile is a superclass of file readers.
|
||||
We have a different subclass for each input file type,
|
||||
such as regular object file, archive file, etc.
|
||||
They are responsible for creating and owning Symbols and InputSections/Chunks.
|
||||
|
||||
* Writer
|
||||
- Writer
|
||||
|
||||
The writer is responsible for writing file headers and InputSections/Chunks to
|
||||
a file. It creates OutputSections, puts all InputSections/Chunks into them,
|
||||
a file. It creates OutputSections, puts all InputSections/Chunks into them,
|
||||
assigns unique, non-overlapping addresses and file offsets to them, and then
|
||||
writes them down to a file.
|
||||
|
||||
* Driver
|
||||
- Driver
|
||||
|
||||
The linking process is driven by the driver. The driver:
|
||||
|
||||
|
|
@ -237,8 +230,7 @@ There are mainly three actors in this linker.
|
|||
- creates a writer,
|
||||
- and passes the symbol table to the writer to write the result to a file.
|
||||
|
||||
Link-Time Optimization
|
||||
----------------------
|
||||
## Link-Time Optimization
|
||||
|
||||
LTO is implemented by handling LLVM bitcode files as object files.
|
||||
The linker resolves symbols in bitcode files normally. If all symbols
|
||||
|
|
@ -248,12 +240,11 @@ Finally, the linker replaces bitcode symbols with ELF/COFF symbols,
|
|||
so that they are linked as if they were in the native format from the beginning.
|
||||
|
||||
The details are described in this document.
|
||||
https://llvm.org/docs/LinkTimeOptimization.html
|
||||
<https://llvm.org/docs/LinkTimeOptimization.html>
|
||||
|
||||
Glossary
|
||||
--------
|
||||
## Glossary
|
||||
|
||||
* RVA (COFF)
|
||||
- RVA (COFF)
|
||||
|
||||
Short for Relative Virtual Address.
|
||||
|
||||
|
|
@ -267,11 +258,11 @@ Glossary
|
|||
loader, so we apply relocations accordingly. Result texts and data
|
||||
will contain raw absolute addresses.
|
||||
|
||||
* VA
|
||||
- VA
|
||||
|
||||
Short for Virtual Address. For COFF, it is equivalent to RVA + image base.
|
||||
|
||||
* Base relocations (COFF)
|
||||
- Base relocations (COFF)
|
||||
|
||||
Relocation information for the loader. If the loader decides to map
|
||||
an executable or a DLL to a different address than their image
|
||||
|
|
@ -286,7 +277,7 @@ Glossary
|
|||
this breaks text sharing, I think this mechanism is not actually bad
|
||||
on today's computers.
|
||||
|
||||
* ICF
|
||||
- ICF
|
||||
|
||||
Short for Identical COMDAT Folding (COFF) or Identical Code Folding (ELF).
|
||||
|
||||
|
|
@ -308,10 +299,11 @@ Glossary
|
|||
although large programs happen to work correctly.
|
||||
LLD works fine with ICF for example.
|
||||
|
||||
Other Info
|
||||
----------
|
||||
## Other Info
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
```{toctree}
|
||||
:maxdepth: 1
|
||||
|
||||
missingkeyfunction
|
||||
```
|
||||
|
||||
missingkeyfunction
|
||||
|
|
|
|||
|
|
@ -1,48 +1,42 @@
|
|||
.. If you want to modify sections/contents permanently, you should modify both
|
||||
ReleaseNotes.rst and ReleaseNotesTemplate.txt.
|
||||
<!-- If you want to modify sections/contents permanently, you should modify both
|
||||
ReleaseNotes.md and ReleaseNotesTemplate.txt. -->
|
||||
|
||||
===========================
|
||||
lld |release| Release Notes
|
||||
===========================
|
||||
(lld-release-release-notes)=
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
# lld {{ release | default("") }} Release Notes
|
||||
|
||||
.. only:: PreRelease
|
||||
```{contents}
|
||||
:local: true
|
||||
```
|
||||
|
||||
.. warning::
|
||||
These are in-progress notes for the upcoming LLVM |release| release.
|
||||
Release notes for previous releases can be found on
|
||||
`the Download Page <https://releases.llvm.org/download.html>`_.
|
||||
::::{only} PreRelease
|
||||
|
||||
Introduction
|
||||
============
|
||||
:::{warning}
|
||||
These are in-progress notes for the upcoming LLVM {{ release | default("") }} release.
|
||||
Release notes for previous releases can be found on
|
||||
[the Download Page](https://releases.llvm.org/download.html).
|
||||
:::
|
||||
::::
|
||||
|
||||
This document contains the release notes for the lld linker, release |release|.
|
||||
## Introduction
|
||||
|
||||
This document contains the release notes for the lld linker, release {{ release | default("") }}.
|
||||
Here we describe the status of lld, including major improvements
|
||||
from the previous release. All lld releases may be downloaded
|
||||
from the `LLVM releases web site <https://llvm.org/releases/>`_.
|
||||
from the [LLVM releases web site](https://llvm.org/releases/).
|
||||
|
||||
Non-comprehensive list of changes in this release
|
||||
=================================================
|
||||
## Non-comprehensive list of changes in this release
|
||||
|
||||
ELF Improvements
|
||||
----------------
|
||||
### ELF Improvements
|
||||
|
||||
Breaking changes
|
||||
----------------
|
||||
### Breaking changes
|
||||
|
||||
COFF Improvements
|
||||
-----------------
|
||||
### COFF Improvements
|
||||
|
||||
MinGW Improvements
|
||||
------------------
|
||||
### MinGW Improvements
|
||||
|
||||
MachO Improvements
|
||||
------------------
|
||||
### MachO Improvements
|
||||
|
||||
WebAssembly Improvements
|
||||
------------------------
|
||||
### WebAssembly Improvements
|
||||
|
||||
Fixes
|
||||
#####
|
||||
#### Fixes
|
||||
|
|
|
|||
|
|
@ -1,264 +1,251 @@
|
|||
WebAssembly lld port
|
||||
====================
|
||||
# WebAssembly lld port
|
||||
|
||||
The WebAssembly version of lld takes WebAssembly binaries as inputs and produces
|
||||
a WebAssembly binary as its output. For the most part it tries to mimic the
|
||||
behaviour of traditional ELF linkers and specifically the ELF lld port. Where
|
||||
a WebAssembly binary as its output. For the most part it tries to mimic the
|
||||
behaviour of traditional ELF linkers and specifically the ELF lld port. Where
|
||||
possible the command line flags and the semantics should be the same.
|
||||
|
||||
|
||||
Object file format
|
||||
------------------
|
||||
## Object file format
|
||||
|
||||
The WebAssembly object file format used by LLVM and LLD is specified as part of
|
||||
the WebAssembly tool conventions on linking_.
|
||||
the WebAssembly tool conventions on [linking].
|
||||
|
||||
This is the object format that the llvm will produce when run with the
|
||||
``wasm32-unknown-unknown`` target.
|
||||
`wasm32-unknown-unknown` target.
|
||||
|
||||
Usage
|
||||
-----
|
||||
## Usage
|
||||
|
||||
The WebAssembly version of lld is installed as **wasm-ld**. It shared many
|
||||
The WebAssembly version of lld is installed as **wasm-ld**. It shared many
|
||||
common linker flags with **ld.lld** but also includes several
|
||||
WebAssembly-specific options:
|
||||
|
||||
.. option:: --no-entry
|
||||
:::{option} --no-entry
|
||||
Don't search for the entry point symbol (by default `_start`).
|
||||
:::
|
||||
|
||||
Don't search for the entry point symbol (by default ``_start``).
|
||||
:::{option} --export-table
|
||||
Export the function table to the environment.
|
||||
:::
|
||||
|
||||
.. option:: --export-table
|
||||
:::{option} --import-table
|
||||
Import the function table from the environment.
|
||||
:::
|
||||
|
||||
Export the function table to the environment.
|
||||
:::{option} --export-all
|
||||
Export all symbols (normally combined with --no-gc-sections)
|
||||
|
||||
.. option:: --import-table
|
||||
Note that this will not export linker-generated mutable globals unless
|
||||
the resulting binaryen already includes the 'mutable-globals' features
|
||||
since that would otherwise create and invalid binaryen.
|
||||
:::
|
||||
|
||||
Import the function table from the environment.
|
||||
:::{option} --export-dynamic
|
||||
When building an executable, export any non-hidden symbols. By default only
|
||||
the entry point and any symbols marked as exports (either via the command line
|
||||
or via the `export-name` source attribute) are exported.
|
||||
:::
|
||||
|
||||
.. option:: --export-all
|
||||
:::{option} --global-base=<value>
|
||||
Address at which to place global data.
|
||||
:::
|
||||
|
||||
Export all symbols (normally combined with --no-gc-sections)
|
||||
:::{option} --no-merge-data-segments
|
||||
Disable merging of data segments.
|
||||
:::
|
||||
|
||||
Note that this will not export linker-generated mutable globals unless
|
||||
the resulting binaryen already includes the 'mutable-globals' features
|
||||
since that would otherwise create and invalid binaryen.
|
||||
:::{option} --stack-first
|
||||
Place stack at start of linear memory rather than after data.
|
||||
:::
|
||||
|
||||
.. option:: --export-dynamic
|
||||
:::{option} --compress-relocations
|
||||
Relocation targets in the code section are 5-bytes wide in order to
|
||||
potentially accommodate the largest LEB128 value. This option will cause the
|
||||
linker to shrink the code section to remove any padding from the final
|
||||
output. However because it affects code offset, this option is not
|
||||
compatible with outputting debug information.
|
||||
:::
|
||||
|
||||
When building an executable, export any non-hidden symbols. By default only
|
||||
the entry point and any symbols marked as exports (either via the command line
|
||||
or via the `export-name` source attribute) are exported.
|
||||
:::{option} --allow-undefined
|
||||
Allow undefined symbols in linked binary. This is the legacy
|
||||
flag which corresponds to `--unresolve-symbols=ignore` +
|
||||
`--import-undefined`.
|
||||
:::
|
||||
|
||||
.. option:: --global-base=<value>
|
||||
:::{option} --allow-undefined-file=<filename>
|
||||
Like `--allow-undefined`, but the filename specified a flat list of
|
||||
symbols, one per line, which are allowed to be undefined.
|
||||
:::
|
||||
|
||||
Address at which to place global data.
|
||||
:::{option} --unresolved-symbols=<method>
|
||||
This is a more full featured version of `--allow-undefined`.
|
||||
The semantics of the different methods are as follows:
|
||||
|
||||
.. option:: --no-merge-data-segments
|
||||
`report-all`
|
||||
: Report all unresolved symbols. This is the default. Normally the linker
|
||||
will generate an error message for each reported unresolved symbol but the
|
||||
option `--warn-unresolved-symbols` can change this to a warning.
|
||||
|
||||
Disable merging of data segments.
|
||||
`ignore-all`
|
||||
: Resolve all undefined symbols to zero. For data and function addresses
|
||||
this is trivial. For direct function calls, the linker will generate a
|
||||
trapping stub function in place of the undefined function.
|
||||
|
||||
.. option:: --stack-first
|
||||
`import-dynamic`
|
||||
: Undefined symbols generate WebAssembly imports, including undefined data
|
||||
symbols. This is somewhat similar to the --import-undefined option but
|
||||
works all symbol types. This options puts limitations on the type of
|
||||
relocations that are allowed for imported data symbols. Relocations that
|
||||
require absolute data addresses (i.e. All R_WASM_MEMORY_ADDR_I32) will
|
||||
generate an error if they cannot be resolved statically. For clang/llvm
|
||||
this means inputs should be compiled with `-fPIC` (i.e. `pic` or
|
||||
`dynamic-no-pic` relocation models). This options is useful for linking
|
||||
binaries that are themselves static (non-relocatable) but whose undefined
|
||||
symbols are resolved by a dynamic linker.
|
||||
:::
|
||||
|
||||
Place stack at start of linear memory rather than after data.
|
||||
:::{option} --import-memory
|
||||
Import memory from the environment.
|
||||
:::
|
||||
|
||||
.. option:: --compress-relocations
|
||||
:::{option} --import-undefined
|
||||
Generate WebAssembly imports for undefined symbols, where possible. For
|
||||
example, for function symbols this is always possible, but in general this
|
||||
is not possible for undefined data symbols. Undefined data symbols will
|
||||
still be reported as normal (in accordance with `--unresolved-symbols`).
|
||||
:::
|
||||
|
||||
Relocation targets in the code section are 5-bytes wide in order to
|
||||
potentially accommodate the largest LEB128 value. This option will cause the
|
||||
linker to shrink the code section to remove any padding from the final
|
||||
output. However because it affects code offset, this option is not
|
||||
compatible with outputting debug information.
|
||||
:::{option} --initial-heap=<value>
|
||||
Initial size of the heap. Default: zero.
|
||||
:::
|
||||
|
||||
.. option:: --allow-undefined
|
||||
:::{option} --initial-memory=<value>
|
||||
Initial size of the linear memory. Default: the sum of stack, static data and heap sizes.
|
||||
:::
|
||||
|
||||
Allow undefined symbols in linked binary. This is the legacy
|
||||
flag which corresponds to ``--unresolve-symbols=ignore`` +
|
||||
``--import-undefined``.
|
||||
:::{option} --max-memory=<value>
|
||||
Maximum size of the linear memory. Default: unlimited.
|
||||
:::
|
||||
|
||||
.. option:: --allow-undefined-file=<filename>
|
||||
|
||||
Like ``--allow-undefined``, but the filename specified a flat list of
|
||||
symbols, one per line, which are allowed to be undefined.
|
||||
|
||||
.. option:: --unresolved-symbols=<method>
|
||||
|
||||
This is a more full featured version of ``--allow-undefined``.
|
||||
The semantics of the different methods are as follows:
|
||||
|
||||
report-all:
|
||||
|
||||
Report all unresolved symbols. This is the default. Normally the linker
|
||||
will generate an error message for each reported unresolved symbol but the
|
||||
option ``--warn-unresolved-symbols`` can change this to a warning.
|
||||
|
||||
ignore-all:
|
||||
|
||||
Resolve all undefined symbols to zero. For data and function addresses
|
||||
this is trivial. For direct function calls, the linker will generate a
|
||||
trapping stub function in place of the undefined function.
|
||||
|
||||
import-dynamic:
|
||||
|
||||
Undefined symbols generate WebAssembly imports, including undefined data
|
||||
symbols. This is somewhat similar to the --import-undefined option but
|
||||
works all symbol types. This options puts limitations on the type of
|
||||
relocations that are allowed for imported data symbols. Relocations that
|
||||
require absolute data addresses (i.e. All R_WASM_MEMORY_ADDR_I32) will
|
||||
generate an error if they cannot be resolved statically. For clang/llvm
|
||||
this means inputs should be compiled with `-fPIC` (i.e. `pic` or
|
||||
`dynamic-no-pic` relocation models). This options is useful for linking
|
||||
binaries that are themselves static (non-relocatable) but whose undefined
|
||||
symbols are resolved by a dynamic linker.
|
||||
|
||||
.. option:: --import-memory
|
||||
|
||||
Import memory from the environment.
|
||||
|
||||
.. option:: --import-undefined
|
||||
|
||||
Generate WebAssembly imports for undefined symbols, where possible. For
|
||||
example, for function symbols this is always possible, but in general this
|
||||
is not possible for undefined data symbols. Undefined data symbols will
|
||||
still be reported as normal (in accordance with ``--unresolved-symbols``).
|
||||
|
||||
.. option:: --initial-heap=<value>
|
||||
|
||||
Initial size of the heap. Default: zero.
|
||||
|
||||
.. option:: --initial-memory=<value>
|
||||
|
||||
Initial size of the linear memory. Default: the sum of stack, static data and heap sizes.
|
||||
|
||||
.. option:: --max-memory=<value>
|
||||
|
||||
Maximum size of the linear memory. Default: unlimited.
|
||||
|
||||
.. option:: --no-growable-memory
|
||||
|
||||
Set maximum size of the linear memory to its initial size, disallowing memory growth.
|
||||
:::{option} --no-growable-memory
|
||||
Set maximum size of the linear memory to its initial size, disallowing memory growth.
|
||||
:::
|
||||
|
||||
By default the function table is neither imported nor exported, but defined
|
||||
for internal use only.
|
||||
|
||||
Behaviour
|
||||
---------
|
||||
## Behaviour
|
||||
|
||||
In general, where possible, the WebAssembly linker attempts to emulate the
|
||||
behaviour of a traditional ELF linker, and in particular the ELF port of lld.
|
||||
For more specific details on how this is achieved see the tool conventions on
|
||||
linking_.
|
||||
[linking].
|
||||
|
||||
Function Signatures
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
### Function Signatures
|
||||
|
||||
One way in which the WebAssembly linker differs from traditional native linkers
|
||||
is that function signature checking is strict in WebAssembly. It is a
|
||||
is that function signature checking is strict in WebAssembly. It is a
|
||||
validation error for a module to contain a call site that doesn't agree with
|
||||
the target signature. Even though this is undefined behaviour in C/C++, it is not
|
||||
uncommon to find this in real-world C/C++ programs. For example, a call site in
|
||||
the target signature. Even though this is undefined behaviour in C/C++, it is not
|
||||
uncommon to find this in real-world C/C++ programs. For example, a call site in
|
||||
one compilation unit which calls a function defined in another compilation
|
||||
unit but with too many arguments.
|
||||
|
||||
In order not to generate such invalid modules, lld has two modes of handling such
|
||||
mismatches: it can simply error-out or it can create stub functions that will
|
||||
trap at runtime (functions that contain only an ``unreachable`` instruction)
|
||||
trap at runtime (functions that contain only an `unreachable` instruction)
|
||||
and use these stub functions at the otherwise invalid call sites.
|
||||
|
||||
The default behaviour is to generate these stub function and to produce
|
||||
a warning. The ``--fatal-warnings`` flag can be used to disable this behaviour
|
||||
a warning. The `--fatal-warnings` flag can be used to disable this behaviour
|
||||
and error out if mismatched are found.
|
||||
|
||||
Exports
|
||||
~~~~~~~
|
||||
### Exports
|
||||
|
||||
When building a shared library any symbols marked as ``visibility=default`` will
|
||||
When building a shared library any symbols marked as `visibility=default` will
|
||||
be exported.
|
||||
|
||||
When building an executable, only the entry point (``_start``) and symbols with
|
||||
the ``WASM_SYMBOL_EXPORTED`` flag are exported by default. In LLVM the
|
||||
``WASM_SYMBOL_EXPORTED`` flag is set by the ``wasm-export-name`` attribute which
|
||||
in turn can be set using ``__attribute__((export_name))`` clang attribute.
|
||||
When building an executable, only the entry point (`_start`) and symbols with
|
||||
the `WASM_SYMBOL_EXPORTED` flag are exported by default. In LLVM the
|
||||
`WASM_SYMBOL_EXPORTED` flag is set by the `wasm-export-name` attribute which
|
||||
in turn can be set using `__attribute__((export_name))` clang attribute.
|
||||
|
||||
In addition, symbols can be exported via the linker command line using
|
||||
``--export`` (which will error if the symbol is not found) or
|
||||
``--export-if-defined`` (which will not).
|
||||
`--export` (which will error if the symbol is not found) or
|
||||
`--export-if-defined` (which will not).
|
||||
|
||||
Finally, just like with native ELF linker the ``--export-dynamic`` flag can be
|
||||
Finally, just like with native ELF linker the `--export-dynamic` flag can be
|
||||
used to export symbols in the executable which are marked as
|
||||
``visibility=default``.
|
||||
`visibility=default`.
|
||||
|
||||
Imports
|
||||
~~~~~~~
|
||||
### Imports
|
||||
|
||||
By default no undefined symbols are allowed in the final binary. The flag
|
||||
``--allow-undefined`` results in a WebAssembly import being defined for each
|
||||
undefined symbol. It is then up to the runtime to provide such symbols.
|
||||
``--allow-undefined-file`` is the same but allows a list of symbols to be
|
||||
By default no undefined symbols are allowed in the final binary. The flag
|
||||
`--allow-undefined` results in a WebAssembly import being defined for each
|
||||
undefined symbol. It is then up to the runtime to provide such symbols.
|
||||
`--allow-undefined-file` is the same but allows a list of symbols to be
|
||||
specified.
|
||||
|
||||
Alternatively symbols can be marked in the source code as with the
|
||||
``import_name`` and/or ``import_module`` clang attributes which signals that
|
||||
`import_name` and/or `import_module` clang attributes which signals that
|
||||
they are expected to be undefined at static link time.
|
||||
|
||||
Stub Libraries
|
||||
~~~~~~~~~~~~~~
|
||||
### Stub Libraries
|
||||
|
||||
Another way to specify imports and exports is via a "stub library". This
|
||||
Another way to specify imports and exports is via a "stub library". This
|
||||
feature is inspired by the ELF stub objects which are supported by the Solaris
|
||||
linker. Stub libraries are text files that can be passed as normal linker
|
||||
inputs, similar to how linker scripts can be passed to the ELF linker. The stub
|
||||
linker. Stub libraries are text files that can be passed as normal linker
|
||||
inputs, similar to how linker scripts can be passed to the ELF linker. The stub
|
||||
library is a stand-in for a set of symbols that will be available at runtime,
|
||||
but doesn't contain any actual code or data. Instead it contains just a list of
|
||||
symbols, one per line. Each symbol can specify zero or more dependencies.
|
||||
but doesn't contain any actual code or data. Instead it contains just a list of
|
||||
symbols, one per line. Each symbol can specify zero or more dependencies.
|
||||
These dependencies are symbols that must be defined, and exported, by the output
|
||||
module if the symbol is question is imported/required by the output module.
|
||||
|
||||
For example, imagine the runtime provides an external symbol ``foo`` that
|
||||
depends on the ``malloc`` and ``free``. This can be expressed simply as::
|
||||
For example, imagine the runtime provides an external symbol `foo` that
|
||||
depends on the `malloc` and `free`. This can be expressed simply as:
|
||||
|
||||
#STUB
|
||||
foo: malloc,free
|
||||
```
|
||||
#STUB
|
||||
foo: malloc,free
|
||||
```
|
||||
|
||||
Here we are saying that ``foo`` is allowed to be imported (undefined) but that
|
||||
if it is imported, then the output module must also export ``malloc`` and
|
||||
``free`` to the runtime. If ``foo`` is imported (undefined), but the output
|
||||
module does not define ``malloc`` and ``free`` then the link will fail.
|
||||
Here we are saying that `foo` is allowed to be imported (undefined) but that
|
||||
if it is imported, then the output module must also export `malloc` and
|
||||
`free` to the runtime. If `foo` is imported (undefined), but the output
|
||||
module does not define `malloc` and `free` then the link will fail.
|
||||
|
||||
Stub libraries must begin with ``#STUB`` on a line by itself.
|
||||
Stub libraries must begin with `#STUB` on a line by itself.
|
||||
|
||||
Garbage Collection
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
### Garbage Collection
|
||||
|
||||
Since WebAssembly is designed with size in mind the linker defaults to
|
||||
``--gc-sections`` which means that all unused functions and data segments will
|
||||
`--gc-sections` which means that all unused functions and data segments will
|
||||
be stripped from the binary.
|
||||
|
||||
The symbols which are preserved by default are:
|
||||
|
||||
- The entry point (by default ``_start``).
|
||||
- The entry point (by default `_start`).
|
||||
- Any symbol which is to be exported.
|
||||
- Any symbol transitively referenced by the above.
|
||||
|
||||
Weak Undefined Functions
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
### Weak Undefined Functions
|
||||
|
||||
On native platforms, calls to weak undefined functions end up as calls to the
|
||||
null function pointer. With WebAssembly, direct calls must reference a defined
|
||||
function (with the correct signature). In order to handle this case the linker
|
||||
will generate function a stub containing only the ``unreachable`` instruction
|
||||
null function pointer. With WebAssembly, direct calls must reference a defined
|
||||
function (with the correct signature). In order to handle this case the linker
|
||||
will generate function a stub containing only the `unreachable` instruction
|
||||
and use this for any direct references to an undefined weak function.
|
||||
|
||||
For example a runtime call to a weak undefined function ``foo`` will up trapping
|
||||
on ``unreachable`` inside and linker-generated function called
|
||||
``undefined:foo``.
|
||||
For example a runtime call to a weak undefined function `foo` will up trapping
|
||||
on `unreachable` inside and linker-generated function called
|
||||
`undefined:foo`.
|
||||
|
||||
Missing features
|
||||
----------------
|
||||
## Missing features
|
||||
|
||||
- Merging of data section similar to ``SHF_MERGE`` in the ELF world is not
|
||||
- Merging of data section similar to `SHF_MERGE` in the ELF world is not
|
||||
supported.
|
||||
- Dynamic linking support is still experimental. The spec for this is not
|
||||
- Dynamic linking support is still experimental. The spec for this is not
|
||||
yet finalized:
|
||||
https://github.com/WebAssembly/tool-conventions/blob/main/DynamicLinking.md
|
||||
<https://github.com/WebAssembly/tool-conventions/blob/main/DynamicLinking.md>
|
||||
|
||||
.. _linking: https://github.com/WebAssembly/tool-conventions/blob/main/Linking.md
|
||||
[linking]: https://github.com/WebAssembly/tool-conventions/blob/main/Linking.md
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ globals().update(common_conf(tags, markdown=Markdown.EXCEPT_MAN))
|
|||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions += ["sphinx.ext.intersphinx", "sphinx.ext.todo"]
|
||||
myst_enable_extensions.append("deflist")
|
||||
|
||||
# General information about the project.
|
||||
project = "lld"
|
||||
|
|
@ -220,6 +221,25 @@ texinfo_documents = [
|
|||
# texinfo_show_urls = 'footnote'
|
||||
|
||||
|
||||
# This can be treated as its own sphinx extension. setup() will be called by
|
||||
# sphinx. In it, register a function to be called when the configuration has
|
||||
# been initialized. The configuration will contain the values of the -D options
|
||||
# passed to sphinx-build on the command line.
|
||||
#
|
||||
# See llvm/cmake/modules/AddSphinxTarget.cmake for details on how sphinx-build
|
||||
# is invoked.
|
||||
def setup(app):
|
||||
app.connect("config-inited", myst_substitutions_update)
|
||||
|
||||
|
||||
# Override the myst_parser substitutions map after the configuration has been
|
||||
# initialized.
|
||||
def myst_substitutions_update(app, config):
|
||||
config.myst_substitutions.update(
|
||||
{"release": config.release, "version": config.version}
|
||||
)
|
||||
|
||||
|
||||
# FIXME: Define intersphinx configuration.
|
||||
intersphinx_mapping = {}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,39 +1,36 @@
|
|||
=====================
|
||||
Error Handling Script
|
||||
=====================
|
||||
# Error Handling Script
|
||||
|
||||
LLD provides the ability to hook into some error handling routines through a
|
||||
user-provided script specified with ``--error-handling-script=<path to the script>``
|
||||
user-provided script specified with `--error-handling-script=<path to the script>`
|
||||
when certain errors are encountered. This document specifies the requirements of
|
||||
such a script.
|
||||
|
||||
Generic Requirements
|
||||
====================
|
||||
## Generic Requirements
|
||||
|
||||
The script is expected to be available in the ``PATH`` or to be provided using a
|
||||
The script is expected to be available in the `PATH` or to be provided using a
|
||||
full path. It must be executable. It is executed in the same environment as the
|
||||
parent process.
|
||||
|
||||
Arguments
|
||||
=========
|
||||
## Arguments
|
||||
|
||||
LLD calls the error handling script using the following arguments::
|
||||
LLD calls the error handling script using the following arguments:
|
||||
|
||||
error-handling-script <tag> <tag-specific-arguments...>
|
||||
```
|
||||
error-handling-script <tag> <tag-specific-arguments...>
|
||||
```
|
||||
|
||||
The following tags are supported:
|
||||
|
||||
- ``missing-lib``: indicates that LLD failed to find a library. The library name
|
||||
is specified as the second argument, e.g. ``error-handling-script missing-lib
|
||||
mylib``
|
||||
|
||||
- ``undefined-symbol``: indicates that given symbol is marked as undefined. The
|
||||
- `missing-lib`: indicates that LLD failed to find a library. The library name
|
||||
is specified as the second argument, e.g. `error-handling-script missing-lib
|
||||
mylib`
|
||||
- `undefined-symbol`: indicates that given symbol is marked as undefined. The
|
||||
unmangled symbol name is specified as the second argument, e.g.
|
||||
``error-handling-script undefined-symbol mysymbol``
|
||||
`error-handling-script undefined-symbol mysymbol`
|
||||
|
||||
Return Value
|
||||
============
|
||||
## Return Value
|
||||
|
||||
Upon success, the script is expected to return 0. A non-zero value is
|
||||
interpreted as an error and reported to the user. In both cases, LLD still
|
||||
reports the original error.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
LLD - The LLVM Linker
|
||||
=====================
|
||||
# LLD - The LLVM Linker
|
||||
|
||||
LLD is a linker from the LLVM project that is a drop-in replacement
|
||||
for system linkers and runs much faster than them. It also provides
|
||||
|
|
@ -11,138 +10,125 @@ several different linkers. The ELF port is the one that will be described in
|
|||
this document. The PE/COFF port is complete, including
|
||||
Windows debug info (PDB) support.
|
||||
|
||||
Features
|
||||
--------
|
||||
## Features
|
||||
|
||||
- LLD is a drop-in replacement for the GNU linkers that accepts the
|
||||
same command line arguments and linker scripts as GNU.
|
||||
|
||||
- LLD is very fast. When you link a large program on a multicore
|
||||
machine, you can expect that LLD runs more than twice as fast as the GNU
|
||||
gold linker. Your mileage may vary, though.
|
||||
|
||||
- It supports various CPUs/ABIs including AArch64, AMDGPU, ARM, Hexagon,
|
||||
LoongArch, MIPS 32/64 big/little-endian, PowerPC, PowerPC64, RISC-V,
|
||||
SPARC V9, x86-32 and x86-64. Among these, AArch64, ARM (>= v4), LoongArch,
|
||||
PowerPC, PowerPC64, RISC-V, x86-32 and x86-64 have production quality.
|
||||
MIPS seems decent too.
|
||||
|
||||
- It is always a cross-linker, meaning that it always supports all the
|
||||
above targets however it was built. In fact, we don't provide a
|
||||
build-time option to enable/disable each target. This should make it
|
||||
easy to use our linker as part of a cross-compile toolchain.
|
||||
|
||||
- You can embed LLD in your program to eliminate dependencies on
|
||||
external linkers. All you have to do is to construct object files
|
||||
and command line arguments just like you would do to invoke an
|
||||
external linker and then call the linker's main function,
|
||||
``lld::lldMain``, from your code.
|
||||
|
||||
`lld::lldMain`, from your code.
|
||||
- It is small. We are using LLVM libObject library to read from object
|
||||
files, so it is not a completely fair comparison, but as of February
|
||||
2017, LLD/ELF consists only of 21k lines of C++ code while GNU gold
|
||||
consists of 198k lines of C++ code.
|
||||
|
||||
- Link-time optimization (LTO) is supported by default. Essentially,
|
||||
all you have to do to do LTO is to pass the ``-flto`` option to clang.
|
||||
all you have to do to do LTO is to pass the `-flto` option to clang.
|
||||
Then clang creates object files not in the native object file format
|
||||
but in LLVM bitcode format. LLD reads bitcode object files, compile
|
||||
them using LLVM and emit an output file. Because in this way LLD can
|
||||
see the entire program, it can do the whole program optimization.
|
||||
|
||||
- Some very old features for ancient Unix systems (pre-90s or even
|
||||
before that) have been removed. Some default settings have been
|
||||
tuned for the 21st century. For example, the stack is marked as
|
||||
non-executable by default to tighten security.
|
||||
|
||||
Performance
|
||||
-----------
|
||||
## Performance
|
||||
|
||||
This is a link time comparison on a 2-socket 20-core 40-thread Xeon
|
||||
E5-2680 2.80 GHz machine with an SSD drive. We ran gold and lld with
|
||||
or without multi-threading support. To disable multi-threading, we
|
||||
added ``-no-threads`` to the command lines.
|
||||
added `-no-threads` to the command lines.
|
||||
|
||||
============ =========== ============ ==================== ================== =============== =============
|
||||
Program Output size GNU ld GNU gold w/o threads GNU gold w/threads lld w/o threads lld w/threads
|
||||
ffmpeg dbg 92 MiB 1.72s 1.16s 1.01s 0.60s 0.35s
|
||||
mysqld dbg 154 MiB 8.50s 2.96s 2.68s 1.06s 0.68s
|
||||
clang dbg 1.67 GiB 104.03s 34.18s 23.49s 14.82s 5.28s
|
||||
chromium dbg 1.14 GiB 209.05s [1]_ 64.70s 60.82s 27.60s 16.70s
|
||||
============ =========== ============ ==================== ================== =============== =============
|
||||
| Program | Output size | GNU ld | GNU gold w/o threads | GNU gold w/threads | lld w/o threads | lld w/threads |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| ffmpeg dbg | 92 MiB | 1.72s | 1.16s | 1.01s | 0.60s | 0.35s |
|
||||
| mysqld dbg | 154 MiB | 8.50s | 2.96s | 2.68s | 1.06s | 0.68s |
|
||||
| clang dbg | 1.67 GiB | 104.03s | 34.18s | 23.49s | 14.82s | 5.28s |
|
||||
| chromium dbg | 1.14 GiB | 209.05s[^1] | 64.70s | 60.82s | 27.60s | 16.70s |
|
||||
|
||||
As you can see, lld is significantly faster than GNU linkers.
|
||||
Note that this is just a benchmark result of our environment.
|
||||
Depending on number of available cores, available amount of memory or
|
||||
disk latency/throughput, your results may vary.
|
||||
|
||||
.. [1] Since GNU ld doesn't support the ``-icf=all`` and
|
||||
``-gdb-index`` options, we removed them from the command line
|
||||
for GNU ld. GNU ld would have been slower than this if it had
|
||||
these options.
|
||||
[^1]: Since GNU ld doesn't support the `-icf=all` and
|
||||
`-gdb-index` options, we removed them from the command line
|
||||
for GNU ld. GNU ld would have been slower than this if it had
|
||||
these options.
|
||||
|
||||
Build
|
||||
-----
|
||||
## Build
|
||||
|
||||
If you have already checked out LLVM using SVN, you can check out LLD
|
||||
under ``tools`` directory just like you probably did for clang. For the
|
||||
details, see `Getting Started with the LLVM System
|
||||
<https://llvm.org/docs/GettingStarted.html>`_.
|
||||
under `tools` directory just like you probably did for clang. For the
|
||||
details, see [Getting Started with the LLVM System](https://llvm.org/docs/GettingStarted.html).
|
||||
|
||||
If you haven't checked out LLVM, the easiest way to build LLD is to
|
||||
check out the entire LLVM projects/sub-projects from a git mirror and
|
||||
build that tree. You need `cmake` and of course a C++ compiler.
|
||||
|
||||
.. code-block:: console
|
||||
```console
|
||||
$ git clone https://github.com/llvm/llvm-project llvm-project
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
$ cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS=lld -DCMAKE_INSTALL_PREFIX=/usr/local ../llvm-project/llvm
|
||||
$ make install
|
||||
```
|
||||
|
||||
$ git clone https://github.com/llvm/llvm-project llvm-project
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
$ cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS=lld -DCMAKE_INSTALL_PREFIX=/usr/local ../llvm-project/llvm
|
||||
$ make install
|
||||
## Using LLD
|
||||
|
||||
Using LLD
|
||||
---------
|
||||
|
||||
LLD is installed as ``ld.lld``. On Unix, linkers are invoked by
|
||||
LLD is installed as `ld.lld`. On Unix, linkers are invoked by
|
||||
compiler drivers, so you are not expected to use that command
|
||||
directly. There are a few ways to tell compiler drivers to use ld.lld
|
||||
instead of the default linker.
|
||||
|
||||
The easiest way to do that is to overwrite the default linker. After
|
||||
installing LLD to somewhere on your disk, you can create a symbolic
|
||||
link by doing ``ln -s /path/to/ld.lld /usr/bin/ld`` so that
|
||||
``/usr/bin/ld`` is resolved to LLD.
|
||||
link by doing `ln -s /path/to/ld.lld /usr/bin/ld` so that
|
||||
`/usr/bin/ld` is resolved to LLD.
|
||||
|
||||
If you don't want to change the system setting, you can use clang's
|
||||
``-fuse-ld`` option. In this way, you want to set ``-fuse-ld=lld`` to
|
||||
`-fuse-ld` option. In this way, you want to set `-fuse-ld=lld` to
|
||||
LDFLAGS when building your programs.
|
||||
|
||||
LLD leaves its name and version number to a ``.comment`` section in an
|
||||
LLD leaves its name and version number to a `.comment` section in an
|
||||
output. If you are in doubt whether you are successfully using LLD or
|
||||
not, run ``readelf --string-dump .comment <output-file>`` and examine the
|
||||
not, run `readelf --string-dump .comment <output-file>` and examine the
|
||||
output. If the string "Linker: LLD" is included in the output, you are
|
||||
using LLD.
|
||||
|
||||
Internals
|
||||
---------
|
||||
## Internals
|
||||
|
||||
For the internals of the linker, please read :doc:`NewLLD`. It is a bit
|
||||
For the internals of the linker, please read {doc}`NewLLD`. It is a bit
|
||||
outdated but the fundamental concepts remain valid. We'll update the
|
||||
document soon.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
```{toctree}
|
||||
:maxdepth: 1
|
||||
|
||||
NewLLD
|
||||
WebAssembly
|
||||
windows_support
|
||||
missingkeyfunction
|
||||
error_handling_script
|
||||
ReleaseNotes
|
||||
ELF/large_sections
|
||||
ELF/linker_script
|
||||
ELF/start-stop-gc
|
||||
ELF/warn_backrefs
|
||||
MachO/index
|
||||
DTLTO
|
||||
NewLLD
|
||||
WebAssembly
|
||||
windows_support
|
||||
missingkeyfunction
|
||||
error_handling_script
|
||||
ReleaseNotes
|
||||
ELF/large_sections
|
||||
ELF/linker_script
|
||||
ELF/start-stop-gc
|
||||
ELF/warn_backrefs
|
||||
MachO/index
|
||||
DTLTO
|
||||
```
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
Missing Key Function
|
||||
====================
|
||||
# Missing Key Function
|
||||
|
||||
If your build failed with a linker error something like this::
|
||||
If your build failed with a linker error something like this:
|
||||
|
||||
foo.cc:28: error: undefined reference to 'vtable for C'
|
||||
the vtable symbol may be undefined because the class is missing its key function
|
||||
(see https://lld.llvm.org/missingkeyfunction)
|
||||
```
|
||||
foo.cc:28: error: undefined reference to 'vtable for C'
|
||||
the vtable symbol may be undefined because the class is missing its key function
|
||||
(see https://lld.llvm.org/missingkeyfunction)
|
||||
```
|
||||
|
||||
it's likely that your class C has a key function (defined by the ABI as the first
|
||||
non-pure, non-inline, virtual function), but you haven't actually defined it.
|
||||
|
|
@ -25,21 +26,22 @@ ensure there is at least one eligible function that can serve as the key functio
|
|||
|
||||
Here are the most common mistakes that lead to this error:
|
||||
|
||||
Failing to define a virtual destructor
|
||||
--------------------------------------
|
||||
## Failing to define a virtual destructor
|
||||
|
||||
Say you have a base class declared in a header file::
|
||||
Say you have a base class declared in a header file:
|
||||
|
||||
class B {
|
||||
public:
|
||||
B();
|
||||
virtual ~B();
|
||||
...
|
||||
};
|
||||
```
|
||||
class B {
|
||||
public:
|
||||
B();
|
||||
virtual ~B();
|
||||
...
|
||||
};
|
||||
```
|
||||
|
||||
Here, ``~B`` is the first non-pure, non-inline, virtual function, so it is the key
|
||||
function. If you forget to define ``B::~B`` in your source file, the compiler will
|
||||
not emit the vtable for ``B``, and you'll get an undefined reference to "vtable
|
||||
Here, `~B` is the first non-pure, non-inline, virtual function, so it is the key
|
||||
function. If you forget to define `B::~B` in your source file, the compiler will
|
||||
not emit the vtable for `B`, and you'll get an undefined reference to "vtable
|
||||
for B".
|
||||
|
||||
This is just an example of the more general mistake of forgetting to define the
|
||||
|
|
@ -50,31 +52,31 @@ you won't see any undefined reference errors that point directly to the problem.
|
|||
|
||||
The solution in this case is to implement the missing function.
|
||||
|
||||
Forgetting to declare a virtual function in an abstract class as pure
|
||||
---------------------------------------------------------------------
|
||||
## Forgetting to declare a virtual function in an abstract class as pure
|
||||
|
||||
Say you have an abstract base class declared in a header file::
|
||||
Say you have an abstract base class declared in a header file:
|
||||
|
||||
class A {
|
||||
public:
|
||||
A();
|
||||
virtual ~A() {}
|
||||
virtual int foo() = 0;
|
||||
...
|
||||
virtual int bar();
|
||||
...
|
||||
};
|
||||
```
|
||||
class A {
|
||||
public:
|
||||
A();
|
||||
virtual ~A() {}
|
||||
virtual int foo() = 0;
|
||||
...
|
||||
virtual int bar();
|
||||
...
|
||||
};
|
||||
```
|
||||
|
||||
This base class is intended to be abstract, but you forgot to mark one of the
|
||||
functions pure. Here, ``A::bar``, being non-pure, is nominated as the key function,
|
||||
and as a result, the vtable for ``A`` is not emitted, because the compiler is
|
||||
waiting for a translation unit that defines ``A::bar``.
|
||||
functions pure. Here, `A::bar`, being non-pure, is nominated as the key function,
|
||||
and as a result, the vtable for `A` is not emitted, because the compiler is
|
||||
waiting for a translation unit that defines `A::bar`.
|
||||
|
||||
The solution in this case is to add the missing ``= 0`` to the declaration of
|
||||
``A::bar``.
|
||||
The solution in this case is to add the missing `= 0` to the declaration of
|
||||
`A::bar`.
|
||||
|
||||
Key function is defined, but the linker doesn't see it
|
||||
------------------------------------------------------
|
||||
## Key function is defined, but the linker doesn't see it
|
||||
|
||||
It's also possible that you have defined the key function somewhere, but the
|
||||
object file containing the definition of that function isn't being linked into
|
||||
|
|
@ -83,3 +85,4 @@ your application.
|
|||
The solution in this case is to check your dependencies to make sure that
|
||||
the object file or the library file containing the key function is given to
|
||||
the linker.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,21 @@
|
|||
.. raw:: html
|
||||
|
||||
<style type="text/css">
|
||||
.none { background-color: #FFCCCC }
|
||||
.partial { background-color: #FFFF99 }
|
||||
.good { background-color: #CCFF99 }
|
||||
</style>
|
||||
```{raw} html
|
||||
<style type="text/css">
|
||||
.none { background-color: #FFCCCC }
|
||||
.partial { background-color: #FFFF99 }
|
||||
.good { background-color: #CCFF99 }
|
||||
</style>
|
||||
```
|
||||
|
||||
```{eval-rst}
|
||||
.. role:: none
|
||||
.. role:: partial
|
||||
.. role:: good
|
||||
```
|
||||
|
||||
===============
|
||||
Windows support
|
||||
===============
|
||||
# Windows support
|
||||
|
||||
LLD supports Windows operating system. When invoked as ``lld-link.exe`` or with
|
||||
``-flavor link``, the driver for Windows operating system is used to parse
|
||||
LLD supports Windows operating system. When invoked as `lld-link.exe` or with
|
||||
`-flavor link`, the driver for Windows operating system is used to parse
|
||||
command line options, and it drives further linking processes. LLD accepts
|
||||
almost all command line options that the linker shipped with Microsoft Visual
|
||||
C++ (link.exe) supports.
|
||||
|
|
@ -23,64 +23,61 @@ C++ (link.exe) supports.
|
|||
The current status is that LLD is used to link production builds of large
|
||||
real-world binaries such as Firefox and Chromium.
|
||||
|
||||
Development status
|
||||
==================
|
||||
## Development status
|
||||
|
||||
Driver
|
||||
:good:`Mostly done`. Some exotic command line options that are not usually
|
||||
used for application development, such as ``/DRIVER``, are not supported.
|
||||
: {good}`Mostly done`. Some exotic command line options that are not usually
|
||||
used for application development, such as `/DRIVER`, are not supported.
|
||||
|
||||
Linking against DLL
|
||||
:good:`Done`. LLD can read import libraries needed to link against DLL. Both
|
||||
: {good}`Done`. LLD can read import libraries needed to link against DLL. Both
|
||||
export-by-name and export-by-ordinal are supported.
|
||||
|
||||
Linking against static library
|
||||
:good:`Done`. The format of static library (.lib) on Windows is actually the
|
||||
: {good}`Done`. The format of static library (.lib) on Windows is actually the
|
||||
same as on Unix (.a). LLD can read it.
|
||||
|
||||
Creating DLL
|
||||
:good:`Done`. LLD creates a DLL if ``/DLL`` option is given. Exported
|
||||
functions can be specified either via command line (``/EXPORT``) or via
|
||||
: {good}`Done`. LLD creates a DLL if `/DLL` option is given. Exported
|
||||
functions can be specified either via command line (`/EXPORT`) or via
|
||||
module-definition file (.def). Both export-by-name and export-by-ordinal are
|
||||
supported.
|
||||
|
||||
Windows resource files support
|
||||
:good:`Done`. If an ``.res`` file is given, LLD converts the file to a COFF
|
||||
: {good}`Done`. If an `.res` file is given, LLD converts the file to a COFF
|
||||
file using LLVM's Object library.
|
||||
|
||||
Safe Structured Exception Handler (SEH)
|
||||
:good:`Done` for both x86 and x64.
|
||||
: {good}`Done` for both x86 and x64.
|
||||
|
||||
Module-definition file
|
||||
:partial:`Partially done`. LLD currently recognizes these directives:
|
||||
``EXPORTS``, ``HEAPSIZE``, ``STACKSIZE``, ``NAME``, and ``VERSION``.
|
||||
: {partial}`Partially done`. LLD currently recognizes these directives:
|
||||
`EXPORTS`, `HEAPSIZE`, `STACKSIZE`, `NAME`, and `VERSION`.
|
||||
|
||||
Debug info
|
||||
:good:`Done`. LLD can emit PDBs that are at parity with those generated by
|
||||
link.exe. However, LLD does not support /DEBUG:FASTLINK.
|
||||
: {good}`Done`. LLD can emit PDBs that are at parity with those generated by
|
||||
link.exe. However, LLD does not support /DEBUG:FASTLINK.
|
||||
|
||||
## Downloading LLD
|
||||
|
||||
Downloading LLD
|
||||
===============
|
||||
The Windows version of LLD is included in the [pre-built binaries of LLVM's
|
||||
releases](https://releases.llvm.org/download.html) and in the [LLVM Snapshot
|
||||
Builds](https://llvm.org/builds/).
|
||||
|
||||
The Windows version of LLD is included in the `pre-built binaries of LLVM's
|
||||
releases <https://releases.llvm.org/download.html>`_ and in the `LLVM Snapshot
|
||||
Builds <https://llvm.org/builds/>`_.
|
||||
## Building LLD
|
||||
|
||||
Building LLD
|
||||
============
|
||||
|
||||
Using Visual Studio IDE/MSBuild
|
||||
-------------------------------
|
||||
### Using Visual Studio IDE/MSBuild
|
||||
|
||||
1. Check out LLVM and LLD from the LLVM SVN repository (or Git mirror),
|
||||
#. run ``cmake -G "Visual Studio 12" <llvm-source-dir>`` from VS command prompt,
|
||||
#. open LLVM.sln with Visual Studio, and
|
||||
#. build ``lld`` target in ``lld executables`` folder
|
||||
2. run `cmake -G "Visual Studio 12" <llvm-source-dir>` from VS command prompt,
|
||||
3. open LLVM.sln with Visual Studio, and
|
||||
4. build `lld` target in `lld executables` folder
|
||||
|
||||
Alternatively, you can use msbuild if you don't like to work in an IDE::
|
||||
Alternatively, you can use msbuild if you don't like to work in an IDE:
|
||||
|
||||
msbuild LLVM.sln /m /target:"lld executables\lld"
|
||||
```
|
||||
msbuild LLVM.sln /m /target:"lld executables\lld"
|
||||
```
|
||||
|
||||
MSBuild.exe had been shipped as a component of the .NET framework, but since
|
||||
2013 it's part of Visual Studio. You can find it at "C:\\Program Files
|
||||
|
|
@ -89,20 +86,17 @@ MSBuild.exe had been shipped as a component of the .NET framework, but since
|
|||
You can build LLD as a 64-bit application. To do that, open VS2013 x64 command
|
||||
prompt and run cmake for "Visual Studio 12 Win64" target.
|
||||
|
||||
Using Ninja
|
||||
-----------
|
||||
### Using Ninja
|
||||
|
||||
1. Check out LLVM and LLD from the LLVM SVN repository (or Git mirror),
|
||||
#. run ``cmake -G ninja <llvm-source-dir>`` from VS command prompt,
|
||||
#. run ``ninja lld``
|
||||
2. run `cmake -G ninja <llvm-source-dir>` from VS command prompt,
|
||||
3. run `ninja lld`
|
||||
|
||||
Extensions
|
||||
==========
|
||||
## Extensions
|
||||
|
||||
LLD flags
|
||||
---------
|
||||
### LLD flags
|
||||
|
||||
* ``/build-id``: Always generate GUID hash. When PDB is generated, LLD uses PDB
|
||||
- `/build-id`: Always generate GUID hash. When PDB is generated, LLD uses PDB
|
||||
content hash for GUID. Otherwise, LLD uses output binary content hash for GUID.
|
||||
LLD also provides ``__buildid`` symbol pointing to the 16 bytes GUID hash if
|
||||
LLD also provides `__buildid` symbol pointing to the 16 bytes GUID hash if
|
||||
there is a reference to it.
|
||||
|
|
|
|||
Loading…
Reference in a new issue