]> granicus.if.org Git - php/commitdiff
Fixed bug #80782 (DASM_S_RANGE_VREG on PHP_INT_MIN-1)
authorDmitry Stogov <dmitry@zend.com>
Wed, 24 Feb 2021 09:20:20 +0000 (12:20 +0300)
committerDmitry Stogov <dmitry@zend.com>
Wed, 24 Feb 2021 09:20:20 +0000 (12:20 +0300)
NEWS
ext/opcache/jit/zend_jit_x86.dasc
ext/opcache/tests/jit/bug80782.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index e3e8be870b5258ad6daf1c23c15831de22101260..18bd50a9864a7b94d63e96d1f040175f1c97142f 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,7 @@ PHP                                                                        NEWS
 
 - Opcache:
   . Fixed bug #80786 (PHP crash using JIT). (Nikita)
+  . Fixed bug #80782 (DASM_S_RANGE_VREG on PHP_INT_MIN-1). (Dmitry)
 
 - Session:
   . Fixed bug #80774 (session_name() problem with backslash). (cmb)
index 0df475e468a837c60b43ba6134797d21dd4c43fb..d886085ad4b88e45904a9c26bb01040de3c2772a 100644 (file)
@@ -4329,12 +4329,17 @@ static int zend_jit_math_long_long(dasm_State    **Dst,
                }
 
                do {
-                       if ((Z_MODE(op1_addr) == IS_CONST_ZVAL && Z_LVAL_P(Z_ZV(op1_addr)) == 1) ||
-                           (Z_MODE(op2_addr) == IS_CONST_ZVAL && Z_LVAL_P(Z_ZV(op2_addr)) == 1)) {
+                       if ((sizeof(void*) == 8 || Z_MODE(res_addr) != IS_REG) &&
+                           ((Z_MODE(op1_addr) == IS_CONST_ZVAL && Z_LVAL_P(Z_ZV(op1_addr)) == 1) ||
+                            (Z_MODE(op2_addr) == IS_CONST_ZVAL && Z_LVAL_P(Z_ZV(op2_addr)) == 1))) {
                                if (opcode == ZEND_ADD) {
                                        |.if X64
                                                |       mov64 rax, 0x43e0000000000000
-                                               |       SET_ZVAL_LVAL res_addr, rax
+                                               if (Z_MODE(res_addr) == IS_REG) {
+                                                       |       movd xmm(Z_REG(res_addr)-ZREG_XMM0), rax
+                                               } else {
+                                                       |       SET_ZVAL_LVAL res_addr, rax
+                                               }
                                        |.else
                                                |       SET_ZVAL_LVAL res_addr, 0
                                                |       SET_ZVAL_W2 res_addr, 0x41e00000
@@ -4343,7 +4348,11 @@ static int zend_jit_math_long_long(dasm_State    **Dst,
                                } else if (opcode == ZEND_SUB) {
                                        |.if X64
                                                |       mov64 rax, 0xc3e0000000000000
-                                               |       SET_ZVAL_LVAL res_addr, rax
+                                               if (Z_MODE(res_addr) == IS_REG) {
+                                                       |       movd xmm(Z_REG(res_addr)-ZREG_XMM0), rax
+                                               } else {
+                                                       |       SET_ZVAL_LVAL res_addr, rax
+                                               }
                                        |.else
                                                |       SET_ZVAL_LVAL res_addr, 0x00200000
                                                |       SET_ZVAL_W2 res_addr, 0xc1e00000
diff --git a/ext/opcache/tests/jit/bug80782.phpt b/ext/opcache/tests/jit/bug80782.phpt
new file mode 100644 (file)
index 0000000..c05987c
--- /dev/null
@@ -0,0 +1,18 @@
+--TEST--
+Bug #80782 (DASM_S_RANGE_VREG on PHP_INT_MIN-1)
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.file_update_protection=0
+opcache.jit=tracing
+opcache.jit_buffer_size=1M
+opcache.protect_memory=1
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+define('LONG_MIN', PHP_INT_MIN);
+var_dump(LONG_MIN-1);
+?>
+--EXPECTF--
+float(%s)