Skip to content

[sanitizer_common] [Darwin] Adopt _dyld_get_dyld_header#182943

Merged
ndrewh merged 1 commit intollvm:mainfrom
ndrewh:GetDyldImageHeaderViaSharedCache
Feb 24, 2026
Merged

[sanitizer_common] [Darwin] Adopt _dyld_get_dyld_header#182943
ndrewh merged 1 commit intollvm:mainfrom
ndrewh:GetDyldImageHeaderViaSharedCache

Conversation

@ndrewh
Copy link
Copy Markdown
Contributor

@ndrewh ndrewh commented Feb 23, 2026

There is an issue on recent macOS versions with GetDyldImageHeaderViaSharedCache, which is fixed by adopting _dyld_get_dyld_header. We weakly declare this to ensure runtimes compile with older SDK (currently on CI bots).

rdar://167854578

@llvmbot
Copy link
Copy Markdown
Member

llvmbot commented Feb 23, 2026

@llvm/pr-subscribers-compiler-rt-sanitizer

Author: Andrew Haberlandt (ndrewh)

Changes

There is an issue on recent macOS versions with GetDyldImageHeaderViaSharedCache, which is fixed by adopting _dyld_get_dyld_header. We weakly declare this to ensure runtimes work on older OS, and also newer OS compiled with older SDK (i.e. the current bots).

rdar://167854578


Full diff: https://github.com/llvm/llvm-project/pull/182943.diff

3 Files Affected:

  • (modified) compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cpp (+6-2)
  • (modified) compiler-rt/lib/sanitizer_common/weak_symbols.txt (+1)
  • (modified) compiler-rt/lib/tsan/go/buildgo.sh (+1-1)
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cpp
index 979729f15aa16..0e80f2e3916b2 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cpp
@@ -176,7 +176,7 @@ void MemoryMappingLayout::Reset() {
 // The dyld load address should be unchanged throughout process execution,
 // and it is expensive to compute once many libraries have been loaded,
 // so cache it here and do not reset.
-static mach_header *dyld_hdr = 0;
+static const mach_header *dyld_hdr = 0;
 static const char kDyldPath[] = "/usr/lib/dyld";
 static const int kDyldImageIdx = -1;
 
@@ -244,14 +244,18 @@ extern intptr_t _dyld_get_image_slide(const struct mach_header* mh);
 extern int dyld_shared_cache_iterate_text(
     const uuid_t cacheUuid,
     void (^callback)(const dyld_shared_cache_dylib_text_info *info));
+SANITIZER_WEAK_IMPORT const struct mach_header *_dyld_get_dyld_header(void);
 }  // extern "C"
 
