Skip to content

feat(opcache): macOS/arm64 support for the relocator (addressing-model tripwire) - #268

Merged
lisachenko merged 1 commit into
8.4from
claude/opcache-119-darwin-relocator
Aug 20, 2026
Merged

feat(opcache): macOS/arm64 support for the relocator (addressing-model tripwire)#268
lisachenko merged 1 commit into
8.4from
claude/opcache-119-darwin-relocator

Conversation

@lisachenko

Copy link
Copy Markdown
Owner

What this changes

Fixes #119 — stacked on #267.

Scoping finding (the point of the issue): the ZEND_USE_ABS_CONST_ADDR/ZEND_USE_ABS_JMP_ADDR per-opline branches are compiled in only when SIZEOF_SIZE_T == 4 (zend_compile.h). Darwin x64 and arm64 are 64-bit and use the same relative addressing as linux — there is no darwin-specific opline walking to port, and implementing those branches would be dead code on every supported build. So they are deliberately not implemented; 32-bit builds (the only absolute-addressing ones) stay refused by PHP_INT_SIZE === 8.

Landed instead: OpcodeAddressingModelTest — a tripwire proving the relative model on a real compiled payload (every IS_CONST operand is a literal-table index; every JMP-family operand lands on an opline of its own op_array) that fails, not skips, on any supported build (darwin CI legs included) if a build ever emits absolute operands. Plus fixtures/addressing-probe.php (getenv-guarded so SCCP can't fold the const/jump ops). Docs + the opcodes comment record the invariant and its source.

Darwin execution happens on this PR's tests-macos CI legs — the tripwire runs there; if it ever goes red, a darwin build unexpectedly uses absolute addressing and the abs-addr branches would then need porting.

Environment it was verified on

  • PHP version (full first line of php -v): PHP 8.4.19 (cli) (built: Mar 30 2026 19:28:35) (NTS) + ZTS debug container
  • Thread safety: NTS + ZTS
  • OS / architecture: Linux x86-64 (Ubuntu); darwin validated via CI legs
  • Debug build (--enable-debug)? yes — debug84 NTS + debug84-zts, opcache gate 48 each

Also: host 520 tests, opcache gate 48; PHPStan level max clean; cs-fixer clean.

Checklist

  • Targets the minimum affected version branch (chain → 8.4)
  • composer test passes on the matching PHP minor
  • composer phpstan (level max) and composer cs:check are green
  • Tests added or updated; no new struct dereferences
  • tools/generator/symbols.php unchanged — nothing generated touched
  • Conventional Commits used for the commit messages

🤖 Generated with Claude Code

https://claude.ai/code/session_01BDcCQiYqbMkjRPyhWgLL6M


Generated by Claude Code

…pwire

Scope finding for issue #119 (macOS/arm64 relocator support): the per-opline
absolute-address branches of zend_file_cache_(un)serialize_op_array
(op1/op2.zv SERIALIZE_PTR and the jmp_addr switch) are compiled in only when
ZEND_USE_ABS_CONST_ADDR / ZEND_USE_ABS_JMP_ADDR are 1, and zend_compile.h
(PHP-8.4.19) defines both as 1 exactly when SIZEOF_SIZE_T == 4. Darwin x64
and arm64 are 64-bit builds and use the same relative addressing as linux -
there is no darwin-specific opline walking to port. Implementing those
branches would be dead code on every build the relocator supports, so they
are deliberately NOT implemented; 32-bit builds (the only ones that use
absolute addressing) stay refused by the PHP_INT_SIZE === 8 predicate.

What lands instead:
- OpcodeAddressingModelTest: proves the relative model on a real compiled
  payload - every IS_CONST operand in the file is a literal-table index and
  every JMP-family operand lands on an opline of its own op_array. The test
  runs (does not skip) on every supported build, darwin CI legs included,
  and FAILS loudly if a build ever produces absolute operands.
- fixtures/addressing-probe.php: top-level code built around getenv() so SCCP
  cannot fold away the ?: and !== branches - IS_CONST operands and
  conditional jumps are guaranteed in the main op_array.
- The opcodes comment in PayloadRelocator and docs/opcache-binary.md now
  state the invariant and its source precisely.

Darwin execution of these tests happens on the PR's tests-macos CI legs (the
relocator group already gates there since #118 removed the ZTS exclusion);
no local darwin validation is possible from this environment.

Acceptance evidence:
- host: full default suite (520 tests, baseline skip counts), --group opcache
  --fail-on-skipped OK (48 tests, 338 assertions)
- z-engine-php:debug84 and z-engine-php:debug84-zts containers: same opcache
  gate OK (48/338 each)
- phpstan level max clean, php-cs-fixer clean

Fixes #119

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BDcCQiYqbMkjRPyhWgLL6M
@lisachenko
lisachenko force-pushed the claude/opcache-118-zts-relocator branch from 67fee31 to fb8bda9 Compare August 20, 2026 00:30
@lisachenko
lisachenko force-pushed the claude/opcache-119-darwin-relocator branch from 193bd6e to a20e806 Compare August 20, 2026 00:30
Base automatically changed from claude/opcache-118-zts-relocator to 8.4 August 20, 2026 00:35
@lisachenko
lisachenko marked this pull request as ready for review August 20, 2026 00:36
@lisachenko
lisachenko merged commit 83678e3 into 8.4 Aug 20, 2026
21 checks passed
@lisachenko
lisachenko deleted the claude/opcache-119-darwin-relocator branch August 20, 2026 00:42
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.

feat(opcache): macOS/arm64 support for the relocator (absolute-address oplines)

2 participants