Skip to content

Commit d9bea79

Browse files
authored
Merge pull request #251 from cjeker/sparc64_asm_support
Implement the fcontext asm for sparc64
2 parents 99be0a6 + 17945a2 commit d9bea79

File tree

4 files changed

+193
-0
lines changed

4 files changed

+193
-0
lines changed

build/Jamfile.v2

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,30 @@ alias asm_sources
519519
<toolset>gcc
520520
;
521521

522+
# SPARC64
523+
# SPARC64/SYSV/ELF
524+
alias asm_sources
525+
: asm/make_sparc64_sysv_elf_gas.S
526+
asm/jump_sparc64_sysv_elf_gas.S
527+
asm/ontop_sparc64_sysv_elf_gas.S
528+
: <abi>sysv
529+
<address-model>64
530+
<architecture>sparc
531+
<binary-format>elf
532+
<toolset>clang
533+
;
534+
535+
alias asm_sources
536+
: asm/make_sparc64_sysv_elf_gas.S
537+
asm/jump_sparc64_sysv_elf_gas.S
538+
asm/ontop_sparc64_sysv_elf_gas.S
539+
: <abi>sysv
540+
<address-model>64
541+
<architecture>sparc
542+
<binary-format>elf
543+
<toolset>gcc
544+
;
545+
522546
# S390X
523547
# S390X/SYSV/ELF
524548
alias asm_sources

src/asm/jump_sparc64_sysv_elf_gas.S

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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 void* fcontext_t;
10+
*
11+
* struct transfer_t {
12+
* fcontext_t fctx;
13+
* void * data;
14+
* };
15+
*
16+
* transfer_t jump_fcontext(fcontext_t const to, void *vp);
17+
*/
18+
#define CC64FSZ 176
19+
#define BIAS 2047
20+
#define SP 128
21+
#define I7 136
22+
23+
.file "jump_sparc64_sysv_elf_gas.S"
24+
.text
25+
.align 4
26+
.global jump_fcontext
27+
.type jump_fcontext, %function
28+
jump_fcontext:
29+
# prepare stack
30+
save %sp, -CC64FSZ, %sp
31+
32+
# store framepointer and return address in slots reserved
33+
# for arguments
34+
stx %fp, [%sp + BIAS + SP]
35+
stx %i7, [%sp + BIAS + I7]
36+
mov %sp, %o0
37+
# force flush register windows to stack and with that save context
38+
flushw
39+
# get SP (pointing to new context-data) from %i0 param
40+
mov %i0, %sp
41+
# load framepointer and return address from context
42+
ldx [%sp + BIAS + SP], %fp
43+
ldx [%sp + BIAS + I7], %i7
44+
45+
ret
46+
restore %o0, %g0, %o0
47+
# restore old %sp (pointing to old context-data) in %o0
48+
# *data stored in %o1 was not modified
49+
.size jump_fcontext,.-jump_fcontext
50+
# Mark that we don't need executable stack.
51+
.section .note.GNU-stack,"",%progbits

src/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+
* fcontext_t *make_fcontext(void *sp, size_t size, void (*fn)(transfer_t));
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 transfer_t, 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

src/asm/ontop_sparc64_sysv_elf_gas.S

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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+
* transfer_t ontop_fcontext(fcontext_t const to, void *vp, transfer_t (*fn)(transfer_t));
10+
*/
11+
#define CC64FSZ 176
12+
#define BIAS 2047
13+
#define SP 128
14+
#define I7 136
15+
16+
.file "ontop_sparc64_sysv_elf_gas.S"
17+
.text
18+
.align 4
19+
.global ontop_fcontext
20+
.type ontop_fcontext, %function
21+
ontop_fcontext:
22+
# prepare stack
23+
save %sp, -CC64FSZ, %sp
24+
25+
# store framepointer and return address in slots reserved
26+
# for arguments
27+
stx %fp, [%sp + BIAS + SP]
28+
stx %i7, [%sp + BIAS + I7]
29+
mov %sp, %o0
30+
# force flush register windows to stack and with that save context
31+
flushw
32+
# get SP (pointing to new context-data) from %i0 param
33+
mov %i0, %sp
34+
# load framepointer and return address from context
35+
ldx [%sp + BIAS + SP], %fp
36+
ldx [%sp + BIAS + I7], %i7
37+
38+
# ontop_fcontext requires to directly call a function on top of the
39+
# current frame so restore register window before doing the jump
40+
# to the context function which then is in %o2. Do not clobber
41+
# %o7 in the jump so that (*fn)() returns to that address.
42+
restore %o0, %g0, %o0
43+
# restore old %sp (pointing to old context-data) in %o0
44+
# *data stored in %o1 was not modified
45+
46+
jmpl %o2, %g0
47+
nop
48+
.size jump_fcontext,.-jump_fcontext
49+
# Mark that we don't need executable stack.
50+
.section .note.GNU-stack,"",%progbits

0 commit comments

Comments
 (0)