[all-commits] [llvm/llvm-project] bacd87: [lld][MachO] Preserve __eh_frame ordering during B...
Karim Alweheshy via All-commits
all-commits at lists.llvm.org
Tue May 26 10:20:36 PDT 2026
Branch: refs/heads/main
Home: https://github.com/llvm/llvm-project
Commit: bacd876134494c69d02b4509e125c47b5e86d3d2
https://github.com/llvm/llvm-project/commit/bacd876134494c69d02b4509e125c47b5e86d3d2
Author: Karim Alweheshy <9082720+karim-alweheshy at users.noreply.github.com>
Date: 2026-05-26 (Tue, 26 May 2026)
Changed paths:
M lld/MachO/BPSectionOrderer.cpp
A lld/test/MachO/eh-frame-ordering.s
Log Message:
-----------
[lld][MachO] Preserve __eh_frame ordering during BP section sorting (#191412)
The Balanced Partitioning section orderer collects all live
`ConcatInputSection`s as candidates for content-similarity reordering.
This includes `__eh_frame` CIE and FDE records, which have internal
ordering constraints: each FDE contains a backward-relative 32-bit
offset to its parent CIE, requiring CIEs to precede their FDEs.
When the BP orderer assigns priorities to `__eh_frame` subsections and
`Writer.cpp` sorts by those priorities, FDEs can end up before their
parent CIEs. The resulting CIE-pointer offsets resolve correctly with
32-bit wrapping arithmetic but underflow with 64-bit pointer arithmetic,
causing DWARF consumers (crash reporters, debuggers) to silently lose
unwind data.
## Fix
Have the BP orderer skip the Mach-O `__TEXT,__eh_frame` section
explicitly before collecting candidate subsections, preserving the
existing CIE/FDE order without adding state to `Section`.
This is the only MachO section with this constraint:
- `__unwind_info` is a `SyntheticSection` (not a `ConcatOutputSection`),
so it never enters the BP pipeline
- `__gcc_except_tab` LSDA entries are referenced by absolute offset, so
reordering is safe
- `-order_file` is unaffected because it assigns priorities through
symbol definitions (which live in `__text`, not `__eh_frame`). Only the
BP orderer enumerates sections directly.
## Production impact
Verified on a large iOS application (~218 MB binary, ~34,000 FDEs)
linked with `lld` + `--bp-compression-sort=both`.
### Static analysis of `__eh_frame`
Simulating 64-bit CIE pointer resolution on the output binary across
multiple builds:
| Build | `__eh_frame` layout | FDEs resolved (64-bit) | FDEs failed |
|---|---|---|---|
| lld + BP sort | FDEs first | 15 / 34,257 | **34,242 (99.96%)** |
| lld + fix | CIEs first | 30,558 / 30,558 | **0** |
### Runtime verification
Proxied crash report uploads from a device running both the affected and
fixed binaries:
| | Affected build | Fixed build |
|---|---|---|
| Threads captured | 3 | 24 |
| Total frames | 28 | 135 |
| Background threads | 0-2 | 23 |
The affected build lost ~85% of thread data. The crash reporter could
only unwind the crashed thread (via compact unwind). All background
thread unwind data was silently dropped.
## Reproducer
Minimal test case (ARM64). Requires `--bp-compression-sort=both` to
trigger:
```bash
llvm-mc -filetype=obj -emit-compact-unwind-non-canonical=true \
-triple=arm64-apple-macos11.0 test.s -o test.o
ld64.lld -arch arm64 -platform_version macos 11.0 11.0 \
-syslibroot $(xcrun --show-sdk-path) -lSystem -lc++ \
test.o -o test --bp-compression-sort=both
llvm-objdump --dwarf=frames test
# Without fix: "error: parsing FDE data at 0x0 failed due to missing CIE"
# With fix: CIE records correctly precede their FDEs
```
Standalone reproducer with 64-bit CIE simulation script:
https://gist.github.com/karim-alweheshy/ae28196c4fbb295f81cc793cfbe0c1b7
## Test
The lit test creates multiple functions with `cfi_escape` (forcing DWARF
unwind mode) and different personality functions (producing separate
CIEs), then links with `--bp-compression-sort=both`. Verified on both
x86_64 and arm64.
Made with [Cursor](https://cursor.com)
---------
Co-authored-by: Karim Alweheshy <karim.alweheshy at reddit.com>
Co-authored-by: Ellis Hoag <ellis.sparky.hoag at gmail.com>
To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications
More information about the All-commits
mailing list