forked from ariadne/libucontext
add mips64 implementation
parent
f3a873e6e6
commit
80a6ca3854
|
@ -0,0 +1,100 @@
|
|||
#ifndef __ARCH_MIPS64_DEFS_H
|
||||
#define __ARCH_MIPS64_DEFS_H
|
||||
|
||||
#define REG_SZ (8)
|
||||
|
||||
#define REG_R0 (0)
|
||||
#define REG_R1 (1)
|
||||
#define REG_R2 (2)
|
||||
#define REG_R3 (3)
|
||||
#define REG_R4 (4)
|
||||
#define REG_R5 (5)
|
||||
#define REG_R6 (6)
|
||||
#define REG_R7 (7)
|
||||
#define REG_R8 (8)
|
||||
#define REG_R9 (9)
|
||||
#define REG_R10 (10)
|
||||
#define REG_R11 (11)
|
||||
#define REG_R12 (12)
|
||||
#define REG_R13 (13)
|
||||
#define REG_R14 (14)
|
||||
#define REG_R15 (15)
|
||||
#define REG_R16 (16)
|
||||
#define REG_R17 (17)
|
||||
#define REG_R18 (18)
|
||||
#define REG_R19 (19)
|
||||
#define REG_R20 (20)
|
||||
#define REG_R21 (21)
|
||||
#define REG_R22 (22)
|
||||
#define REG_R23 (23)
|
||||
#define REG_R24 (24)
|
||||
#define REG_R25 (25)
|
||||
#define REG_R26 (26)
|
||||
#define REG_R27 (27)
|
||||
#define REG_R28 (28)
|
||||
#define REG_R29 (29)
|
||||
#define REG_R30 (30)
|
||||
#define REG_R31 (31)
|
||||
|
||||
/* $a0 is $4 */
|
||||
#define REG_A0 (4)
|
||||
|
||||
/* stack pointer is actually $29 */
|
||||
#define REG_SP (29)
|
||||
|
||||
/* frame pointer is actually $30 */
|
||||
#define REG_FP (30)
|
||||
|
||||
/* $s0 ($16) is used as link register */
|
||||
#define REG_LNK (16)
|
||||
|
||||
/* $t9 ($25) is used as entry */
|
||||
#define REG_ENTRY (25)
|
||||
|
||||
/* offset to mc_gregs in ucontext_t */
|
||||
#define MCONTEXT_GREGS (40)
|
||||
|
||||
/* offset to PC in ucontext_t */
|
||||
#define MCONTEXT_PC (MCONTEXT_GREGS + 576)
|
||||
|
||||
/* offset to uc_link in ucontext_t */
|
||||
#define UCONTEXT_UC_LINK (8)
|
||||
|
||||
/* offset to uc_stack.ss_sp in ucontext_t */
|
||||
#define UCONTEXT_STACK_PTR (16)
|
||||
|
||||
/* offset to uc_stack.ss_size in ucontext_t */
|
||||
#define UCONTEXT_STACK_SIZE (24)
|
||||
|
||||
/* setup frame, from MIPS N32/N64 calling convention manual */
|
||||
#define ALSZ 15
|
||||
#define ALMASK ~15
|
||||
#define FRAMESZ (((LOCALSZ * REG_SZ) + ALSZ) & ALMASK) // 16
|
||||
#define GPOFF (FRAMESZ - (LOCALSZ * REG_SZ)) // [16 - 16]
|
||||
|
||||
#define SETUP_FRAME(__proc) \
|
||||
.frame $sp, FRAMESZ, $ra; \
|
||||
.mask 0x10000000, 0; \
|
||||
.fmask 0x00000000, 0;
|
||||
|
||||
#define PUSH_FRAME(__proc) \
|
||||
daddiu $sp, -FRAMESZ; \
|
||||
.cpsetup $25, GPOFF, __proc;
|
||||
|
||||
#define POP_FRAME(__proc) \
|
||||
.cpreturn; \
|
||||
daddiu $sp, FRAMESZ
|
||||
|
||||
#define FUNC(__proc) \
|
||||
.globl __proc; \
|
||||
.align 2; \
|
||||
.type __proc, @function; \
|
||||
.ent __proc, 0; \
|
||||
__proc: \
|
||||
SETUP_FRAME(__proc)
|
||||
|
||||
#define END(__proc) \
|
||||
.end __proc; \
|
||||
.size __proc,.-__proc;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Ariadne Conill <ariadne@dereferenced.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* This software is provided 'as is' and without any warranty, express or
|
||||
* implied. In no event shall the authors be liable for any damages arising
|
||||
* from the use of this software.
|
||||
*/
|
||||
|
||||
LOCALSZ = 1
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
FUNC(__getcontext)
|
||||
/* copy $gp, $sp, $fp to temporary registers so we don't clobber them */
|
||||
move $a2, $gp
|
||||
move $a3, $sp
|
||||
move $a4, $fp
|
||||
|
||||
PUSH_FRAME(__getcontext)
|
||||
|
||||
/* set the magic flag */
|
||||
li $v0, 1
|
||||
sd $v0, ((0 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
|
||||
/* set registers */
|
||||
sd $s0, ((16 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
sd $s1, ((17 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
sd $s2, ((18 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
sd $s3, ((19 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
sd $s4, ((20 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
sd $s5, ((21 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
sd $s6, ((22 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
sd $s7, ((23 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
|
||||
sd $a2, ((28 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
sd $a3, ((29 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
sd $a4, ((30 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
sd $ra, ((31 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
sd $ra, (MCONTEXT_PC)($a0)
|
||||
|
||||
POP_FRAME(__getcontext)
|
||||
|
||||
jr $ra
|
||||
END(__getcontext)
|
||||
|
||||
.weak getcontext;
|
||||
getcontext = __getcontext;
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Ariadne Conill <ariadne@dereferenced.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* This software is provided 'as is' and without any warranty, express or
|
||||
* implied. In no event shall the authors be liable for any damages arising
|
||||
* from the use of this software.
|
||||
*/
|
||||
|
||||
/* $gp + 5 args */
|
||||
LOCALSZ = 6
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
A3_OFF = FRAMESZ - (5 * REG_SZ)
|
||||
A4_OFF = FRAMESZ - (4 * REG_SZ)
|
||||
A5_OFF = FRAMESZ - (3 * REG_SZ)
|
||||
A6_OFF = FRAMESZ - (2 * REG_SZ)
|
||||
A7_OFF = FRAMESZ - (1 * REG_SZ)
|
||||
|
||||
/*
|
||||
* Because we have to fiddle with $gp, we have to implement this in
|
||||
* assembly rather than C. Annoying, that...
|
||||
*/
|
||||
|
||||
FUNC(__makecontext)
|
||||
PUSH_FRAME(__makecontext)
|
||||
|
||||
/* store $a3 through $a7 to the stack frame. */
|
||||
sd $a3, A3_OFF($sp)
|
||||
sd $a4, A4_OFF($sp)
|
||||
sd $a5, A5_OFF($sp)
|
||||
sd $a6, A6_OFF($sp)
|
||||
sd $a7, A7_OFF($sp)
|
||||
|
||||
/* set $zero in the mcontext to 1. */
|
||||
li $v0, 1
|
||||
sd $v0, ((0 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
|
||||
/* ensure the stack is aligned on a quad-word boundary. */
|
||||
ld $t0, UCONTEXT_STACK_PTR($a0)
|
||||
ld $t2, UCONTEXT_STACK_SIZE($a0)
|
||||
daddiu $t1, $sp, A3_OFF
|
||||
daddu $t0, $t2
|
||||
and $t0, ALMASK
|
||||
blez $a2, no_more_arguments
|
||||
|
||||
/* store register arguments. */
|
||||
daddiu $t2, $a0, MCONTEXT_GREGS + (4 * REG_SZ)
|
||||
move $t3, $zero
|
||||
|
||||
store_register_arg:
|
||||
daddiu $t3, 1
|
||||
ld $v1, ($t1)
|
||||
daddiu $t1, REG_SZ
|
||||
sd $v1, ($t2)
|
||||
daddiu $t2, REG_SZ
|
||||
bgeu $t3, $a2, no_more_arguments
|
||||
bltu $t3, 8, store_register_arg
|
||||
|
||||
/* make room for stack arguments. */
|
||||
dsubu $t2, $a2, $t3
|
||||
dsll $t2, 3
|
||||
dsubu $t0, $t2
|
||||
and $t0, ALMASK
|
||||
|
||||
/* store stack arguments. */
|
||||
move $t2, $t0
|
||||
|
||||
store_stack_arg:
|
||||
daddiu $t3, 1
|
||||
ld $v1, ($t1)
|
||||
daddiu $t1, REG_SZ
|
||||
sd $v1, ($t2)
|
||||
daddiu $t2, REG_SZ
|
||||
bltu $t3, $a2, store_stack_arg
|
||||
|
||||
no_more_arguments:
|
||||
/* trampoline setup. */
|
||||
dla $t9, __start_context
|
||||
|
||||
/* copy link pointer as $s0... */
|
||||
ld $v1, UCONTEXT_UC_LINK($a0)
|
||||
sd $v1, ((16 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
|
||||
/* set our $sp */
|
||||
sd $t0, ((29 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
|
||||
/* $gp is copied as $s1 */
|
||||
sd $gp, ((17 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
|
||||
/* set our $ra */
|
||||
sd $t9, ((31 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
|
||||
/* set our $pc */
|
||||
sd $a1, MCONTEXT_PC($a0)
|
||||
|
||||
POP_FRAME(__makecontext)
|
||||
|
||||
jr $ra
|
||||
END(__makecontext)
|
||||
|
||||
|
||||
.weak makecontext
|
||||
makecontext = __makecontext;
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Ariadne Conill <ariadne@dereferenced.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* This software is provided 'as is' and without any warranty, express or
|
||||
* implied. In no event shall the authors be liable for any damages arising
|
||||
* from the use of this software.
|
||||
*/
|
||||
|
||||
LOCALSZ = 1
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
FUNC(__setcontext)
|
||||
PUSH_FRAME(__setcontext)
|
||||
|
||||
/* check for the magic flag. */
|
||||
li $v0, 1
|
||||
dla $v1, ((0 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
bne $v0, $v1, fail
|
||||
|
||||
/* move the context to $v0 */
|
||||
move $v0, $a0
|
||||
|
||||
/* load the registers */
|
||||
ld $a0, ((4 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $a1, ((5 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $a2, ((6 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $a3, ((7 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $a4, ((8 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $a5, ((9 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $a6, ((10 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $a7, ((11 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
|
||||
ld $s0, ((16 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $s1, ((17 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $s2, ((18 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $s3, ((19 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $s4, ((20 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $s5, ((21 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $s6, ((22 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $s7, ((23 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
|
||||
ld $gp, ((28 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $sp, ((29 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $fp, ((30 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $ra, ((31 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $t9, (MCONTEXT_PC)($v0)
|
||||
|
||||
move $v0, $zero
|
||||
jr $t9
|
||||
|
||||
fail:
|
||||
dla $t9, exit
|
||||
|
||||
POP_FRAME(__setcontext)
|
||||
|
||||
jalr $t9
|
||||
END(__setcontext)
|
||||
|
||||
.weak setcontext;
|
||||
setcontext = __setcontext;
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Ariadne Conill <ariadne@dereferenced.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* This software is provided 'as is' and without any warranty, express or
|
||||
* implied. In no event shall the authors be liable for any damages arising
|
||||
* from the use of this software.
|
||||
*/
|
||||
|
||||
LOCALSZ = 1
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
FUNC(__start_context)
|
||||
move $gp, $s1
|
||||
|
||||
/* we receive our initial ucontext in $s0, so if $s0 is nil, bail */
|
||||
beqz $s0, no_linked_context
|
||||
|
||||
/* call setcontext */
|
||||
move $a0, $s0
|
||||
dla $t9, __setcontext
|
||||
|
||||
jalr $t9
|
||||
|
||||
no_linked_context:
|
||||
move $a0, $zero
|
||||
dla $t9, exit
|
||||
jalr $t9
|
||||
nop
|
||||
END(__start_context)
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Ariadne Conill <ariadne@dereferenced.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* This software is provided 'as is' and without any warranty, express or
|
||||
* implied. In no event shall the authors be liable for any damages arising
|
||||
* from the use of this software.
|
||||
*/
|
||||
|
||||
LOCALSZ = 2
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
A1_OFFSET = FRAMESZ - (1 * REG_SZ)
|
||||
|
||||
FUNC(__swapcontext)
|
||||
/* copy $gp, $sp, $fp to temporary registers so we don't clobber them */
|
||||
move $a2, $gp
|
||||
move $a3, $sp
|
||||
move $a4, $fp
|
||||
|
||||
PUSH_FRAME(__swapcontext)
|
||||
|
||||
/* set the magic flag */
|
||||
li $v0, 1
|
||||
sd $v0, ((0 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
|
||||
/* set registers */
|
||||
sd $s0, ((16 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
sd $s1, ((17 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
sd $s2, ((18 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
sd $s3, ((19 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
sd $s4, ((20 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
sd $s5, ((21 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
sd $s6, ((22 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
sd $s7, ((23 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
|
||||
sd $a2, ((28 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
sd $a3, ((29 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
sd $a4, ((30 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
sd $ra, ((31 * REG_SZ) + MCONTEXT_GREGS)($a0)
|
||||
sd $ra, (MCONTEXT_PC)($a0)
|
||||
|
||||
/* copy new context address in $a1 to stack */
|
||||
sd $a1, A1_OFFSET($sp)
|
||||
|
||||
/* load new context address into $v0 */
|
||||
ld $v0, A1_OFFSET($sp)
|
||||
|
||||
/* load the registers */
|
||||
ld $a0, ((4 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $a1, ((5 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $a2, ((6 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $a3, ((7 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $a4, ((8 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $a5, ((9 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $a6, ((10 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $a7, ((11 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
|
||||
ld $s0, ((16 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $s1, ((17 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $s2, ((18 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $s3, ((19 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $s4, ((20 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $s5, ((21 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $s6, ((22 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $s7, ((23 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
|
||||
ld $gp, ((28 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $sp, ((29 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $fp, ((30 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $ra, ((31 * REG_SZ) + MCONTEXT_GREGS)($v0)
|
||||
ld $t9, (MCONTEXT_PC)($v0)
|
||||
|
||||
move $v0, $zero
|
||||
jr $t9
|
||||
|
||||
fail:
|
||||
dla $t9, exit
|
||||
|
||||
POP_FRAME(__swapcontext)
|
||||
|
||||
move $v0, $zero
|
||||
jalr $t9
|
||||
END(__swapcontext)
|
||||
|
||||
.weak swapcontext;
|
||||
swapcontext = __swapcontext;
|
Loading…
Reference in New Issue