]> granicus.if.org Git - php/commitdiff
Fixed bug #80745 (JIT produces Assert failure and UNKNOWN:0 var_dumps in code involvi...
authorDmitry Stogov <dmitry@zend.com>
Wed, 17 Feb 2021 08:51:13 +0000 (11:51 +0300)
committerDmitry Stogov <dmitry@zend.com>
Wed, 17 Feb 2021 08:51:13 +0000 (11:51 +0300)
NEWS
ext/opcache/jit/zend_jit.c
ext/opcache/jit/zend_jit_trace.c
ext/opcache/tests/jit/bug80745.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index d8a37b4323b47ce312b66c352c8731ad39c065c2..63901ebd5e275bb20cdce311d4da889813d75c63 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -28,6 +28,8 @@ PHP                                                                        NEWS
   . Fixed bug #80682 (opcache doesn't honour pcre.jit option). (Remi)
   . Fixed bug #80742 (Opcache JIT makes some boolean logic unexpectedly be
     true). (Dmitry)
+  . Fixed bug #80745 (JIT produces Assert failure and UNKNOWN:0 var_dumps in
+    code involving bitshifts). (Dmitry)
 
 - OpenSSL:
   . Fixed bug #80747 (Providing RSA key size < 512 generates key that crash
index 1306bb36ba015b0b693483173205d9a34b72dd11..7513abbf9bcc368eb006c9c897fe87c61317db45 100644 (file)
@@ -2303,7 +2303,17 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
                                                        break;
                                                }
                                                if (opline->result_type != IS_UNUSED) {
-                                                       res_use_info = RES_USE_INFO();
+                                                       res_use_info = -1;
+
+                                                       if (opline->result_type == IS_CV) {
+                                                               zend_jit_addr res_use_addr = RES_USE_REG_ADDR();
+
+                                                               if (Z_MODE(res_use_addr) != IS_REG
+                                                                || Z_LOAD(res_use_addr)
+                                                                || Z_STORE(res_use_addr)) {
+                                                                       res_use_info = RES_USE_INFO();
+                                                               }
+                                                       }
                                                        res_info = RES_INFO();
                                                        res_addr = RES_REG_ADDR();
                                                } else {
@@ -2354,7 +2364,17 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
                                                                goto jit_failure;
                                                        }
                                                } else {
-                                                       res_use_info = RES_USE_INFO();
+                                                       res_use_info = -1;
+
+                                                       if (opline->result_type == IS_CV) {
+                                                               zend_jit_addr res_use_addr = RES_USE_REG_ADDR();
+
+                                                               if (Z_MODE(res_use_addr) != IS_REG
+                                                                || Z_LOAD(res_use_addr)
+                                                                || Z_STORE(res_use_addr)) {
+                                                                       res_use_info = RES_USE_INFO();
+                                                               }
+                                                       }
                                                }
                                                if (!zend_jit_long_math(&dasm_state, opline,
                                                                op1_info, OP1_RANGE(), OP1_REG_ADDR(),
@@ -2398,7 +2418,17 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
                                                                goto jit_failure;
                                                        }
                                                } else {
-                                                       res_use_info = RES_USE_INFO();
+                                                       res_use_info = -1;
+
+                                                       if (opline->result_type == IS_CV) {
+                                                               zend_jit_addr res_use_addr = RES_USE_REG_ADDR();
+
+                                                               if (Z_MODE(res_use_addr) != IS_REG
+                                                                || Z_LOAD(res_use_addr)
+                                                                || Z_STORE(res_use_addr)) {
+                                                                       res_use_info = RES_USE_INFO();
+                                                               }
+                                                       }
                                                }
                                                res_info = RES_INFO();
                                                if (opline->opcode == ZEND_ADD &&
index 69c4f79fa87352c95ad4bfd10f27c7baeac4248e..8353c3cec04f997798a95f66a55671c817c66ef2 100644 (file)
@@ -3878,10 +3878,15 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
                                                                STACK_MEM_TYPE(stack, EX_VAR_TO_NUM(opline->result.var)))
                                                                        & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE);
 #else
+                                                       res_use_info = -1;
                                                        if (opline->result_type == IS_CV) {
-                                                               res_use_info = RES_USE_INFO();
-                                                       } else {
-                                                               res_use_info = MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE;
+                                                               zend_jit_addr res_use_addr = RES_USE_REG_ADDR();
+
+                                                               if (Z_MODE(res_use_addr) != IS_REG
+                                                                || Z_LOAD(res_use_addr)
+                                                                || Z_STORE(res_use_addr)) {
+                                                                       res_use_info = RES_USE_INFO();
+                                                               }
                                                        }
 #endif
                                                        res_info = RES_INFO();
@@ -3973,10 +3978,15 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
                                                                STACK_MEM_TYPE(stack, EX_VAR_TO_NUM(opline->result.var)))
                                                                        & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE);
 #else
+                                                       res_use_info = -1;
                                                        if (opline->result_type == IS_CV) {
-                                                               res_use_info = RES_USE_INFO();
-                                                       } else {
-                                                               res_use_info = MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE;
+                                                               zend_jit_addr res_use_addr = RES_USE_REG_ADDR();
+
+                                                               if (Z_MODE(res_use_addr) != IS_REG
+                                                                || Z_LOAD(res_use_addr)
+                                                                || Z_STORE(res_use_addr)) {
+                                                                       res_use_info = RES_USE_INFO();
+                                                               }
                                                        }
 #endif
                                                }
@@ -4050,10 +4060,15 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
                                                                STACK_MEM_TYPE(stack, EX_VAR_TO_NUM(opline->result.var)))
                                                                        & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE);
 #else
+                                                       res_use_info = -1;
                                                        if (opline->result_type == IS_CV) {
-                                                               res_use_info = RES_USE_INFO();
-                                                       } else {
-                                                               res_use_info = MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE;
+                                                               zend_jit_addr res_use_addr = RES_USE_REG_ADDR();
+
+                                                               if (Z_MODE(res_use_addr) != IS_REG
+                                                                || Z_LOAD(res_use_addr)
+                                                                || Z_STORE(res_use_addr)) {
+                                                                       res_use_info = RES_USE_INFO();
+                                                               }
                                                        }
 #endif
                                                }
diff --git a/ext/opcache/tests/jit/bug80745.phpt b/ext/opcache/tests/jit/bug80745.phpt
new file mode 100644 (file)
index 0000000..66956f4
--- /dev/null
@@ -0,0 +1,43 @@
+--TEST--
+Bug #80745 (JIT produces Assert failure and UNKNOWN:0 var_dumps in code involving bitshifts)
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.file_update_protection=0
+opcache.jit=function
+opcache.jit_buffer_size=1M
+opcache.protect_memory=1
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+final class Message
+{
+    public $qr = false;
+
+    public $opcode = 0;
+
+    public $aa = false;
+}
+
+echo "Starting...\n";
+
+function headerToBinary(Message $message)
+{
+        $flags = 0;
+        $flags = ($flags << 1) | ($message->qr ? 1 : 0);
+        $flags = ($flags << 4) | $message->opcode;
+        var_dump($flags);
+        $flags = ($flags << 1) | ($message->aa ? 1 : 0);
+}
+
+headerToBinary(new Message());
+
+echo "PROBLEM NOT REPRODUCED !\n";
+?>
+--EXPECT--
+Starting...
+int(0)
+PROBLEM NOT REPRODUCED !
+