From 67f1b1116e8b827014825a46693929221136b0c8 Mon Sep 17 00:00:00 2001 From: Wes Smith Date: Mon, 22 Jun 2026 11:53:47 +0200 Subject: [PATCH] android: Fix ART crash on Android 17 arm64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two bugs make Java.perform() SIGBUS on API 37. _getArtMethodSpec() left kAccNterpEntryPointFastPathFlag unmasked, which the API 37 probe method carries, so the access_flags scan latched onto the next ArtMethod and corrupted the flag offset. makeArtThreadStateTransitionImpl()'s invokeCallback loads callback through a PC-relative literal flushed too late: the relocated ExceptionClear body pushes the pool out of ±1 MiB reach. Emit invokeCallback first, flush after its ret, enter via the relocated body. --- lib/android.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/android.js b/lib/android.js index 11daebe..62c9c9f 100644 --- a/lib/android.js +++ b/lib/android.js @@ -1187,7 +1187,7 @@ function _getArtMethodSpec (vm) { const entrypointFieldSize = (apiLevel <= 21) ? 8 : pointerSize; const expectedAccessFlags = kAccPublic | kAccStatic | kAccFinal | kAccNative; - const relevantAccessFlagsMask = ~(kAccFastInterpreterToInterpreterInvoke | kAccPublicApi | kAccNterpInvokeFastPathFlag) >>> 0; + const relevantAccessFlagsMask = ~(kAccFastInterpreterToInterpreterInvoke | kAccPublicApi | kAccNterpInvokeFastPathFlag | kAccNterpEntryPointFastPathFlag) >>> 0; let jniCodeOffset = null; let accessFlagsOffset = null; @@ -4866,15 +4866,14 @@ function recompileExceptionClearForArm64 (buffer, pc, exceptionClearImpl, nextFu const writer = new Arm64Writer(buffer, { pc }); - writer.putBLabel('performTransition'); - const invokeCallback = pc.add(writer.offset); writer.putPushAllXRegisters(); writer.putCallAddressWithArguments(callback, ['x0']); writer.putPopAllXRegisters(); writer.putRet(); + writer.flush(); - writer.putLabel('performTransition'); + const performEntry = pc.add(writer.offset); let foundCore = false; let threadReg = null; @@ -5004,7 +5003,7 @@ function recompileExceptionClearForArm64 (buffer, pc, exceptionClearImpl, nextFu throwThreadStateTransitionParseError(); } - return new NativeFunction(pc, 'void', ['pointer'], nativeFunctionOptions); + return new NativeFunction(performEntry, 'void', ['pointer'], nativeFunctionOptions); } function throwThreadStateTransitionParseError () {