Skip to content

Commit 42ccf93

Browse files
committed
Merge branch 'PHP-8.0' into PHP-8.1
* PHP-8.0: JIT: Fixed memory lieak
2 parents 0040571 + 48a65fe commit 42ccf93

File tree

3 files changed

+119
-72
lines changed

3 files changed

+119
-72
lines changed

ext/opcache/jit/zend_jit_arm64.dasc

Lines changed: 52 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -830,11 +830,10 @@ static bool logical_immediate_p(uint64_t value, uint32_t reg_size)
830830
|.endmacro
831831

832832
|.macro UNDEF_OPLINE_RESULT_IF_USED, tmp_reg1, tmp_reg2
833-
| ldr REG0, EX->opline
834-
| ldrb tmp_reg1, OP:REG0->result_type
833+
| ldrb tmp_reg1, OP:RX->result_type
835834
| TST_32_WITH_CONST tmp_reg1, (IS_TMP_VAR|IS_VAR), tmp_reg2
836835
| beq >1
837-
| ldr REG0w, OP:REG0->result.var
836+
| ldr REG0w, OP:RX->result.var
838837
| add REG0, FP, REG0
839838
| SET_Z_TYPE_INFO REG0, IS_UNDEF, tmp_reg1
840839
|1:
@@ -1850,6 +1849,48 @@ static int zend_jit_exception_handler_undef_stub(dasm_State **Dst)
18501849
return 1;
18511850
}
18521851

