Skip to content

Commit 4bf4c24

Browse files
cjekerdevnexen
authored andcommitted
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 phpGH-13382.
1 parent a04577f commit 4bf4c24

File tree

4 files changed

+120
-0
lines changed

4 files changed

+120
-0
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ PHP NEWS
1616
. Added support for Zend Max Execution Timers on FreeBSD. (Kévin Dunglas)
1717
. Ensure fiber stack is not backed by THP. (crrodriguez)
1818
. Implement GH-13609 (Dump wrapped object in WeakReference class). (nielsdos)
19+
. Added sparc64 arch assembly support for zend fiber. (Claudio Jeker)
1920

2021
- Curl:
2122
. Deprecated the CURLOPT_BINARYTRANSFER constant. (divinity76)

Zend/asm/jump_sparc64_sysv_elf_gas.S

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
Copyright Claudio Jeker 2024
3+
Distributed under the Boost Software License, Version 1.0.
4+
(See accompanying file LICENSE_1_0.txt or copy at
5+
http://www.boost.org/LICENSE_1_0.txt)
6+
*/
7+
8+
/*
9+
* typedef struct {
10+
* void *handle;
11+
* zend_fiber_transfer *transfer;
12+
* } boost_context_data;
13+
*
14+
* boost_context_data jump_fcontext(void *to, zend_fiber_transfer *transfer);
15+
*/
16+
#define CC64FSZ 176
17+
#define BIAS 2047
18+
#define SP 128
19+
#define I7 136
20+
21+
.file "jump_sparc64_sysv_elf_gas.S"
22+
.text
23+
.align 4
24+
.global jump_fcontext
25+
.type jump_fcontext, %function
26+
jump_fcontext:
27+
# prepare stack
28+
save %sp, -CC64FSZ, %sp
29+
30+
# store framepointer and return address in slots reserved
31+
# for arguments
32+
stx %fp, [%sp + BIAS + SP]
33+
stx %i7, [%sp + BIAS + I7]
34+
mov %sp, %o0
35+
# force flush register windows to stack and with that save context
36+
flushw
37+
# get SP (pointing to new context-data) from %i0 param
38+
mov %i0, %sp
39+
# load framepointer and return address from context
40+
ldx [%sp + BIAS + SP], %fp
41+
ldx [%sp + BIAS + I7], %i7
42+
43+
ret
44+
restore %o0, %g0, %o0
45+
# restore old %sp (pointing to old context-data) in %o0
46+
# *data stored in %o1 was not modified
47+
.size jump_fcontext,.-jump_fcontext
48+
# Mark that we don't need executable stack.
49+
.section .note.GNU-stack,"",%progbits

Zend/asm/make_sparc64_sysv_elf_gas.S

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
Copyright Claudio Jeker 2024
3+
Distributed under the Boost Software License, Version 1.0.
4+
(See accompanying file LICENSE_1_0.txt or copy at
5+
http://www.boost.org/LICENSE_1_0.txt)
6+
*/
7+
8+
/*
9+
* void *make_fcontext(void *sp, size_t size, void (*fn)(boost_context_data));
10+
*/
11+
#define CC64FSZ 176
12+
#define BIAS 2047
13+
#define FP 112
14+
#define SP 128
15+
#define I7 136
16+
17+
.file "make_sparc64_sysv_elf_gas.S"
18+
.text
19+
.align 4
20+
.global make_fcontext
21+
.type make_fcontext, %function
22+
make_fcontext:
23+
save %sp, -CC64FSZ, %sp
24+
25+
# shift address in %i0 (allocated stack) to lower 16 byte boundary
26+
and %i0, -0xf, %i0
27+
28+
# reserve space for two frames on the stack
29+
# the first frame is for the call the second one holds the data
30+
# for jump_fcontext
31+
sub %i0, 2 * CC64FSZ, %i0
32+
33+
# third argument of make_fcontext() is the context-function to call
34+
# store it in the first stack frame, also clear %fp there to indicate
35+
# the end of the stack.
36+
stx %i2, [%i0 + CC64FSZ + I7]
37+
stx %g0, [%i0 + CC64FSZ + FP]
38+
39+
# On OpenBSD stackghost prevents overriding the return address on
40+
# a stack frame. So this code uses an extra trampoline to load
41+
# to call the context-function and then do the _exit(0) dance.
42+
# Extract the full address of the trampoline via pc relative addressing
43+
1:
44+
rd %pc, %l0
45+
add %l0, (trampoline - 1b - 8), %l0
46+
stx %l0, [%i0 + I7]
47+
48+
# Save framepointer to first stack frame but first substract the BIAS
49+
add %i0, CC64FSZ - BIAS, %l0
50+
stx %l0, [%i0 + SP]
51+
52+
# Return context-data which is also includes the BIAS
53+
ret
54+
restore %i0, -BIAS, %o0
55+
56+
trampoline:
57+
ldx [%sp + BIAS + I7], %l0
58+
59+
# no need to setup boost_context_data, already in %o0 and %o1
60+
jmpl %l0, %o7
61+
nop
62+
63+
call _exit
64+
clr %o0
65+
unimp
66+
.size make_fcontext,.-make_fcontext
67+
# Mark that we don't need executable stack.
68+
.section .note.GNU-stack,"",%progbits

configure.ac

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,6 +1257,7 @@ AS_CASE([$host_cpu],
12571257
[ppc64*|powerpc64*], [fiber_cpu="ppc64"],
12581258
[ppc*|powerpc*], [fiber_cpu="ppc32"],
12591259
[riscv64*], [fiber_cpu="riscv64"],
1260+
[sparc64], [fiber_cpu="sparc64"],
12601261
[s390x*], [fiber_cpu="s390x"],
12611262
[mips64*], [fiber_cpu="mips64"],
12621263
[mips*], [fiber_cpu="mips32"],
@@ -1278,6 +1279,7 @@ AS_CASE([$fiber_cpu],
12781279
[ppc64], [fiber_asm_file_prefix="ppc64_sysv"],
12791280
[ppc32], [fiber_asm_file_prefix="ppc32_sysv"],
12801281
[riscv64], [fiber_asm_file_prefix="riscv64_sysv"],
1282+
[sparc64], [fiber_asm_file_prefix="sparc64_sysv"],
12811283
[s390x], [fiber_asm_file_prefix="s390x_sysv"],
12821284
[mips64], [fiber_asm_file_prefix="mips64_n64"],
12831285
[mips32], [fiber_asm_file_prefix="mips32_o32"],

0 commit comments

Comments
 (0)