commit d68f00cb6e8b4d2d0090f04ed4edcffdaf6c2ef5
parent 78ec17447c5bd31bf94df1dcce31dd4975eda7f8
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Wed, 10 Jun 2026 18:08:19 -0700
docs(todo): track the two open x86_64-macos linker bugs
Add the chained-fixups rebase (off-by-one-page SIGBUS in dyld) and the
TLV/thread-local gap (arm64-only TLV passes → SIGSEGV) to the known-bugs
backlog, with file:line, repro toy cases, and the `make test-cross
TARGET=macos-x64 DEPTH=full` lane that captures them RED.
Diffstat:
1 file changed, 32 insertions(+), 0 deletions(-)
diff --git a/doc/plan/TODO.md b/doc/plan/TODO.md
@@ -85,6 +85,38 @@ Add new deferred fixes below as they are discovered.
the existing scratch between mem-staging and operand-staging — a register-policy
decision, hence "reviewed change."
+- **x86_64-macos chained-fixups rebase is off by one page (SIGBUS at dyld load).**
+ A global pointer initialized to another global's address (`var gp: *i64 = &g`,
+ or C `long g; long *gp = &g;`) crashes at process start *inside dyld* —
+ `applyFixupsGeneric` does `movq` to e.g. `0x100008000`, exactly **one 16 KB
+ page past** `__data` (`0x100004000`), faulting on unmapped memory. The rebased
+ pointer *value* kit writes is correct (gp holds g's address, same bytes as the
+ working arm64-macos build); the bug is the **`dyld_chained_starts_in_segment`
+ page table** kit emits for x86_64 — a wrong `page_start` / `segment_offset`
+ (or page indexing) sends dyld's chain walk into the next page. arm64-macos is
+ fine. Reproduces both freestanding and hosted (`-lc`). Location:
+ `src/obj/macho/link.c` ~1544–1700 (the chained-fixups emit; `MZ_PAGE=0x4000`).
+ Repro / guard: toy case `15_cg_api_types_bytes_globals` (SIGBUS, want exit 92)
+ under `make test-cross TARGET=macos-x64 DEPTH=full` (test/toy/vm.sh macos).
+
+- **x86_64-macos thread-locals are not linked (TLV pass is arm64-only).** An
+ extern/`_Thread_local` access on x86_64-macos SIGSEGVs at runtime: the Mach-O
+ linker's TLV collection + apply passes (`src/obj/macho/link.c` ~251–264,
+ 465–468, plus the `__thread_ptrs` slot pass ~1638) key off the **arm64** TLV
+ relocs (`ARM64_RELOC_TLVP_LOAD_PAGE21/PAGEOFF12`); x86_64's single
+ `X86_64_RELOC_TLV` is never collected, so no `__thread_ptrs` slot / descriptor
+ is set up and the thread-local load dereferences garbage. (Freestanding x86_64
+ thread-locals additionally can't even link — `undefined reference to
+ '_tlv_bootstrap'`, a libSystem symbol — which is why these cases carry a
+ `.link.hosted` sidecar and must link `-lc`.) arm64-macos is fine. Repro / guard:
+ toy cases `141_threadlocal_mutate` (want 43) + `142_threadlocal_multi`
+ (want 134), both SIGSEGV, in the `macos-x64 DEPTH=full` lane above.
+
+ (Context: x86_64-macos compile+link+execute via Rosetta otherwise works as of
+ `feat(macho): x86_64-macos compile+link+execute via Rosetta`; the full toy
+ corpus is 324/330 green and these two gaps are the only failures. The lane is
+ committed RED to track them.)
+
## Deferred dedups & abstraction cleanups ("use the shared seam")
- **A.2 — optimizer-path inline-asm dedup.** The three `aa_/x64_/rv_asm_block_native`