Implement fcontext handling for sparc64_sysv_elf.

This was tested on OpenBSD sparc64 and all fiber related tests pass.
On OpenBSD stackghost prevents the modification of the return address
and therefor an extra trampoline is needed in make_fcontext(). This
should not matter on other OS implementing sysv ABI and the trampoline
should work there as well.

Close GH-13382.
This commit is contained in:
Claudio Jeker 2024-02-13 10:37:20 +01:00 committed by David Carlier
parent a04577fb4a
commit 4bf4c24aa8
4 changed files with 120 additions and 0 deletions

1
NEWS
View file

@ -16,6 +16,7 @@ PHP NEWS
. Added support for Zend Max Execution Timers on FreeBSD. (Kévin Dunglas)
. Ensure fiber stack is not backed by THP. (crrodriguez)
. Implement GH-13609 (Dump wrapped object in WeakReference class). (nielsdos)
. Added sparc64 arch assembly support for zend fiber. (Claudio Jeker)
- Curl:
. Deprecated the CURLOPT_BINARYTRANSFER constant. (divinity76)

View file

@ -0,0 +1,49 @@
/*
Copyright Claudio Jeker 2024
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
/*
* typedef struct {
* void *handle;
* zend_fiber_transfer *transfer;
* } boost_context_data;
*
* boost_context_data jump_fcontext(void *to, zend_fiber_transfer *transfer);
*/
#define CC64FSZ 176
#define BIAS 2047
#define SP 128
#define I7 136
.file "jump_sparc64_sysv_elf_gas.S"
.text
.align 4
.global jump_fcontext
.type jump_fcontext, %function
jump_fcontext:
# prepare stack
save %sp, -CC64FSZ, %sp
# store framepointer and return address in slots reserved
# for arguments
stx %fp, [%sp + BIAS + SP]
stx %i7, [%sp + BIAS + I7]
mov %sp, %o0
# force flush register windows to stack and with that save context
flushw
# get SP (pointing to new context-data) from %i0 param
mov %i0, %sp
# load framepointer and return address from context
ldx [%sp + BIAS + SP], %fp
ldx [%sp + BIAS + I7], %i7
ret
restore %o0, %g0, %o0
# restore old %sp (pointing to old context-data) in %o0
# *data stored in %o1 was not modified
.size jump_fcontext,.-jump_fcontext
# Mark that we don't need executable stack.
.section .note.GNU-stack,"",%progbits

View file

@ -0,0 +1,68 @@
/*
Copyright Claudio Jeker 2024
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
/*
* void *make_fcontext(void *sp, size_t size, void (*fn)(boost_context_data));
*/
#define CC64FSZ 176
#define BIAS 2047
#define FP 112
#define SP 128
#define I7 136
.file "make_sparc64_sysv_elf_gas.S"
.text
.align 4
.global make_fcontext
.type make_fcontext, %function
make_fcontext:
save %sp, -CC64FSZ, %sp
# shift address in %i0 (allocated stack) to lower 16 byte boundary
and %i0, -0xf, %i0
# reserve space for two frames on the stack
# the first frame is for the call the second one holds the data
# for jump_fcontext
sub %i0, 2 * CC64FSZ, %i0
# third argument of make_fcontext() is the context-function to call
# store it in the first stack frame, also clear %fp there to indicate
# the end of the stack.
stx %i2, [%i0 + CC64FSZ + I7]
stx %g0, [%i0 + CC64FSZ + FP]
# On OpenBSD stackghost prevents overriding the return address on
# a stack frame. So this code uses an extra trampoline to load
# to call the context-function and then do the _exit(0) dance.
# Extract the full address of the trampoline via pc relative addressing
1:
rd %pc, %l0
add %l0, (trampoline - 1b - 8), %l0
stx %l0, [%i0 + I7]
# Save framepointer to first stack frame but first substract the BIAS
add %i0, CC64FSZ - BIAS, %l0
stx %l0, [%i0 + SP]
# Return context-data which is also includes the BIAS
ret
restore %i0, -BIAS, %o0
trampoline:
ldx [%sp + BIAS + I7], %l0
# no need to setup boost_context_data, already in %o0 and %o1
jmpl %l0, %o7
nop
call _exit
clr %o0
unimp
.size make_fcontext,.-make_fcontext
# Mark that we don't need executable stack.
.section .note.GNU-stack,"",%progbits

View file

@ -1257,6 +1257,7 @@ AS_CASE([$host_cpu],
[ppc64*|powerpc64*], [fiber_cpu="ppc64"],
[ppc*|powerpc*], [fiber_cpu="ppc32"],
[riscv64*], [fiber_cpu="riscv64"],
[sparc64], [fiber_cpu="sparc64"],
[s390x*], [fiber_cpu="s390x"],
[mips64*], [fiber_cpu="mips64"],
[mips*], [fiber_cpu="mips32"],
@ -1278,6 +1279,7 @@ AS_CASE([$fiber_cpu],
[ppc64], [fiber_asm_file_prefix="ppc64_sysv"],
[ppc32], [fiber_asm_file_prefix="ppc32_sysv"],
[riscv64], [fiber_asm_file_prefix="riscv64_sysv"],
[sparc64], [fiber_asm_file_prefix="sparc64_sysv"],
[s390x], [fiber_asm_file_prefix="s390x_sysv"],
[mips64], [fiber_asm_file_prefix="mips64_n64"],
[mips32], [fiber_asm_file_prefix="mips32_o32"],