-static mach_header *GetDyldImageHeaderViaSharedCache() {
+static const mach_header *GetDyldImageHeaderViaSharedCache() {
   uuid_t uuid;
   bool hasCache = _dyld_get_shared_cache_uuid(uuid);
   if (!hasCache)
     return nullptr;
 
+  if (&_dyld_get_dyld_header != nullptr)
+    return _dyld_get_dyld_header();
+
   size_t cacheLength;
   __block uptr cacheStart = (uptr)_dyld_get_shared_cache_range(&cacheLength);
   CHECK(cacheStart && cacheLength);
diff --git a/compiler-rt/lib/sanitizer_common/weak_symbols.txt b/compiler-rt/lib/sanitizer_common/weak_symbols.txt
index 77e7b5d9f702e..600ab8a7c649c 100644
--- a/compiler-rt/lib/sanitizer_common/weak_symbols.txt
+++ b/compiler-rt/lib/sanitizer_common/weak_symbols.txt
@@ -10,3 +10,4 @@ ___sanitizer_symbolize_demangle
 ___sanitizer_symbolize_flush
 ___sanitizer_symbolize_set_demangle
 ___sanitizer_symbolize_set_inline_frames
+__dyld_get_dyld_header
diff --git a/compiler-rt/lib/tsan/go/buildgo.sh b/compiler-rt/lib/tsan/go/buildgo.sh
index d9e56402ad48f..1340071819fcb 100755
--- a/compiler-rt/lib/tsan/go/buildgo.sh
+++ b/compiler-rt/lib/tsan/go/buildgo.sh
@@ -165,7 +165,7 @@ elif [ "$GOOS" = "netbsd" ]; then
 	"
 elif [ "$GOOS" = "darwin" ]; then
 	OSCFLAGS="-fPIC -Wno-unused-const-variable -Wno-unknown-warning-option -mmacosx-version-min=10.7"
-	OSLDFLAGS="-lpthread -fPIC -fpie -mmacosx-version-min=10.7"
+	OSLDFLAGS="-lpthread -fPIC -fpie -mmacosx-version-min=10.7 -Wl,-U,__dyld_get_dyld_header"
 	SRCS="
 		$SRCS
 		../rtl/tsan_platform_mac.cpp

@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 23, 2026

✅ With the latest revision this PR passed the C/C++ code formatter.

@ndrewh ndrewh force-pushed the GetDyldImageHeaderViaSharedCache branch from ea41f5f to bdf57bf Compare February 23, 2026 21:44
@ndrewh
Copy link
Copy Markdown
Contributor Author

ndrewh commented Feb 23, 2026

Fixed clang-format

@ndrewh ndrewh merged commit 2e7d07a into llvm:main Feb 24, 2026
10 checks passed
tudinhh pushed a commit to tudinhh/llvm-project that referenced this pull request Feb 26, 2026
HendrikHuebner pushed a commit to HendrikHuebner/llvm-project that referenced this pull request Mar 10, 2026
gopherbot pushed a commit to golang/go that referenced this pull request Mar 19, 2026
With llvm/llvm-project#182943, the race
detector syso has a weak import of __dyld_get_dyld_header, which
is only defined on newer macOS (26.4+). For external linking with
a pre-Xcode 26.4 C toolchain, we need to tell the C linker to
permit that symbol not being defined. Pass a flag to do so.

Change-Id: I95a3cd2c7fd3ad50bc47985b3ecca0d4e8352162
Reviewed-on: https://go-review.googlesource.com/c/go/+/755261
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Lasse Folger <lassefolger@google.com>
@ndrewh
Copy link
Copy Markdown
Contributor Author

ndrewh commented Mar 27, 2026

/cherry-pick 2e7d07a

@ndrewh
Copy link
Copy Markdown
Contributor Author

ndrewh commented Mar 27, 2026

I think we should cherry-pick this to make sure that clang 22 supports ASAN on macOS 26.4.

@llvmbot
Copy link
Copy Markdown
Member

llvmbot commented Mar 27, 2026

/cherry-pick 2e7d07a

Error: Command failed due to missing milestone.

@ndrewh ndrewh added this to the LLVM 22.x Release milestone Mar 27, 2026
@github-project-automation github-project-automation bot moved this to Needs Triage in LLVM Release Status Mar 27, 2026
@github-project-automation github-project-automation bot moved this from Needs Triage to Done in LLVM Release Status Mar 27, 2026
@ndrewh
Copy link
Copy Markdown
Contributor Author

ndrewh commented Mar 27, 2026

/cherry-pick 2e7d07a

@llvmbot
Copy link
Copy Markdown
Member

llvmbot commented Mar 27, 2026

/pull-request #188913

dylan-conway added a commit to oven-sh/bun that referenced this pull request Mar 29, 2026
…t mode

DirectBuild: deps simple enough to list files compile as first-class
ninja edges instead of a cmake sub-process. tinycc converted — drops
the overlay CMakeLists.txt and the recurring ASAN workarounds on the
c2str host tool, which now gets -fno-sanitize=all unconditionally.

ASAN dyld shim: macOS 26.4's Dyld.framework reimplemented
dyld_shared_cache_iterate_text in Swift with a _Block_copy that
deadlocks ASAN init (llvm/llvm-project#182943). Shim interposes a
non-allocating version using _dyld_get_dyld_header. Linked via
LC_LOAD_DYLIB + @rpath so it auto-loads with bun-debug — no env var.
Darwin+ASAN only.

workarounds.ts: self-obsoleting registry. Every temporary fix registers
an expectedToBeFixed predicate; configure fails with cleanup
instructions once the upstream fix ships.

build.ts: quiet build output when exec args present (original bd
behavior), `--` separator for flag disambiguation, `--target` accepts
space-separated value, colored target name in done message, signal
exit re-raised. Arg routing documented in file header.

tty.ts: centralized ANSI/TTY abstraction. nameColor() hashes names to
stable colors; stream.ts and the done message share it.

config.ts/tools.ts: clangVersion captured from the existing
toolchain-resolve --version spawn, exposed on Config. findTool returns
{path, version}.

Also:
- configure() no longer prints; build.ts decides based on quiet mode
- provides.sources deps get phonies pointing at compiled .o files
- scripts/bd, scripts/bd.ps1 removed (bd is a package.json script)
- scripts/build/CLAUDE.md: architecture doc with goals, ninja primer,
  common tasks, arg routing
dylan-conway added a commit to oven-sh/bun that referenced this pull request Mar 30, 2026
…t mode

DirectBuild: deps simple enough to list files compile as first-class
ninja edges instead of a cmake sub-process. tinycc converted — drops
the overlay CMakeLists.txt and the recurring ASAN workarounds on the
c2str host tool, which now gets -fno-sanitize=all unconditionally.

ASAN dyld shim: macOS 26.4's Dyld.framework reimplemented
dyld_shared_cache_iterate_text in Swift with a _Block_copy that
deadlocks ASAN init (llvm/llvm-project#182943). Shim interposes a
non-allocating version using _dyld_get_dyld_header. Linked via
LC_LOAD_DYLIB + @rpath so it auto-loads with bun-debug — no env var.
Darwin+ASAN only.

workarounds.ts: self-obsoleting registry. Every temporary fix registers
an expectedToBeFixed predicate; configure fails with cleanup
instructions once the upstream fix ships.

build.ts: quiet build output when exec args present (original bd
behavior), `--` separator for flag disambiguation, `--target` accepts
space-separated value, colored target name in done message, signal
exit re-raised. Arg routing documented in file header.

tty.ts: centralized ANSI/TTY abstraction. nameColor() hashes names to
stable colors; stream.ts and the done message share it.

config.ts/tools.ts: clangVersion captured from the existing
toolchain-resolve --version spawn, exposed on Config. findTool returns
{path, version}.

Also:
- configure() no longer prints; build.ts decides based on quiet mode
- provides.sources deps get phonies pointing at compiled .o files
- scripts/bd, scripts/bd.ps1 removed (bd is a package.json script)
- scripts/build/CLAUDE.md: architecture doc with goals, ninja primer,
  common tasks, arg routing
dylan-conway added a commit to oven-sh/bun that referenced this pull request Mar 30, 2026
…t mode

DirectBuild: deps simple enough to list files compile as first-class
ninja edges instead of a cmake sub-process. tinycc converted — drops
the overlay CMakeLists.txt and the recurring ASAN workarounds on the
c2str host tool, which now gets -fno-sanitize=all unconditionally.

ASAN dyld shim: macOS 26.4's Dyld.framework reimplemented
dyld_shared_cache_iterate_text in Swift with a _Block_copy that
deadlocks ASAN init (llvm/llvm-project#182943). Shim interposes a
non-allocating version using _dyld_get_dyld_header. Linked via
LC_LOAD_DYLIB + @rpath so it auto-loads with bun-debug — no env var.
Darwin+ASAN only.

workarounds.ts: self-obsoleting registry. Every temporary fix registers
an expectedToBeFixed predicate; configure fails with cleanup
instructions once the upstream fix ships.

build.ts: quiet build output when exec args present (original bd
behavior), `--` separator for flag disambiguation, `--target` accepts
space-separated value, colored target name in done message, signal
exit re-raised. Arg routing documented in file header.

tty.ts: centralized ANSI/TTY abstraction. nameColor() hashes names to
stable colors; stream.ts and the done message share it.

config.ts/tools.ts: clangVersion captured from the existing
toolchain-resolve --version spawn, exposed on Config. findTool returns
{path, version}.

Also:
- configure() no longer prints; build.ts decides based on quiet mode
- provides.sources deps get phonies pointing at compiled .o files
- scripts/bd, scripts/bd.ps1 removed (bd is a package.json script)
- scripts/build/CLAUDE.md: architecture doc with goals, ninja primer,
  common tasks, arg routing
dylan-conway added a commit to oven-sh/bun that referenced this pull request Mar 30, 2026
…t mode

DirectBuild: deps simple enough to list files compile as first-class
ninja edges instead of a cmake sub-process. tinycc converted — drops
the overlay CMakeLists.txt and the recurring ASAN workarounds on the
c2str host tool, which now gets -fno-sanitize=all unconditionally.

ASAN dyld shim: macOS 26.4's Dyld.framework reimplemented
dyld_shared_cache_iterate_text in Swift with a _Block_copy that
deadlocks ASAN init (llvm/llvm-project#182943). Shim interposes a
non-allocating version using _dyld_get_dyld_header. Linked via
LC_LOAD_DYLIB + @rpath so it auto-loads with bun-debug — no env var.
Darwin+ASAN only.

workarounds.ts: self-obsoleting registry. Every temporary fix registers
an expectedToBeFixed predicate; configure fails with cleanup
instructions once the upstream fix ships.

build.ts: quiet build output when exec args present (original bd
behavior), `--` separator for flag disambiguation, `--target` accepts
space-separated value, colored target name in done message, signal
exit re-raised. Arg routing documented in file header.

tty.ts: centralized ANSI/TTY abstraction. nameColor() hashes names to
stable colors; stream.ts and the done message share it.

config.ts/tools.ts: clangVersion captured from the existing
toolchain-resolve --version spawn, exposed on Config. findTool returns
{path, version}.

Also:
- configure() no longer prints; build.ts decides based on quiet mode
- provides.sources deps get phonies pointing at compiled .o files
- scripts/bd, scripts/bd.ps1 removed (bd is a package.json script)
- scripts/build/CLAUDE.md: architecture doc with goals, ninja primer,
  common tasks, arg routing
c-rhodes pushed a commit to llvmbot/llvm-project that referenced this pull request Mar 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Development

Successfully merging this pull request may close these issues.

3 participants