From 09ed02ce56ea5bf3e59f21ee0390cd85eb8bfaa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Sat, 12 Apr 2025 11:53:18 +0200 Subject: [PATCH] Fix segmentation fault on macOS 15.4 (#21176) Strips off additional bits that are not part of the actual TLV key to avoid applications using DRuntime crashing during initialization. Fixes #21126. --- changelog/druntime.macos-15-4-segfault.dd | 7 +++++++ druntime/src/rt/sections_darwin_64.d | 8 +++++++- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 changelog/druntime.macos-15-4-segfault.dd diff --git a/changelog/druntime.macos-15-4-segfault.dd b/changelog/druntime.macos-15-4-segfault.dd new file mode 100644 index 0000000000..cbdf993039 --- /dev/null +++ b/changelog/druntime.macos-15-4-segfault.dd @@ -0,0 +1,7 @@ +Fixed generated binaries crashing on macOS 15.4 + +macOS 15.4 has introduced an undocumented ABI change to the format of +thread local variable section, which causes almost all executable built with +previous D compiler versions to crash during initialization, if they use +DRuntime. This release introduces a mitigation for this issue that is +backwards compatible with previous versions of macOS. diff --git a/druntime/src/rt/sections_darwin_64.d b/druntime/src/rt/sections_darwin_64.d index 12395a28dc..d885621211 100644 --- a/druntime/src/rt/sections_darwin_64.d +++ b/druntime/src/rt/sections_darwin_64.d @@ -145,7 +145,13 @@ pthread_key_t firstTLVKey(const mach_header_64* header) pure nothrow @nogc if ((section.flags & SECTION_TYPE) != S_THREAD_LOCAL_VARIABLES) continue; - return section.firstTLVDescriptor(slide).key; + // NOTE: macOS 15.4 has started to fill the upper 32 bits of + // the `key` field with an additional number. Using the whole + // 64-bit field as a key results in a segmentation fault. Even + // though none of this appears to be documented anywhere, we + // assume that only the lower 32 bits are used for the actual + // key and this results in binaries that execute normally. + return section.firstTLVDescriptor(slide).key & 0xFFFF_FFFF; } }