Skip to content

Preserve the executable header in the default export policy - #3073

Open
karim-alweheshy wants to merge 2 commits into
bazelbuild:ks/add-empty-exported_symbols_list-by-defaultfrom
karim-alweheshy:codex/preserve-executable-header-3024
Open

karim-alweheshy wants to merge 2 commits into
bazelbuild:ks/add-empty-exported_symbols_list-by-defaultfrom
karim-alweheshy:codex/preserve-executable-header-3024

Conversation

@karim-alweheshy

@karim-alweheshy karim-alweheshy commented Sep 15, 2026

Copy link
Copy Markdown

Summary

Companion to #3024, targeting ks/add-empty-exported_symbols_list-by-default rather than main. This keeps Keith's existing commits intact and adds only the header-preserving follow-up discussed in #3024 (comment).

The default export policy now retains __mh_execute_header for executable Mach-Os instead of exporting nothing. Crash reporters use a dynamic lookup of that symbol to locate the main image; Firebase's implementation is one example.

  • Mach-O bundles and kernel extensions keep the original no-export default: they do not have an executable header symbol.
  • Dynamic libraries, bundle-loader exclusions, and explicit export lists/link options retain Pass -no_exported_symbols by default #3024's behavior.
  • Explicit export policies remain authoritative; this does not automatically add symbols to user-authored lists.
  • No new production build actions, graph traversal, or symbol-scanning tools are introduced.

Validation

Using Xcode 26.5 (17F42), Apple ld 1267:

  • CI portability follow-up: the runtime fixture builds both x86_64 and arm64 slices so ARM workers can execute it without Rosetta. The runtime test passed with Bazel 8.0.1 and 9.2.0; both slices also passed explicit architecture-selected execution. The original Intel-only fixture fails forced ARM execution with “Bad CPU type in executable.”
  • 14 focused tests passed with Bazel 9.1.1rc1.
  • The same 14 tests passed with Bazel 8.0.1.
  • The new optimized macOS executable test verifies that dlsym(RTLD_MAIN_ONLY, MH_EXECUTE_SYM) and dladdr recover the main image, while lookup of the ordinary main symbol fails.
  • Negative control: restoring only Pass -no_exported_symbols by default #3024's original -no_exported_symbols implementation makes that runtime test fail with “The executable header must remain discoverable.” Restoring this fix makes it pass.
  • Action tests cover iOS applications/extensions, macOS command-line applications, dylibs, bundles, kernel extensions, explicit export lists, custom export/alias options, and hosted-test/bundle-loader compatibility.
  • Buildifier formatting and lint, ShellCheck, Bash syntax, and git diff --check passed.

The focused checks do not replace the full upstream CI matrix or an end-to-end Firebase crash-upload test. Framework export derivation is intentionally out of scope.

Integration

Merge this companion into #3024's branch, or cherry-pick the follow-up commit. This does not rebase #3024 onto current main or resolve its existing main-branch conflicts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant