Skip to content

Commit 864ad1b

Browse files
committed
Merge branch 'PHP-8.4'
* PHP-8.4: Fix GH-18136: tracing JIT floating point register clobbering on Windows and ARM64
2 parents 158181f + 1a1a83f commit 864ad1b

File tree

5 files changed

+106
-1
lines changed

5 files changed

+106
-1
lines changed

Zend/asm/save_xmm_x86_64_ms_masm.asm

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
.code
2+
3+
; ZEND_API void execute_ex(zend_execute_data *ex)
4+
PUBLIC execute_ex
5+
6+
EXTERN execute_ex_real:PROC
7+
8+
; Assembly wrapper around the real execute_ex function, so that we can
9+
; save the preserved registers when re-entering the VM from JIT code.
10+
; See GH-18136.
11+
execute_ex PROC EXPORT FRAME
12+
; 10 floating points numbers
13+
; 32 bytes shadow space
14+
; 8 bytes to align after the return address
15+
sub rsp, 8*10 + 32 + 8
16+
.allocstack 8*10 + 32 + 8
17+
.endprolog
18+
movsd qword ptr [rsp + 32 + 8*0], xmm6
19+
movsd qword ptr [rsp + 32 + 8*1], xmm7
20+
movsd qword ptr [rsp + 32 + 8*2], xmm8
21+
movsd qword ptr [rsp + 32 + 8*3], xmm9
22+
movsd qword ptr [rsp + 32 + 8*4], xmm10
23+
movsd qword ptr [rsp + 32 + 8*5], xmm11
24+
movsd qword ptr [rsp + 32 + 8*6], xmm12
25+
movsd qword ptr [rsp + 32 + 8*7], xmm13
26+
movsd qword ptr [rsp + 32 + 8*8], xmm14
27+
movsd qword ptr [rsp + 32 + 8*9], xmm15
28+
call execute_ex_real
29+
movsd xmm6, qword ptr [rsp + 32 + 8*0]
30+
movsd xmm7, qword ptr [rsp + 32 + 8*1]
31+
movsd xmm8, qword ptr [rsp + 32 + 8*2]
32+
movsd xmm9, qword ptr [rsp + 32 + 8*3]
33+
movsd xmm10, qword ptr [rsp + 32 + 8*4]
34+
movsd xmm11, qword ptr [rsp + 32 + 8*5]
35+
movsd xmm12, qword ptr [rsp + 32 + 8*6]
36+
movsd xmm13, qword ptr [rsp + 32 + 8*7]
37+
movsd xmm14, qword ptr [rsp + 32 + 8*8]
38+
movsd xmm15, qword ptr [rsp + 32 + 8*9]
39+
add rsp, 8*10 + 32 + 8
40+
ret
41+
execute_ex ENDP
42+
43+
END

Zend/zend_vm_execute.h

+9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Zend/zend_vm_execute.skl

