mips: add MIPS O32 ABI implementation (closes #2)

arm_linker_fix
Ariadne Conill 2020-03-29 15:54:32 +00:00
parent 01432abb3e
commit add34ddac7
6 changed files with 405 additions and 0 deletions

94
arch/mips/defs.h Normal file
View File

@ -0,0 +1,94 @@
#ifndef __ARCH_MIPS64_DEFS_H
#define __ARCH_MIPS64_DEFS_H
#define REG_SZ (4)
#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 (32)
/* offset to uc_link in ucontext_t */
#define UCONTEXT_UC_LINK (4)
/* offset to uc_stack.ss_sp in ucontext_t */
#define UCONTEXT_STACK_PTR (8)
/* offset to uc_stack.ss_size in ucontext_t */
#define UCONTEXT_STACK_SIZE (12)
/* 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; \
.set noreorder; \
.cpload $25; \
.set reorder;
#define PUSH_FRAME(__proc) \
addiu $sp, -FRAMESZ; \
.cprestore GPOFF;
#define POP_FRAME(__proc) \
addiu $sp, FRAMESZ
#define ENT(__proc) .ent __proc, 0;
#include <common-defs.h>
#endif

46
arch/mips/getcontext.S Normal file
View File

@ -0,0 +1,46 @@
/*
* 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"
ALIAS(getcontext, __getcontext)
FUNC(__getcontext)
/* copy $gp, $sp, $fp to temporary registers so we don't clobber them */
move $a2, $gp
move $a3, $sp
move $a1, $fp
PUSH_FRAME(__getcontext)
/* set registers */
sw $s0, ((16 * REG_SZ) + MCONTEXT_GREGS)($a0)
sw $s1, ((17 * REG_SZ) + MCONTEXT_GREGS)($a0)
sw $s2, ((18 * REG_SZ) + MCONTEXT_GREGS)($a0)
sw $s3, ((19 * REG_SZ) + MCONTEXT_GREGS)($a0)
sw $s4, ((20 * REG_SZ) + MCONTEXT_GREGS)($a0)
sw $s5, ((21 * REG_SZ) + MCONTEXT_GREGS)($a0)
sw $s6, ((22 * REG_SZ) + MCONTEXT_GREGS)($a0)
sw $s7, ((23 * REG_SZ) + MCONTEXT_GREGS)($a0)
sw $a2, ((28 * REG_SZ) + MCONTEXT_GREGS)($a0)
sw $a3, ((29 * REG_SZ) + MCONTEXT_GREGS)($a0)
sw $a1, ((30 * REG_SZ) + MCONTEXT_GREGS)($a0)
sw $ra, ((31 * REG_SZ) + MCONTEXT_GREGS)($a0)
sw $ra, (MCONTEXT_PC)($a0)
POP_FRAME(__getcontext)
jr $ra
END(__getcontext)

100
arch/mips/makecontext.S Normal file
View File

@ -0,0 +1,100 @@
/*
* 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"
A3_OFF = FRAMESZ + (3 * REG_SZ)
/*
* Because we have to fiddle with $gp, we have to implement this in
* assembly rather than C. Annoying, that...
*/
ALIAS(makecontext, __makecontext)
FUNC(__makecontext)
PUSH_FRAME(__makecontext)
/* store $a3 through $a7 to the stack frame. */
sw $a3, A3_OFF($sp)
/* set $zero in the mcontext to 1. */
li $v0, 1
sw $v0, ((0 * REG_SZ) + MCONTEXT_GREGS)($a0)
/* ensure the stack is aligned on a quad-word boundary. */
lw $t0, UCONTEXT_STACK_PTR($a0)
lw $t2, UCONTEXT_STACK_SIZE($a0)
addiu $t1, $sp, A3_OFF
addu $t0, $t2
and $t0, ALMASK
blez $a2, no_more_arguments
/* store register arguments. */
addiu $t2, $a0, MCONTEXT_GREGS + (4 * REG_SZ)
move $t3, $zero
store_register_arg:
addiu $t3, 1
lw $v1, ($t1)
addiu $t1, REG_SZ
sw $v1, ($t2)
addiu $t2, REG_SZ
bgeu $t3, $a2, no_more_arguments
bltu $t3, 4, store_register_arg
/* make room for stack arguments. */
subu $t2, $a2, $t3
sll $t2, 3
subu $t0, $t2
and $t0, ALMASK
/* store stack arguments. */
move $t2, $t0
store_stack_arg:
addiu $t3, 1
lw $v1, ($t1)
addiu $t1, REG_SZ
sw $v1, ($t2)
addiu $t2, REG_SZ
bltu $t3, $a2, store_stack_arg
no_more_arguments:
/* make room for $a0-$a3 storage */
addiu $t0, -(4 * REG_SZ)
/* trampoline setup. */
la $t9, __start_context
/* copy link pointer as $s0... */
lw $v1, UCONTEXT_UC_LINK($a0)
sw $v1, ((16 * REG_SZ) + MCONTEXT_GREGS)($a0)
/* set our $sp */
sw $t0, ((29 * REG_SZ) + MCONTEXT_GREGS)($a0)
/* $gp is copied as $s1 */
sw $gp, ((17 * REG_SZ) + MCONTEXT_GREGS)($a0)
/* set our $ra */
sw $t9, ((31 * REG_SZ) + MCONTEXT_GREGS)($a0)
/* set our $pc */
sw $a1, MCONTEXT_PC($a0)
POP_FRAME(__makecontext)
jr $ra
END(__makecontext)

50
arch/mips/setcontext.S Normal file
View File

@ -0,0 +1,50 @@
/*
* 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"
ALIAS(setcontext, __setcontext)
FUNC(__setcontext)
PUSH_FRAME(__setcontext)
/* move the context to $v0 */
move $v0, $a0
/* load the registers */
lw $a0, ((4 * REG_SZ) + MCONTEXT_GREGS)($v0)
lw $a1, ((5 * REG_SZ) + MCONTEXT_GREGS)($v0)
lw $a2, ((6 * REG_SZ) + MCONTEXT_GREGS)($v0)
lw $a3, ((7 * REG_SZ) + MCONTEXT_GREGS)($v0)
lw $s0, ((16 * REG_SZ) + MCONTEXT_GREGS)($v0)
lw $s1, ((17 * REG_SZ) + MCONTEXT_GREGS)($v0)
lw $s2, ((18 * REG_SZ) + MCONTEXT_GREGS)($v0)
lw $s3, ((19 * REG_SZ) + MCONTEXT_GREGS)($v0)
lw $s4, ((20 * REG_SZ) + MCONTEXT_GREGS)($v0)
lw $s5, ((21 * REG_SZ) + MCONTEXT_GREGS)($v0)
lw $s6, ((22 * REG_SZ) + MCONTEXT_GREGS)($v0)
lw $s7, ((23 * REG_SZ) + MCONTEXT_GREGS)($v0)
lw $gp, ((28 * REG_SZ) + MCONTEXT_GREGS)($v0)
lw $sp, ((29 * REG_SZ) + MCONTEXT_GREGS)($v0)
lw $fp, ((30 * REG_SZ) + MCONTEXT_GREGS)($v0)
lw $ra, ((31 * REG_SZ) + MCONTEXT_GREGS)($v0)
lw $t9, (MCONTEXT_PC)($v0)
move $v0, $zero
jr $t9
POP_FRAME(__setcontext)
END(__setcontext)

34
arch/mips/startcontext.S Normal file
View File

@ -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
la $t9, __setcontext
jr $t9
no_linked_context:
move $a0, $zero
la $t9, exit
jalr $t9
nop
END(__start_context)

81
arch/mips/swapcontext.S Normal file
View File

@ -0,0 +1,81 @@
/*
* 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)
ALIAS(swapcontext, __swapcontext)
FUNC(__swapcontext)
/* copy $gp, $sp, $fp to temporary registers so we don't clobber them */
move $a2, $gp
move $a3, $sp
PUSH_FRAME(__swapcontext)
/* 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 $fp, ((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 $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:
la $t9, exit
POP_FRAME(__swapcontext)
move $v0, $zero
jalr $t9
END(__swapcontext)