Skip to content

Commit 806d2e0

Browse files
committed
Backport GH-16348
Agreed by RM: #16168 (comment) The inline assembly uses labels with the prefix `.L`. On Linux systems this is the local label prefix. It appears that macOS uses `L` as a local prefix, which means that the prefix used in the inline assembly is not local for macOS systems [1]. When combined with inlining, this causes the compiler to get confused and merge a part of the inline assembly between different functions, causing control flow to jump from one function to another function. This is avoided on PHP 8.2 and up by the fact that it uses `zend_never_inline NOIPA`, but nothing guarantees that compiler changes won't affect this as well. To solve this issue, we instead use local labels. These will make the compiler pick the correct prefix, preventing the issue. Additionally, while here, we also change the computation of `delta`. It is undefined behaviour to compute the pointer difference between two different objects. To circumvent this, we cast first to `uintptr_t`. This change is cleanly backportable to 8.1 for vendors to pick up. [1] #16168 (comment) With the help of investigation and testing of @ryandesign. Closes GH-16348.
1 parent b0b39cd commit 806d2e0

File tree

1 file changed

+22
-22
lines changed

1 file changed

+22
-22
lines changed

Zend/zend_string.c

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -397,33 +397,33 @@ ZEND_API bool ZEND_FASTCALL NO_CALLER_SAVED_REGISTERS I_REPLACE_SONAME_FNNAME_ZU
397397
#if defined(__GNUC__) && defined(__i386__)
398398
ZEND_API bool ZEND_FASTCALL zend_string_equal_val(zend_string *s1, zend_string *s2)
399399
{
400-
char *ptr = ZSTR_VAL(s1);
401-
size_t delta = (char*)s2 - (char*)s1;
400+
const char *ptr = ZSTR_VAL(s1);
401+
uintptr_t delta = (uintptr_t) s2 - (uintptr_t) s1;
402402
size_t len = ZSTR_LEN(s1);
403403
zend_ulong ret;
404404

405405
__asm__ (
406-
".LL0%=:\n\t"
406+
"0:\n\t"
407407
"movl (%2,%3), %0\n\t"
408408
"xorl (%2), %0\n\t"
409-
"jne .LL1%=\n\t"
409+
"jne 1f\n\t"
410410
"addl $0x4, %2\n\t"
411411
"subl $0x4, %1\n\t"
412-
"ja .LL0%=\n\t"
412+
"ja 0b\n\t"
413413
"movl $0x1, %0\n\t"
414-
"jmp .LL3%=\n\t"
415-
".LL1%=:\n\t"
414+
"jmp 3f\n\t"
415+
"1:\n\t"
416416
"cmpl $0x4,%1\n\t"
417-
"jb .LL2%=\n\t"
417+
"jb 2f\n\t"
418418
"xorl %0, %0\n\t"
419-
"jmp .LL3%=\n\t"
420-
".LL2%=:\n\t"
419+
"jmp 3f\n\t"
420+
"2:\n\t"
421421
"negl %1\n\t"
422422
"lea 0x20(,%1,8), %1\n\t"
423423
"shll %b1, %0\n\t"
424424
"sete %b0\n\t"
425425
"movzbl %b0, %0\n\t"
426-
".LL3%=:\n"
426+
"3:\n"
427427
: "=&a"(ret),
428428
"+c"(len),
429429
"+r"(ptr)
@@ -435,33 +435,33 @@ ZEND_API bool ZEND_FASTCALL zend_string_equal_val(zend_string *s1, zend_string *
435435
#elif defined(__GNUC__) && defined(__x86_64__) && !defined(__ILP32__)
436436
ZEND_API bool ZEND_FASTCALL zend_string_equal_val(zend_string *s1, zend_string *s2)
437437
{
438-
char *ptr = ZSTR_VAL(s1);
439-
size_t delta = (char*)s2 - (char*)s1;
438+
const char *ptr = ZSTR_VAL(s1);
439+
uintptr_t delta = (uintptr_t) s2 - (uintptr_t) s1;
440440
size_t len = ZSTR_LEN(s1);
441441
zend_ulong ret;
442442

443443
__asm__ (
444-
".LL0%=:\n\t"
444+
"0:\n\t"
445445
"movq (%2,%3), %0\n\t"
446446
"xorq (%2), %0\n\t"
447-
"jne .LL1%=\n\t"
447+
"jne 1f\n\t"
448448
"addq $0x8, %2\n\t"
449449
"subq $0x8, %1\n\t"
450-
"ja .LL0%=\n\t"
450+
"ja 0b\n\t"
451451
"movq $0x1, %0\n\t"
452-
"jmp .LL3%=\n\t"
453-
".LL1%=:\n\t"
452+
"jmp 3f\n\t"
453+
"1:\n\t"
454454
"cmpq $0x8,%1\n\t"
455-
"jb .LL2%=\n\t"
455+
"jb 2f\n\t"
456456
"xorq %0, %0\n\t"
457-
"jmp .LL3%=\n\t"
458-
".LL2%=:\n\t"
457+
"jmp 3f\n\t"
458+
"2:\n\t"
459459
"negq %1\n\t"
460460
"lea 0x40(,%1,8), %1\n\t"
461461
"shlq %b1, %0\n\t"
462462
"sete %b0\n\t"
463463
"movzbq %b0, %0\n\t"
464-
".LL3%=:\n"
464+
"3:\n"
465465
: "=&a"(ret),
466466
"+c"(len),
467467
"+r"(ptr)

0 commit comments

Comments
 (0)