+9
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,19 @@
77
# pragma GCC optimize("no-gcse")
88
# pragma GCC optimize("no-ivopts")
99
#endif
10+
#ifdef _WIN64
11+
/* See save_xmm_x86_64_ms_masm.asm */
12+
void {%EXECUTOR_NAME%}_ex_real(zend_execute_data *ex)
13+
#else
1014
ZEND_API void {%EXECUTOR_NAME%}_ex(zend_execute_data *ex)
15+
#endif
1116
{
1217
DCL_OPLINE
1318

19+
#if defined(__GNUC__) && defined(__aarch64__)
20+
__asm__ __volatile__ (""::: "v8","v9","v10","v11","v12","v13","v14","v15");
21+
#endif
22+
1423
{%HELPER_VARS%}
1524

1625
{%INTERNAL_LABELS%}

ext/opcache/tests/jit/gh18136.phpt

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--TEST--
2+
GH-18136 (tracing JIT floating point register clobbering on Windows and ARM64)
3+
--EXTENSIONS--
4+
opcache
5+
--INI--
6+
opcache.jit=tracing
7+
opcache.jit_buffer_size=64M
8+
opcache.jit_hot_func=4
9+
opcache.jit_hot_loop=4
10+
--FILE--
11+
<?php
12+
namespace Foo;
13+
14+
function diff($point1, $point2)
15+
{
16+
$a = deg2rad($point1); // Prefixing these with \ also makes the issue go away
17+
$b = deg2rad($point2);
18+
return $a - $b;
19+
}
20+
21+
function getRawDistance()
22+
{
23+
$distance = 0;
24+
for ($p = 0; $p < 200; $p++) {
25+
// Needs to be a namespaced call_user_func call to reproduce the issue (i.e. adding \ at front makes the issue go away)
26+
$distance += call_user_func('Foo\diff', 0, $p);
27+
}
28+
29+
return $distance;
30+
}
31+
32+
var_dump(getRawDistance());
33+
?>
34+
--EXPECT--
35+
float(-347.3205211468715)

win32/build/config.w32

+10-1
Original file line numberDiff line numberDiff line change
@@ -267,14 +267,23 @@ if (TARGET_ARCH == 'arm64') {
267267
DEFINE('FIBER_ASM_FLAGS', '/DBOOST_CONTEXT_EXPORT=EXPORT /nologo /c /Fo');
268268
}
269269

270-
ADD_FLAG('ASM_OBJS', '$(BUILD_DIR)\\Zend\\jump_' + FIBER_ASM_ABI + '.obj $(BUILD_DIR)\\Zend\\make_' + FIBER_ASM_ABI + '.obj');
270+
var all_asm_objs = '$(BUILD_DIR)\\Zend\\jump_' + FIBER_ASM_ABI + '.obj $(BUILD_DIR)\\Zend\\make_' + FIBER_ASM_ABI + '.obj';
271+
if (TARGET_ARCH == 'x64') {
272+
all_asm_objs += ' $(BUILD_DIR)\\Zend\\save_xmm_x86_64_ms_masm.obj';
273+
}
274+
ADD_FLAG('ASM_OBJS', all_asm_objs);
271275

272276
MFO.WriteLine('$(BUILD_DIR)\\Zend\\jump_' + FIBER_ASM_ABI + '.obj: Zend\\asm\\jump_' + FIBER_ASM_ABI + '.asm');
273277
MFO.WriteLine('\t$(PHP_ASSEMBLER) $(FIBER_ASM_FLAGS) $(BUILD_DIR)\\Zend\\jump_$(FIBER_ASM_ABI).obj Zend\\asm\\jump_$(FIBER_ASM_ABI).asm');
274278

275279
MFO.WriteLine('$(BUILD_DIR)\\Zend\\make_' + FIBER_ASM_ABI + '.obj: Zend\\asm\\make_' + FIBER_ASM_ABI + '.asm');
276280
MFO.WriteLine('\t$(PHP_ASSEMBLER) $(FIBER_ASM_FLAGS) $(BUILD_DIR)\\Zend\\make_$(FIBER_ASM_ABI).obj Zend\\asm\\make_$(FIBER_ASM_ABI).asm');
277281

282+
if (TARGET_ARCH == 'x64') {
283+
MFO.WriteLine('$(BUILD_DIR)\\Zend\\save_xmm_x86_64_ms_masm.obj: Zend\\asm\\save_xmm_x86_64_ms_masm.asm');
284+
MFO.WriteLine('\t$(PHP_ASSEMBLER) $(FIBER_ASM_FLAGS) $(BUILD_DIR)\\Zend\\save_xmm_x86_64_ms_masm.obj Zend\\asm\\save_xmm_x86_64_ms_masm.asm');
285+
}
286+
278287
ADD_FLAG("CFLAGS_BD_ZEND", "/D ZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
279288
if (VS_TOOLSET && VCVERS >= 1914) {
280289
ADD_FLAG("CFLAGS_BD_ZEND", "/d2FuncCache1");

0 commit comments

Comments
 (0)