Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement the fcontext asm for sparc64 #251

Merged
merged 1 commit into from
Mar 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions build/Jamfile.v2
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,30 @@ alias asm_sources
<toolset>gcc
;

# SPARC64
# SPARC64/SYSV/ELF
alias asm_sources
: asm/make_sparc64_sysv_elf_gas.S
asm/jump_sparc64_sysv_elf_gas.S
asm/ontop_sparc64_sysv_elf_gas.S
: <abi>sysv
<address-model>64
<architecture>sparc
<binary-format>elf
<toolset>clang
;

alias asm_sources
: asm/make_sparc64_sysv_elf_gas.S
asm/jump_sparc64_sysv_elf_gas.S
asm/ontop_sparc64_sysv_elf_gas.S
: <abi>sysv
<address-model>64
<architecture>sparc
<binary-format>elf
<toolset>gcc
;

# S390X
# S390X/SYSV/ELF
alias asm_sources
Expand Down
51 changes: 51 additions & 0 deletions src/asm/jump_sparc64_sysv_elf_gas.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
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 void* fcontext_t;
*
* struct transfer_t {
* fcontext_t fctx;
* void * data;
* };
*
* transfer_t jump_fcontext(fcontext_t const to, void *vp);
*/
#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
68 changes: 68 additions & 0 deletions src/asm/make_sparc64_sysv_elf_gas.S
Original file line number Diff line number Diff line change
@@ -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)
*/

/*
* fcontext_t *make_fcontext(void *sp, size_t size, void (*fn)(transfer_t));
*/
#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 transfer_t, 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
50 changes: 50 additions & 0 deletions src/asm/ontop_sparc64_sysv_elf_gas.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
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)
*/

/*
* transfer_t ontop_fcontext(fcontext_t const to, void *vp, transfer_t (*fn)(transfer_t));
*/
#define CC64FSZ 176
#define BIAS 2047
#define SP 128
#define I7 136

.file "ontop_sparc64_sysv_elf_gas.S"
.text
.align 4
.global ontop_fcontext
.type ontop_fcontext, %function
ontop_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

# ontop_fcontext requires to directly call a function on top of the
# current frame so restore register window before doing the jump
# to the context function which then is in %o2. Do not clobber
# %o7 in the jump so that (*fn)() returns to that address.
restore %o0, %g0, %o0
# restore old %sp (pointing to old context-data) in %o0
# *data stored in %o1 was not modified

jmpl %o2, %g0
nop
.size jump_fcontext,.-jump_fcontext
# Mark that we don't need executable stack.
.section .note.GNU-stack,"",%progbits
Loading