1852+
static int zend_jit_exception_handler_free_op1_op2_stub(dasm_State **Dst)
1853+
{
1854+
zend_jit_addr addr = ZEND_ADDR_MEM_ZVAL(ZREG_REG0, 0);
1855+
1856+
|->exception_handler_free_op1_op2:
1857+
| UNDEF_OPLINE_RESULT_IF_USED TMP1w, TMP2w
1858+
| ldrb TMP1w, OP:RX->op1_type
1859+
| TST_32_WITH_CONST TMP1w, (IS_TMP_VAR|IS_VAR), TMP2w
1860+
| beq >9
1861+
| ldr REG0w, OP:RX->op1.var
1862+
| add REG0, REG0, FP
1863+
| ZVAL_PTR_DTOR addr, MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN|MAY_BE_REF, 0, 0, NULL, ZREG_TMP1, ZREG_TMP2
1864+
|9:
1865+
| ldrb TMP1w, OP:RX->op2_type
1866+
| TST_32_WITH_CONST TMP1w, (IS_TMP_VAR|IS_VAR), TMP2w
1867+
| beq >9
1868+
| ldr REG0w, OP:RX->op2.var
1869+
| add REG0, REG0, FP
1870+
| ZVAL_PTR_DTOR addr, MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN|MAY_BE_REF, 0, 0, NULL, ZREG_TMP1, ZREG_TMP2
1871+
|9:
1872+
| b ->exception_handler
1873+
return 1;
1874+
}
1875+
1876+
static int zend_jit_exception_handler_free_op2_stub(dasm_State **Dst)
1877+
{
1878+
zend_jit_addr addr = ZEND_ADDR_MEM_ZVAL(ZREG_REG0, 0);
1879+
1880+
|->exception_handler_free_op2:
1881+
| MEM_LOAD_64_ZTS ldr, RX, executor_globals, opline_before_exception, REG0
1882+
| UNDEF_OPLINE_RESULT_IF_USED TMP1w, TMP2w
1883+
| ldrb TMP1w, OP:RX->op2_type
1884+
| TST_32_WITH_CONST TMP1w, (IS_TMP_VAR|IS_VAR), TMP2w
1885+
| beq >9
1886+
| ldr REG0w, OP:RX->op2.var
1887+
| add REG0, REG0, FP
1888+
| ZVAL_PTR_DTOR addr, MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN|MAY_BE_REF, 0, 0, NULL, ZREG_TMP1, ZREG_TMP2
1889+
|9:
1890+
| b ->exception_handler
1891+
return 1;
1892+
}
1893+
18531894
static int zend_jit_leave_function_stub(dasm_State **Dst)
18541895
{
18551896
|->leave_function_handler:
@@ -2121,57 +2162,23 @@ static int zend_jit_undefined_function_stub(dasm_State **Dst)
21212162

21222163
static int zend_jit_negative_shift_stub(dasm_State **Dst)
21232164
{
2124-
zend_jit_addr addr = ZEND_ADDR_MEM_ZVAL(ZREG_REG0, 0);
2125-
21262165
|->negative_shift:
21272166
| ldr RX, EX->opline
2128-
| UNDEF_OPLINE_RESULT_IF_USED TMP1w, TMP2w
21292167
| LOAD_ADDR CARG1, zend_ce_arithmetic_error
21302168
| LOAD_ADDR CARG2, "Bit shift by negative number"
21312169
| EXT_CALL zend_throw_error, REG0
2132-
| ldrb TMP1w, OP:RX->op1_type
2133-
| TST_32_WITH_CONST TMP1w, (IS_TMP_VAR|IS_VAR), TMP2w
2134-
| beq >9
2135-
| ldr REG0w, OP:RX->op1.var
2136-
| add REG0, REG0, FP
2137-
| ZVAL_PTR_DTOR addr, MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN|MAY_BE_REF, 0, 0, NULL, ZREG_TMP1, ZREG_TMP2
2138-
|9:
2139-
| ldrb TMP1w, OP:RX->op2_type
2140-
| TST_32_WITH_CONST TMP1w, (IS_TMP_VAR|IS_VAR), TMP2w
2141-
| beq >9
2142-
| ldr REG0w, OP:RX->op2.var
2143-
| add REG0, REG0, FP
2144-
| ZVAL_PTR_DTOR addr, MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN|MAY_BE_REF, 0, 0, NULL, ZREG_TMP1, ZREG_TMP2
2145-
|9:
2146-
| b ->exception_handler
2170+
| b ->exception_handler_free_op1_op2
21472171
return 1;
21482172
}
21492173

21502174
static int zend_jit_mod_by_zero_stub(dasm_State **Dst)
21512175
{
2152-
zend_jit_addr addr = ZEND_ADDR_MEM_ZVAL(ZREG_REG0, 0);
2153-
21542176
|->mod_by_zero:
21552177
| ldr RX, EX->opline
2156-
| UNDEF_OPLINE_RESULT_IF_USED TMP1w, TMP2w
21572178
| LOAD_ADDR CARG1, zend_ce_division_by_zero_error
21582179
| LOAD_ADDR CARG2, "Modulo by zero"
21592180
| EXT_CALL zend_throw_error, REG0
2160-
| ldrb TMP1w, OP:RX->op1_type
2161-
| TST_32_WITH_CONST TMP1w, (IS_TMP_VAR|IS_VAR), TMP2w
2162-
| beq >9
2163-
| ldr REG0w, OP:RX->op1.var
2164-
| add REG0, REG0, FP
2165-
| ZVAL_PTR_DTOR addr, MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN|MAY_BE_REF, 0, 0, NULL, ZREG_TMP1, ZREG_TMP2
2166-
|9:
2167-
| ldrb TMP1w, OP:RX->op2_type
2168-
| TST_32_WITH_CONST TMP1w, (IS_TMP_VAR|IS_VAR), TMP2w
2169-
| beq >9
2170-
| ldr REG0w, OP:RX->op2.var
2171-
| add REG0, REG0, FP
2172-
| ZVAL_PTR_DTOR addr, MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN|MAY_BE_REF, 0, 0, NULL, ZREG_TMP1, ZREG_TMP2
2173-
|9:
2174-
| b ->exception_handler
2181+
| b ->exception_handler_free_op1_op2
21752182
return 1;
21762183
}
21772184

@@ -2701,6 +2708,8 @@ static const zend_jit_stub zend_jit_stubs[] = {
27012708
JIT_STUB(interrupt_handler, SP_ADJ_JIT, SP_ADJ_VM),
27022709
JIT_STUB(exception_handler, SP_ADJ_JIT, SP_ADJ_VM),
27032710
JIT_STUB(exception_handler_undef, SP_ADJ_JIT, SP_ADJ_VM),
2711+
JIT_STUB(exception_handler_free_op1_op2, SP_ADJ_JIT, SP_ADJ_VM),
2712+
JIT_STUB(exception_handler_free_op2, SP_ADJ_JIT, SP_ADJ_VM),
27042713
JIT_STUB(leave_function, SP_ADJ_JIT, SP_ADJ_VM),
27052714
JIT_STUB(leave_throw, SP_ADJ_JIT, SP_ADJ_VM),
27062715
JIT_STUB(icall_throw, SP_ADJ_JIT, SP_ADJ_VM),
@@ -4873,7 +4882,10 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
48734882
| FREE_OP op1_type, op1, op1_info, 0, NULL, ZREG_TMP1, ZREG_TMP2
48744883
| FREE_OP op2_type, op2, op2_info, 0, NULL, ZREG_TMP1, ZREG_TMP2
48754884
if (may_throw) {
4876-
if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_RX) {
4885+
if (opline->opcode == ZEND_ASSIGN_DIM_OP && (opline->op2_type & (IS_VAR|IS_TMP_VAR))) {
4886+
| MEM_LOAD_64_ZTS ldr, TMP2, executor_globals, exception, TMP1
4887+
| cbnz TMP2, ->exception_handler_free_op2
4888+
} else if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_RX) {
48774889
zend_jit_check_exception_undef_result(Dst, opline);
48784890
} else {
48794891
zend_jit_check_exception(Dst);

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 46 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -541,10 +541,9 @@ static size_t tsrm_tls_offset;
541541
|.endmacro
542542

543543
|.macro UNDEF_OPLINE_RESULT_IF_USED
544-
| mov r0, EX->opline
545-
| test byte OP:r0->result_type, (IS_TMP_VAR|IS_VAR)
544+
| test byte OP:RX->result_type, (IS_TMP_VAR|IS_VAR)
546545
| jz >1
547-
| mov eax, dword OP:r0->result.var
546+
| mov eax, dword OP:RX->result.var
548547
| SET_Z_TYPE_INFO FP + r0, IS_UNDEF
549548
|1:
550549
|.endmacro
@@ -1788,6 +1787,42 @@ static int zend_jit_exception_handler_undef_stub(dasm_State **Dst)
17881787
return 1;
17891788
}
17901789

1790+
1791+
static int zend_jit_exception_handler_free_op1_op2_stub(dasm_State **Dst)
1792+
{
1793+
|->exception_handler_free_op1_op2:
1794+
| UNDEF_OPLINE_RESULT_IF_USED
1795+
| test byte OP:RX->op1_type, (IS_TMP_VAR|IS_VAR)
1796+
| je >9
1797+
| mov eax, dword OP:RX->op1.var
1798+
| add r0, FP
1799+
| ZVAL_PTR_DTOR ZEND_ADDR_MEM_ZVAL(ZREG_R0, 0), MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN|MAY_BE_REF, 0, 0, NULL
1800+
|9:
1801+
| test byte OP:RX->op2_type, (IS_TMP_VAR|IS_VAR)
1802+
| je >9
1803+
| mov eax, dword OP:RX->op2.var
1804+
| add r0, FP
1805+
| ZVAL_PTR_DTOR ZEND_ADDR_MEM_ZVAL(ZREG_R0, 0), MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN|MAY_BE_REF, 0, 0, NULL
1806+
|9:
1807+
| jmp ->exception_handler
1808+
return 1;
1809+
}
1810+
1811+
static int zend_jit_exception_handler_free_op2_stub(dasm_State **Dst)
1812+
{
1813+
|->exception_handler_free_op2:
1814+
| MEM_LOAD_ZTS RX, aword, executor_globals, opline_before_exception, r0
1815+
| UNDEF_OPLINE_RESULT_IF_USED
1816+
| test byte OP:RX->op2_type, (IS_TMP_VAR|IS_VAR)
1817+
| je >9
1818+
| mov eax, dword OP:RX->op2.var
1819+
| add r0, FP
1820+
| ZVAL_PTR_DTOR ZEND_ADDR_MEM_ZVAL(ZREG_R0, 0), MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN|MAY_BE_REF, 0, 0, NULL
1821+
|9:
1822+
| jmp ->exception_handler
1823+
return 1;
1824+
}
1825+
17911826
static int zend_jit_leave_function_stub(dasm_State **Dst)
17921827
{
17931828
|->leave_function_handler:
@@ -2102,7 +2137,6 @@ static int zend_jit_negative_shift_stub(dasm_State **Dst)
21022137
{
21032138
|->negative_shift:
21042139
| mov RX, EX->opline
2105-
| UNDEF_OPLINE_RESULT_IF_USED
21062140
|.if X64
21072141
|.if WIN
21082142
| LOAD_ADDR CARG1, &zend_ce_arithmetic_error
@@ -2124,27 +2158,14 @@ static int zend_jit_negative_shift_stub(dasm_State **Dst)
21242158
| EXT_CALL zend_throw_error, r0
21252159
| add r4, 16
21262160
|.endif
2127-
| test byte OP:RX->op1_type, (IS_TMP_VAR|IS_VAR)
2128-
| je >9
2129-
| mov eax, dword OP:RX->op1.var
2130-
| add r0, FP
2131-
| ZVAL_PTR_DTOR ZEND_ADDR_MEM_ZVAL(ZREG_R0, 0), MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN|MAY_BE_REF, 0, 0, NULL
2132-
|9:
2133-
| test byte OP:RX->op2_type, (IS_TMP_VAR|IS_VAR)
2134-
| je >9
2135-
| mov eax, dword OP:RX->op2.var
2136-
| add r0, FP
2137-
| ZVAL_PTR_DTOR ZEND_ADDR_MEM_ZVAL(ZREG_R0, 0), MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN|MAY_BE_REF, 0, 0, NULL
2138-
|9:
2139-
| jmp ->exception_handler
2161+
| jmp ->exception_handler_free_op1_op2
21402162
return 1;
21412163
}
21422164

21432165
static int zend_jit_mod_by_zero_stub(dasm_State **Dst)
21442166
{
21452167
|->mod_by_zero:
21462168
| mov RX, EX->opline
2147-
| UNDEF_OPLINE_RESULT_IF_USED
21482169
|.if X64
21492170
|.if WIN
21502171
| LOAD_ADDR CARG1, &zend_ce_division_by_zero_error
@@ -2166,19 +2187,7 @@ static int zend_jit_mod_by_zero_stub(dasm_State **Dst)
21662187
| EXT_CALL zend_throw_error, r0
21672188
| add r4, 16
21682189
|.endif
2169-
| test byte OP:RX->op1_type, (IS_TMP_VAR|IS_VAR)
2170-
| je >9
2171-
| mov eax, dword OP:RX->op1.var
2172-
| add r0, FP
2173-
| ZVAL_PTR_DTOR ZEND_ADDR_MEM_ZVAL(ZREG_R0, 0), MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN|MAY_BE_REF, 0, 0, NULL
2174-
|9:
2175-
| test byte OP:RX->op2_type, (IS_TMP_VAR|IS_VAR)
2176-
| je >9
2177-
| mov eax, dword OP:RX->op2.var
2178-
| add r0, FP
2179-
| ZVAL_PTR_DTOR ZEND_ADDR_MEM_ZVAL(ZREG_R0, 0), MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN|MAY_BE_REF, 0, 0, NULL
2180-
|9:
2181-
| jmp ->exception_handler
2190+
| jmp ->exception_handler_free_op1_op2
21822191
return 1;
21832192
}
21842193

@@ -2788,6 +2797,8 @@ static const zend_jit_stub zend_jit_stubs[] = {
27882797
JIT_STUB(interrupt_handler, SP_ADJ_JIT, SP_ADJ_VM),
27892798
JIT_STUB(exception_handler, SP_ADJ_JIT, SP_ADJ_VM),
27902799
JIT_STUB(exception_handler_undef, SP_ADJ_JIT, SP_ADJ_VM),
2800+
JIT_STUB(exception_handler_free_op1_op2, SP_ADJ_JIT, SP_ADJ_VM),
2801+
JIT_STUB(exception_handler_free_op2, SP_ADJ_JIT, SP_ADJ_VM),
27912802
JIT_STUB(leave_function, SP_ADJ_JIT, SP_ADJ_VM),
27922803
JIT_STUB(leave_throw, SP_ADJ_JIT, SP_ADJ_VM),
27932804
JIT_STUB(icall_throw, SP_ADJ_JIT, SP_ADJ_VM),
@@ -5316,7 +5327,10 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
53165327
| FREE_OP op1_type, op1, op1_info, 0, NULL
53175328
| FREE_OP op2_type, op2, op2_info, 0, NULL
53185329
if (may_throw) {
5319-
if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_RX) {
5330+
if (opline->opcode == ZEND_ASSIGN_DIM_OP && (opline->op2_type & (IS_VAR|IS_TMP_VAR))) {
5331+
| MEM_CMP_ZTS aword, executor_globals, exception, 0, r0
5332+
| jne ->exception_handler_free_op2
5333+
} else if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_RX) {
53205334
zend_jit_check_exception_undef_result(Dst, opline);
53215335
} else {
53225336
zend_jit_check_exception(Dst);

ext/opcache/tests/jit/mod_004.phpt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
JIT MOD: 004
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.file_update_protection=0
7+
opcache.jit_buffer_size=1M
8+
opcache.protect_memory=1
9+
--FILE--
10+
<?php
11+
$a = [];
12+
$b = "";
13+
$a["x{$b}y"] %= 0;
14+
?>
15+
--EXPECTF--
16+
Warning: Undefined array key "xy" in %smod_004.php on line 4
17+
18+
Fatal error: Uncaught DivisionByZeroError: Modulo by zero in %smod_004.php:4
19+
Stack trace:
20+
#0 {main}
21+
thrown in %smod_004.php on line 4

0 commit comments

Comments
 (0)