Skip to content

Commit 41335c4

Browse files
committed
Support platforms in which user space addresses may have the higher bit set
1 parent 3ce2089 commit 41335c4

File tree

4 files changed

+34
-7
lines changed

4 files changed

+34
-7
lines changed

Zend/zend_portability.h

+8
Original file line numberDiff line numberDiff line change
@@ -879,4 +879,12 @@ static zend_always_inline uint64_t ZEND_BYTES_SWAP64(uint64_t u)
879879
# define UINTPTR_WIDTH (CHAR_BITS * sizeof(uintptr_t))
880880
#endif
881881

882+
#if (defined(__linux__) && defined(__x86_64__)) \
883+
|| (defined(ZEND_WIN32) && defined(_M_AMD64))
884+
/* The kernel reserves the higher part of the address space for itself.
885+
* Therefore, we can assume that the higher bit of user space addresses is
886+
* never set. */
887+
# define ZEND_HIGH_HALF_KERNEL
888+
#endif
889+
882890
#endif /* ZEND_PORTABILITY_H */

Zend/zend_vm_gen.php

+17-5
Original file line numberDiff line numberDiff line change
@@ -1905,7 +1905,11 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
19051905
out($f,"# define ZEND_OPCODE_HANDLER_RET const zend_op *\n");
19061906
out($f,"# define ZEND_VM_TAIL_CALL(call) return call\n");
19071907
out($f,"# define ZEND_VM_CONTINUE() return opline\n");
1908-
out($f,"# define ZEND_VM_RETURN() return NULL\n");
1908+
out($f,"# ifdef ZEND_HIGH_HALF_KERNEL\n");
1909+
out($f,"# define ZEND_VM_RETURN() return NULL\n");
1910+
out($f,"# else\n");
1911+
out($f,"# define ZEND_VM_RETURN() return ZEND_VM_ENTER_BIT\n");
1912+
out($f,"# endif\n");
19091913
if ($kind == ZEND_VM_KIND_HYBRID) {
19101914
out($f,"# define ZEND_VM_HOT\n");
19111915
}
@@ -1944,7 +1948,11 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
19441948
out($f,"# define ZEND_VM_ENTER() opline = EG(current_execute_data)->opline; ZEND_VM_ENTER_EX()\n");
19451949
out($f,"# define ZEND_VM_LEAVE() return 2\n");
19461950
out($f,"#else\n");
1947-
out($f,"# define ZEND_VM_ENTER_BIT (1ULL<<(UINTPTR_WIDTH-1))\n");
1951+
out($f,"# ifdef ZEND_HIGH_HALF_KERNEL\n");
1952+
out($f,"# define ZEND_VM_ENTER_BIT (1ULL<<(UINTPTR_WIDTH-1))\n");
1953+
out($f,"# else\n");
1954+
out($f,"# define ZEND_VM_ENTER_BIT 1ULL\n");
1955+
out($f,"# endif\n");
19481956
out($f,"# define ZEND_VM_ENTER_EX() return (zend_op*)((uintptr_t)opline | ZEND_VM_ENTER_BIT)\n");
19491957
out($f,"# define ZEND_VM_ENTER() execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_ENTER_EX()\n");
19501958
out($f,"# define ZEND_VM_LEAVE() return (zend_op*)((uintptr_t)opline | ZEND_VM_ENTER_BIT)\n");
@@ -2147,7 +2155,11 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
21472155
out($f, $m[1]."if (UNEXPECTED(!OPLINE))".$m[3]."\n");
21482156
out($f,"#else\n");
21492157
out($f, $m[1]."opline = ((opcode_handler_t)opline->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
2150-
out($f, $m[1]."if (UNEXPECTED((intptr_t)OPLINE <= 0))".$m[3]."\n");
2158+
out($f, "# ifdef ZEND_HIGH_HALF_KERNEL\n");
2159+
out($f, $m[1]."if (UNEXPECTED((intptr_t)opline <= 0))".$m[3]."\n");
2160+
out($f, "# else\n");
2161+
out($f, $m[1]."if (UNEXPECTED(((uintptr_t)opline & ZEND_VM_ENTER_BIT)))".$m[3]."\n");
2162+
out($f, "# endif\n");
21512163
out($f,"#endif\n");
21522164
if ($kind == ZEND_VM_KIND_HYBRID) {
21532165
out($f,"#endif /* ZEND_VM_KIND != ZEND_VM_KIND_HYBRID */\n");
@@ -2176,8 +2188,8 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
21762188
"# endif\n" .
21772189
$m[1]."return;\n" .
21782190
"#else\n" .
2179-
$m[1]."if (EXPECTED(opline != NULL && (uintptr_t)opline != ZEND_VM_ENTER_BIT)) {\n" .
2180-
$m[1]."\topline = (zend_op*)((uintptr_t)opline & ~ZEND_VM_ENTER_BIT);\n".
2191+
$m[1]."opline = (const zend_op*)((uintptr_t)opline & ~ZEND_VM_ENTER_BIT);\n".
2192+
$m[1]."if (EXPECTED(opline != NULL)) {\n" .
21812193
$m[1]."\texecute_data = EG(current_execute_data);\n".
21822194
$m[1]."\tZEND_VM_LOOP_INTERRUPT_CHECK();\n".
21832195
$m[1]."} else {\n" .

ext/opcache/jit/zend_jit_internal.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ extern const zend_op *zend_jit_halt_op;
201201
return; \
202202
} while(0)
203203
# define ZEND_VM_ENTER_BIT 0
204+
# define ZEND_VM_RETURN_VAL 0
204205
#else
205206
# define EXECUTE_DATA_D zend_execute_data* execute_data
206207
# define EXECUTE_DATA_C execute_data
@@ -222,7 +223,13 @@ extern const zend_op *zend_jit_halt_op;
222223
# define ZEND_OPCODE_TAIL_CALL_EX(handler, arg) do { \
223224
return handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC arg); \
224225
} while(0)
225-
# define ZEND_VM_ENTER_BIT (1ULL<<(UINTPTR_WIDTH-1))
226+
# ifdef ZEND_HIGH_HALF_KERNEL
227+
# define ZEND_VM_ENTER_BIT (1ULL<<(UINTPTR_WIDTH-1))
228+
# define ZEND_VM_RETURN_VAL 0
229+
# else
230+
# define ZEND_VM_ENTER_BIT 1ULL
231+
# define ZEND_VM_RETURN_VAL ZEND_VM_ENTER_BIT
232+
# endif
226233
#endif
227234

228235
/* VM handlers */

ext/opcache/jit/zend_jit_ir.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -2401,7 +2401,7 @@ static int zend_jit_trace_halt_stub(zend_jit_ctx *jit)
24012401
jit_STORE_IP(jit, IR_NULL);
24022402
ir_RETURN(IR_VOID);
24032403
} else {
2404-
ir_RETURN(ir_CONST_ADDR(0)); // ZEND_VM_RETURN
2404+
ir_RETURN(ir_CONST_ADDR(ZEND_VM_RETURN_VAL)); // ZEND_VM_RETURN
24052405
}
24062406
return 1;
24072407
}

0 commit comments

Comments
 (0)