1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 11:08:11 +00:00

LibC: Implement setjmp and longjmp for riscv64

The assembly implementation is based on the x86_64 version.
This commit is contained in:
Sönke Holz 2024-01-14 11:47:37 +01:00 committed by Andrew Kaster
parent 5825eaa264
commit a504d76b14
2 changed files with 82 additions and 12 deletions

View file

@ -1,20 +1,91 @@
/*
* Copyright (c) 2024, Sönke Holz <sholz8530@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <bits/sighow.h>
//
// /!\ Read setjmp.h before modifying this file!
//
#define DID_SAVE_SIGNAL_MASK_SLOT (14 * 8)
#define SAVED_SIGNAL_MASK_SLOT (14 * 8 + 4)
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/setjmp.html
// int setjmp(jmp_buf env)
// int _setjmp(jmp_buf env)
.global _setjmp .global _setjmp
.global setjmp .global setjmp
_setjmp: _setjmp:
setjmp: setjmp:
# FIXME: Implement setjmp. li a1, 0 // Set savemask argument to 0
unimp
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigsetjmp.html
// int sigsetjmp(sigjmp_buf env, int savemask)
.global sigsetjmp
sigsetjmp:
sw a1, DID_SAVE_SIGNAL_MASK_SLOT(a0) // Store savemask into did_save_signal_mask
sw zero, SAVED_SIGNAL_MASK_SLOT(a0) // Clear saved_signal_mask
beqz a1, .Lsaveregs
addi sp, sp, -16 // Prepare ABI-compliant call to sigprocmask
sd a0, 0(sp)
sd ra, 8(sp)
li a0, 0 // Set argument how
li a1, 0 // Set argument set
addi a2, a0, SAVED_SIGNAL_MASK_SLOT // Set argument oldset
call sigprocmask@plt
ld ra, 8(sp)
ld a0, 0(sp)
addi sp, sp, 16
.Lsaveregs:
sd s0, 0*8(a0) // Save registers
sd s1, 1*8(a0)
sd s2, 2*8(a0)
sd s3, 3*8(a0)
sd s4, 4*8(a0)
sd s5, 5*8(a0)
sd s6, 6*8(a0)
sd s7, 7*8(a0)
sd s8, 8*8(a0)
sd s9, 9*8(a0)
sd s10, 10*8(a0)
sd s11, 11*8(a0)
sd sp, 12*8(a0)
sd ra, 13*8(a0)
li a0, 0
ret
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/longjmp.html
// void longjmp(jmp_buf env, int val)
// void _longjmp(jmp_buf env, int val)
.global _longjmp .global _longjmp
.global longjmp .global longjmp
_longjmp: _longjmp:
longjmp: longjmp:
# FIXME: Implement longjmp. ld s0, 0*8(a0) // Restore registers
unimp ld s1, 1*8(a0)
ld s2, 2*8(a0)
ld s3, 3*8(a0)
ld s4, 4*8(a0)
ld s5, 5*8(a0)
ld s6, 6*8(a0)
ld s7, 7*8(a0)
ld s8, 8*8(a0)
ld s9, 9*8(a0)
ld s10, 10*8(a0)
ld s11, 11*8(a0)
ld sp, 12*8(a0)
ld ra, 13*8(a0)
.global _sigsetjmp mv a0, a1
.global sigsetjmp bnez a0, .Lnonzero
_sigsetjmp: li a0, 1
sigsetjmp: .Lnonzero:
# FIXME: Implement sigsetjmp. ret
unimp

View file

@ -32,10 +32,9 @@ struct __jmp_buf {
// FIXME: This is likely incorrect. // FIXME: This is likely incorrect.
uint64_t regs[22]; uint64_t regs[22];
#elif defined(__riscv) && __riscv_xlen == 64 #elif defined(__riscv) && __riscv_xlen == 64
// FIXME: This is likely incorrect.
uint64_t s[12]; uint64_t s[12];
uint64_t sp; uint64_t sp;
uint64_t pc; uint64_t ra;
#else #else
# error "Unknown architecture" # error "Unknown architecture"
#endif #endif