lld 23.1.0 Release Notes — lld 23.1.0 documentation

# lld 23.1.0 Release Notes

## Introduction

This document contains the release notes for the lld linker, release 23.1.0. 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.

## Non-comprehensive list of changes in this release

### ELF Improvements

- Input file loading is now parallelized, meaningfully reducing link time for large links. (#191690)

- `--gc-sections` mark phase is now parallelized. (#189321)

- Relocation scanning was rewritten as target-specific scanners for all targets with shared library support, devirtualizing the hot relocation-classification path.

- Added `--bp-compression-sort-section=<glob>[=<layout_priority>[=<match_priority>]]`, replacing the old coarse `--bp-compression-sort` modes with a way to split input sections into multiple compression groups, run balanced partitioning independently per group, and leave out sections that are poor candidates for BP. `layout_priority` controls group placement order (lower value = placed first, default 0). `match_priority` resolves conflicts when multiple globs match the same section (lower value = higher priority; explicit priority beats positional last-match-wins; default: positional). In ELF, the glob matches input section names (e.g. `.text.unlikely.code1`).

- Added `-z memtag-{mode,heap,stack}` as generic replacements for the Android-specific `--android-memtag-*` flags; `--android-memtag-note` keeps the Android-specific memtag note opt-in. (#188205)

- Unused space in executable output sections is now filled with trap, primarily for `-z separate-code` mode. (#176845)

- `.eh_frame_hdr` now supports the `DW_EH_PE_sdata8` encoding, auto-upgrading from `sdata4` when a table entry or the frame pointer exceeds the 32-bit range, instead of erroring out for large executables. (#179089)

- `vna_flags` is now set to `VER_FLG_WEAK` when all undefined references to a version are weak, allowing glibc’s dynamic loader to warn instead of error when the version is missing at runtime. (#176673)

- `.ltext.*` input sections are now merged into a single `.ltext` output section, matching the existing `.ldata.*`/`.lrodata.*`/`.lbss.*` handling for the large code model with `-ffunction-sections`. (#190305)

- `.tbss` output sections may now use an explicit address expression; previously it was silently overridden to follow the preceding `.tbss`. (#196447)

- `--discard-locals`/`--discard-all` combined with `-r`/`--emit-relocs` no longer discard local symbols that are referenced only from retained non-`SHF_ALLOC` sections (e.g. `.L` symbols referenced by `.debug_info`), fixing DWARF corruption in the output. (#209035) (#209042)

- `--retain-symbols-file` now filters `.symtab` instead of `.dynsym`, matching GNU ld. (#209063)

- `INCLUDE` in linker scripts now fully parses its own content instead of sharing a lexer buffer stack with the includer, fixing spurious acceptance of malformed scripts. (#193427)

- The `OVERLAY` linker script command now accepts any output-section-command (e.g. symbol assignments), not just input section descriptions. (#203524)

- Thunks are no longer reused across an `OVERLAY` boundary unless the target output section is guaranteed to be resident at the same time. (#200415)

- When a `SECTIONS` command interleaves relro and non-relro sections, lld now emits one `PT_GNU_RELRO` segment per contiguous run of relro sections instead of reporting a `not contiguous with other relro sections` error.

- `SHT_NOBITS` sections are now excluded from LMA overlap checks, matching GNU ld and allowing e.g. a startup section to share an LMA with `.bss` in embedded linker scripts. (#196423)

- LTO: the middle-end no longer emits new references to, or internalizes, symbols defined in bitcode after the extracted-bitcode set has been fixed, preventing undefined symbol references from transforms that run after linking has determined which bitcode files to extract. (#164916)

- DTLTO: significantly improved the performance of adding backend output files to the link, especially on Windows. (#186366)

- For AArch64, fixed `.relr.auth.dyn` -> `.rela.dyn` movement to properly adjust `__rela_iplt_start`/`__rela_iplt_end` and size the `.dynamic` section for both tags. (#195649)

- For AArch64, handle Memtag globals for `R_AARCH64_AUTH_ABS64`. (#173291)

- For AArch64, fixed TLS GD against non-preemptible dynamic symbols (e.g. `protected` or `-Bsymbolic`) in DSOs, which previously produced an inconsistent GOT entry and spurious preemption. (#207881)

- For AArch64, `adrp``+``ldr` GOT relaxation is now decided per-symbol, all-or-nothing, avoiding invalid relaxation when a branch target sits between the `adrp` and `ldr` of a pair. (#208396)

- For AArch64, a redundant local-exec TLS `add` with a zero high-12-bits immediate is now relaxed to a `nop`. (#204286)

- x86-64 CFI jump table relaxation reduces the runtime overhead of indirect calls under Control Flow Integrity by opportunistically moving eligible function bodies into the jump table itself. (#147424)

### Breaking changes

- The symbol partition feature has been removed. lld no longer recognizes `SHT_LLVM_SYMPART` sections, which are now treated as ordinary sections. The feature saw no adoption beyond a Chromium experiment that has since been retired.

- An OutputSection that has an address expression, and is also assigned to a MEMORY region, will now use the address expression in preference to the next available location in the MEMORY region. This brings LLD in line with GNU ld, but is a change in behavior from previous LLD releases.

- The default extension for time trace files is now `.time-trace.json`.

### COFF Improvements

- Added support for `.obj.arm64ec` sections to allow embedding ARM64EC object files inside ARM64 object files.

### MinGW Improvements

- Added `--push-state` and `--pop-state`, offering the same semantics as when used with the ELF linker: The state of `--Bstatic`/`--Bdynamic` and `--whole-archive` are pushed onto a stack and popped from it.

- Added the `--native-def` option to specify the native module-definition file for ARM64X targets. If a module-definition file is passed without this option, it is used for both native and EC views. `--native-def=` can be used to prevent the native view from using the default file.

### MachO Improvements

- `--bp-compression-sort-section` now accepts optional layout and match priorities (same syntax as ELF). In Mach-O, the glob matches the concatenated segment+section name (e.g. `__TEXT__text`).

- Restructure thunk generation algorithm to be more efficiently create thunks (#193367)

- Alphabetically sort LC_LINKER_OPTIONS before processing to match Apple linker behavior (#201604 https://github.com/llvm/llvm-project/pull/201604)

### WebAssembly Improvements

#### Fixes