[PR #3500] [MERGED] fix(native): inspect arm64e.x1 slices by their exact name #5784

Closed
opened 2026-10-31 01:09:24 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/3500
Author: @kaoru0822-kitauji
Created: 10/14/2026
Status: ✅ Merged
Merged: 10/15/2026
Merged by: @kaoru0822-kitauji

Base: main ← Head: fix/macho-arm64e-subtype-slice


📝 Commits (1)

  • b9f76ab fix(native): inspect arm64e.x1 slices by their exact name

📊 Changes

2 files changed (+35 additions, -7 deletions)

View changed files

📝 src/native/NativeMachoInspection.ts (+20 -7)
📝 tests/boundary/providers/native/nativeSelectedArchitecture.test.ts (+15 -0)

📄 Description

Summary

inspect-macho failed on a universal executable whose arm64e slice is arm64e.x1. It passed -arch arm64e to otool, and otool rejects that name because the file has no plain arm64e slice. Fixes #3389.

Problem and expected behavior

selectedArchitectureArguments stripped every dotted lipo slice name down to its CPU family for all tools except dyld_info. lipo uses dotted names for two different things:

  • arm64e.v1 is plain arm64e (cpusubtype 2) with a pointer-auth ABI version suffix. otool, dwarfdump and vtool only accept arm64e for it.
  • arm64e.x1 is a separate cpusubtype (12). The tools only accept its exact name.

Tool behavior measured with the real cctools-1040 tools (otool, nm, dwarfdump, dyld_info, vtool) on macOS 26.7.1:

-arch value arm64e.v1 slice arm64e.x1 slice
arm64e otool, nm, dwarfdump, vtool accept; dyld_info rejects otool, nm, dyld_info, vtool reject
exact name nm, dyld_info accept; otool, dwarfdump, vtool reject otool, nm, dwarfdump, size, dyld_info accept; vtool rejects (unknown arch)

Change and scope

  • toolArchitectureName removes only the .v<N> ABI version suffix, and only for tools other than dyld_info. Every other variant name is passed exactly. -arch arguments are still built in one place.
  • vtool cannot select a variant-subtype slice under any name. It only supplies provenance (build metadata is already normalized from otool only), so it is skipped for these slices and the result records: vtool cannot select the arm64e.x1 slice; build metadata is normalized from otool only.
  • Not changed: how the slice is selected, and the output for v1 or plain slices.

Contribution scope: an ordinary fix within existing boundaries, so no maintainer scope decision is needed.

Contract and boundary impact

  • Semantic owner and earliest changed stage: src/native/NativeMachoInspection.ts, where the selected lipo slice name becomes per-tool -arch arguments.

  • Contribution scope fit and linked maintainer decision: not applicable (ordinary fix).

  • CLI and MCP/tool-catalog contract: no schema change. An x1 slice now returns a result with one added limitation instead of execution_failure.

  • Provider, bridge, target-format, or platform compatibility: macOS native tools only.

  • Evidence, artifact, provenance, or reconstruction contract: selected_architecture keeps the exact arm64e.x1 name and container offset. vtool provenance is missing for that slice, and the limitation says so.

  • Target selection, authority, upstream behavior, and cleanup details: unchanged. Tools only read the file.

  • Generated metadata: none.

  • Read existing files or captured data.

Evidence and regression coverage

  • Tests added or updated: tests/boundary/providers/native/nativeSelectedArchitecture.test.ts gains an ["x86_64", "arm64e.x1"] case. Its runner rejects any tool that doesn't name the exact slice. Every case also asserts that vtool runs only for slices it can name and that the limitation appears only when vtool is skipped.

  • Base reproduction: with the source change reverted, the new case fails (1 failed, 15 passed).

  • Real-tool CLI reproduction (xcrun clang -arch x86_64 -arch arm64e.x1, then rea inspect-macho <fat> --json):

    • main: exit 1, execution_failure, otool does not contain architecture: arm64e
    • this PR: exit 0, selected_architecture: {name: "arm64e.x1", container_file_offset: 16384}. The UUID 4CF86D9F-… matches the x1 slice.
  • Control cases with the real tools: an arm64e + arm64e.x1 FAT and a copy patched to arm64e.v1 (cpusubtype 0x81000002) both still select arm64e.v1 and run vtool, the same as on main.

  • Regression check on real Apple binaries: for /bin/ls and Calculator, the inspect-macho JSON is byte-identical to main's (Evidence ID excluded). Wall time is unchanged at about 0.95 s on both.

  • Remaining proof gaps: only the Command Line Tools vtool (cctools-1040) was tested. A future vtool that understands arm64e.x1 would still be skipped. That is conservative, and the limitation says so.

  • Observed, derived, and inferred claims remain distinguishable.

  • Artifact identity, source provenance, and failed attempts remain preserved.

  • Unsupported, incomplete, unavailable, or uncertain outcomes remain visible.

Validation performed

  • npm run test:focused -- tests/boundary/providers/native/nativeSelectedArchitecture.test.ts tests/boundary/providers/native/nativeProvider.test.ts: 62 passed
  • npm run check:fast: passed
  • Built CLI against real clang-built x1, x1+arm64e and v1 FAT binaries, /bin/ls, and Calculator: as listed above

Compatibility, safety, and release

  • Breaking changes or migration steps: none.
  • Real Hopper/Ghidra, browser, or OS coverage: macOS 26.7.1 arm64 with the real Apple tools. Hopper and Ghidra are not involved.
  • Package or release metadata impact: none.
  • Security, privacy, process, or containment review: one fewer process (vtool) for x1 slices. Nothing else changes.

Author readiness

Human owner:

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/3500 **Author:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Created:** 10/14/2026 **Status:** ✅ Merged **Merged:** 10/15/2026 **Merged by:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Base:** `main` ← **Head:** `fix/macho-arm64e-subtype-slice` --- ### 📝 Commits (1) - [`b9f76ab`](https://github.com/morluto/rea/commit/b9f76ab6a9abd50169f5ce413d3d1bd3ea8c156e) fix(native): inspect arm64e.x1 slices by their exact name ### 📊 Changes **2 files changed** (+35 additions, -7 deletions) <details> <summary>View changed files</summary> 📝 `src/native/NativeMachoInspection.ts` (+20 -7) 📝 `tests/boundary/providers/native/nativeSelectedArchitecture.test.ts` (+15 -0) </details> ### 📄 Description ## Summary `inspect-macho` failed on a universal executable whose arm64e slice is `arm64e.x1`. It passed `-arch arm64e` to otool, and otool rejects that name because the file has no plain arm64e slice. Fixes #3389. ## Problem and expected behavior `selectedArchitectureArguments` stripped every dotted lipo slice name down to its CPU family for all tools except dyld_info. lipo uses dotted names for two different things: - `arm64e.v1` is plain arm64e (cpusubtype 2) with a pointer-auth ABI version suffix. otool, dwarfdump and vtool only accept `arm64e` for it. - `arm64e.x1` is a separate cpusubtype (12). The tools only accept its exact name. Tool behavior measured with the real cctools-1040 tools (otool, nm, dwarfdump, dyld_info, vtool) on macOS 26.7.1: | `-arch` value | `arm64e.v1` slice | `arm64e.x1` slice | |---|---|---| | `arm64e` | otool, nm, dwarfdump, vtool accept; dyld_info rejects | otool, nm, dyld_info, vtool reject | | exact name | nm, dyld_info accept; otool, dwarfdump, vtool reject | otool, nm, dwarfdump, size, dyld_info accept; vtool rejects (`unknown arch`) | ## Change and scope - `toolArchitectureName` removes only the `.v<N>` ABI version suffix, and only for tools other than dyld_info. Every other variant name is passed exactly. `-arch` arguments are still built in one place. - vtool cannot select a variant-subtype slice under any name. It only supplies provenance (build metadata is already normalized from otool only), so it is skipped for these slices and the result records: `vtool cannot select the arm64e.x1 slice; build metadata is normalized from otool only.` - Not changed: how the slice is selected, and the output for v1 or plain slices. Contribution scope: an ordinary fix within existing boundaries, so no maintainer scope decision is needed. ## Contract and boundary impact - Semantic owner and earliest changed stage: `src/native/NativeMachoInspection.ts`, where the selected lipo slice name becomes per-tool `-arch` arguments. - Contribution scope fit and linked maintainer decision: not applicable (ordinary fix). - CLI and MCP/tool-catalog contract: no schema change. An x1 slice now returns a result with one added limitation instead of `execution_failure`. - Provider, bridge, target-format, or platform compatibility: macOS native tools only. - Evidence, artifact, provenance, or reconstruction contract: `selected_architecture` keeps the exact `arm64e.x1` name and container offset. vtool provenance is missing for that slice, and the limitation says so. - Target selection, authority, upstream behavior, and cleanup details: unchanged. Tools only read the file. - Generated metadata: none. - [x] Read existing files or captured data. ## Evidence and regression coverage - Tests added or updated: `tests/boundary/providers/native/nativeSelectedArchitecture.test.ts` gains an `["x86_64", "arm64e.x1"]` case. Its runner rejects any tool that doesn't name the exact slice. Every case also asserts that vtool runs only for slices it can name and that the limitation appears only when vtool is skipped. - Base reproduction: with the source change reverted, the new case fails (1 failed, 15 passed). - Real-tool CLI reproduction (`xcrun clang -arch x86_64 -arch arm64e.x1`, then `rea inspect-macho <fat> --json`): - main: exit 1, `execution_failure`, otool `does not contain architecture: arm64e` - this PR: exit 0, `selected_architecture: {name: "arm64e.x1", container_file_offset: 16384}`. The UUID `4CF86D9F-…` matches the x1 slice. - Control cases with the real tools: an arm64e + arm64e.x1 FAT and a copy patched to `arm64e.v1` (cpusubtype `0x81000002`) both still select `arm64e.v1` and run vtool, the same as on main. - Regression check on real Apple binaries: for `/bin/ls` and Calculator, the `inspect-macho` JSON is byte-identical to main's (Evidence ID excluded). Wall time is unchanged at about 0.95 s on both. - Remaining proof gaps: only the Command Line Tools vtool (cctools-1040) was tested. A future vtool that understands `arm64e.x1` would still be skipped. That is conservative, and the limitation says so. - [x] Observed, derived, and inferred claims remain distinguishable. - [x] Artifact identity, source provenance, and failed attempts remain preserved. - [x] Unsupported, incomplete, unavailable, or uncertain outcomes remain visible. ## Validation performed - `npm run test:focused -- tests/boundary/providers/native/nativeSelectedArchitecture.test.ts tests/boundary/providers/native/nativeProvider.test.ts`: 62 passed - `npm run check:fast`: passed - Built CLI against real clang-built x1, x1+arm64e and v1 FAT binaries, `/bin/ls`, and Calculator: as listed above ## Compatibility, safety, and release - Breaking changes or migration steps: none. - Real Hopper/Ghidra, browser, or OS coverage: macOS 26.7.1 arm64 with the real Apple tools. Hopper and Ghidra are not involved. - Package or release metadata impact: none. - Security, privacy, process, or containment review: one fewer process (vtool) for x1 slices. Nothing else changes. ## Author readiness Human owner: <!-- @GitHub-handle --> - [ ] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [ ] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [ ] I declare this PR ready for initial maintainer review. ## Before merge - [ ] This PR addresses a concrete problem or an agreed enhancement. - [ ] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [ ] The PR has one focused outcome and the title follows `type(scope): outcome`. - [ ] Related issue is linked, or the reason for not linking one is stated above. - [ ] Tests cover changed observable behavior and meaningful failure paths. - [ ] Owning docs, contracts, and generated metadata are updated where needed. - [ ] User-visible CLI/MCP changes include representative output. - [ ] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-31 01:09:24 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#5784
No description provided.