Compare commits
5 Commits
e26a93806e
...
69ebc5e51b
Author | SHA1 | Date |
---|---|---|
Ariadne Conill | 69ebc5e51b | |
Ariadne Conill | 0a72eff002 | |
Ariadne Conill | 973e61441a | |
Ariadne Conill | 00128f7575 | |
Ariadne Conill | 7fc08a6dc6 |
|
@ -24,6 +24,7 @@ target to do it.
|
|||
| m68k | ✓ | | ✓ | ✓ |
|
||||
| mips | ✓ | | ✓ | |
|
||||
| mips64 | ✓ | | ✓ | |
|
||||
| or1k | ✓ | | ✓ | ✓ |
|
||||
| ppc | ✓ | ✓ | | |
|
||||
| ppc64 | ✓ | ✓ | | |
|
||||
| riscv32 | ✓ | | ✓ | ✓ |
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef __ARCH_OR1K_DEFS_H
|
||||
#define __ARCH_OR1K_DEFS_H
|
||||
|
||||
#define REG_SZ (4)
|
||||
#define MCONTEXT_GREGS (20)
|
||||
|
||||
#define REG_SP (1)
|
||||
#define REG_FP (2)
|
||||
#define REG_RA (9)
|
||||
#define REG_SA (11)
|
||||
#define REG_LR (14)
|
||||
#define REG_PC (33)
|
||||
#define REG_SR (34)
|
||||
|
||||
#define PC_OFFSET REG_OFFSET(REG_PC)
|
||||
|
||||
#define FETCH_LINKPTR(dest) \
|
||||
asm("l.ori %0, r14, 0" :: "r" ((dest)))
|
||||
|
||||
#include "common-defs.h"
|
||||
|
||||
#endif
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2022 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.
|
||||
*/
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
ALIAS(getcontext, libucontext_getcontext)
|
||||
ALIAS(__getcontext, libucontext_getcontext)
|
||||
|
||||
FUNC(libucontext_getcontext)
|
||||
l.sw REG_OFFSET(1)(r3), r1 /* store r1 and r2 */
|
||||
l.sw REG_OFFSET(2)(r3), r2
|
||||
|
||||
l.sw REG_OFFSET(9)(r3), r9 /* store r9 to both r9 and r11 in the context */
|
||||
l.sw REG_OFFSET(11)(r3), r9
|
||||
|
||||
l.sw REG_OFFSET(10)(r3), r10 /* store r10 for TLS */
|
||||
|
||||
l.sw REG_OFFSET(14)(r3), r14 /* store r14 through r30 even */
|
||||
l.sw REG_OFFSET(16)(r3), r16
|
||||
l.sw REG_OFFSET(18)(r3), r18
|
||||
l.sw REG_OFFSET(20)(r3), r20
|
||||
l.sw REG_OFFSET(22)(r3), r22
|
||||
l.sw REG_OFFSET(24)(r3), r24
|
||||
l.sw REG_OFFSET(26)(r3), r26
|
||||
l.sw REG_OFFSET(28)(r3), r28
|
||||
l.sw REG_OFFSET(30)(r3), r30
|
||||
|
||||
l.jr r9
|
||||
l.ori r11, r0, 0
|
||||
END(libucontext_getcontext)
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef LIBUCONTEXT_BITS_H
|
||||
#define LIBUCONTEXT_BITS_H
|
||||
|
||||
typedef struct sigaltstack {
|
||||
void *ss_sp;
|
||||
int ss_flags;
|
||||
size_t ss_size;
|
||||
} libucontext_stack_t;
|
||||
|
||||
typedef int libucontext_greg_t, libucontext_gregset_t[32];
|
||||
|
||||
typedef struct {
|
||||
struct {
|
||||
libucontext_gregset_t gpr;
|
||||
libucontext_greg_t pc;
|
||||
libucontext_greg_t sr;
|
||||
} regs;
|
||||
unsigned long oldmask;
|
||||
} libucontext_mcontext_t;
|
||||
|
||||
typedef struct libucontext_ucontext {
|
||||
unsigned long uc_flags;
|
||||
struct libucontext_ucontext *uc_link;
|
||||
libucontext_stack_t uc_stack;
|
||||
libucontext_mcontext_t uc_mcontext;
|
||||
} libucontext_ucontext_t;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2022 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.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include <libucontext/libucontext.h>
|
||||
|
||||
|
||||
extern void libucontext_trampoline(void);
|
||||
|
||||
|
||||
void
|
||||
libucontext_makecontext(libucontext_ucontext_t *ucp, void (*func)(void), int argc, ...)
|
||||
{
|
||||
libucontext_greg_t *sp;
|
||||
va_list va;
|
||||
int i;
|
||||
|
||||
/* set up and align the stack. */
|
||||
sp = (libucontext_greg_t *) ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
|
||||
sp -= argc < 6 ? 0 : (argc - 6);
|
||||
sp = (libucontext_greg_t *) (((uintptr_t) sp & ~0x3));
|
||||
|
||||
/* set up the ucontext structure */
|
||||
ucp->uc_mcontext.regs.gpr[REG_SP] = (libucontext_greg_t) sp;
|
||||
ucp->uc_mcontext.regs.gpr[REG_RA] = (libucontext_greg_t) &libucontext_trampoline;
|
||||
ucp->uc_mcontext.regs.gpr[REG_FP] = 0;
|
||||
ucp->uc_mcontext.regs.gpr[REG_SA] = (libucontext_greg_t) func;
|
||||
ucp->uc_mcontext.regs.gpr[REG_LR] = (libucontext_greg_t) ucp->uc_link;
|
||||
|
||||
va_start(va, argc);
|
||||
|
||||
/* args less than argv[6] have dedicated registers, else they overflow onto stack */
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
if (i < 6)
|
||||
ucp->uc_mcontext.regs.gpr[i + 3] = va_arg (va, libucontext_greg_t);
|
||||
else
|
||||
sp[i - 6] = va_arg (va, libucontext_greg_t);
|
||||
}
|
||||
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
#ifdef EXPORT_UNPREFIXED
|
||||
extern __typeof(libucontext_makecontext) makecontext __attribute__((weak, __alias__("libucontext_makecontext")));
|
||||
extern __typeof(libucontext_makecontext) __makecontext __attribute__((weak, __alias__("libucontext_makecontext")));
|
||||
#endif
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2022 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.
|
||||
*/
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
ALIAS(setcontext, libucontext_setcontext)
|
||||
ALIAS(__setcontext, libucontext_setcontext)
|
||||
|
||||
FUNC(libucontext_setcontext)
|
||||
l.ori r30, r3, 0 /* avoid clobbering r3 by copying to r30 */
|
||||
|
||||
l.lwz r3, REG_OFFSET(3)(r30) /* restore r3-r8 (argument registers) */
|
||||
l.lwz r4, REG_OFFSET(4)(r30)
|
||||
l.lwz r5, REG_OFFSET(5)(r30)
|
||||
l.lwz r6, REG_OFFSET(6)(r30)
|
||||
l.lwz r7, REG_OFFSET(7)(r30)
|
||||
l.lwz r8, REG_OFFSET(8)(r30)
|
||||
|
||||
l.lwz r1, REG_OFFSET(1)(r30) /* restore stack/frame pointers */
|
||||
l.lwz r2, REG_OFFSET(2)(r30)
|
||||
|
||||
l.lwz r9, REG_OFFSET(9)(r30) /* restore link register and starting address register */
|
||||
l.lwz r11, REG_OFFSET(11)(r30)
|
||||
|
||||
l.lwz r10, REG_OFFSET(10)(r30) /* restore TLS register */
|
||||
|
||||
l.lwz r14, REG_OFFSET(14)(r30) /* restore r14-r30, even only */
|
||||
l.lwz r16, REG_OFFSET(16)(r30)
|
||||
l.lwz r18, REG_OFFSET(18)(r30)
|
||||
l.lwz r20, REG_OFFSET(20)(r30)
|
||||
l.lwz r22, REG_OFFSET(22)(r30)
|
||||
l.lwz r24, REG_OFFSET(24)(r30)
|
||||
l.lwz r26, REG_OFFSET(26)(r30)
|
||||
l.lwz r28, REG_OFFSET(28)(r30)
|
||||
l.lwz r30, REG_OFFSET(30)(r30)
|
||||
|
||||
l.jr r11 /* jump to new starting address */
|
||||
l.ori r11, r0, 0
|
||||
END(libucontext_setcontext)
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2022 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.
|
||||
*/
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
ALIAS(swapcontext, libucontext_swapcontext)
|
||||
ALIAS(__swapcontext, libucontext_swapcontext)
|
||||
|
||||
FUNC(libucontext_swapcontext)
|
||||
/* copy context into r3 like getcontext */
|
||||
l.sw REG_OFFSET(1)(r3), r1 /* store r1 and r2 */
|
||||
l.sw REG_OFFSET(2)(r3), r2
|
||||
|
||||
l.sw REG_OFFSET(9)(r3), r9 /* store r9 to both r9 and r11 in the context */
|
||||
l.sw REG_OFFSET(11)(r3), r9
|
||||
|
||||
l.sw REG_OFFSET(10)(r3), r10 /* store r10 for TLS */
|
||||
|
||||
l.sw REG_OFFSET(14)(r3), r14 /* store r14 through r30 even */
|
||||
l.sw REG_OFFSET(16)(r3), r16
|
||||
l.sw REG_OFFSET(18)(r3), r18
|
||||
l.sw REG_OFFSET(20)(r3), r20
|
||||
l.sw REG_OFFSET(22)(r3), r22
|
||||
l.sw REG_OFFSET(24)(r3), r24
|
||||
l.sw REG_OFFSET(26)(r3), r26
|
||||
l.sw REG_OFFSET(28)(r3), r28
|
||||
l.sw REG_OFFSET(30)(r3), r30
|
||||
|
||||
/* set the new context from r4 */
|
||||
l.ori r30, r4, 0 /* copy r4 to r30 to avoid clobbering */
|
||||
|
||||
l.lwz r3, REG_OFFSET(3)(r30) /* restore r3-r8 (argument registers) */
|
||||
l.lwz r4, REG_OFFSET(4)(r30)
|
||||
l.lwz r5, REG_OFFSET(5)(r30)
|
||||
l.lwz r6, REG_OFFSET(6)(r30)
|
||||
l.lwz r7, REG_OFFSET(7)(r30)
|
||||
l.lwz r8, REG_OFFSET(8)(r30)
|
||||
|
||||
l.lwz r1, REG_OFFSET(1)(r30) /* restore stack/frame pointers */
|
||||
l.lwz r2, REG_OFFSET(2)(r30)
|
||||
|
||||
l.lwz r9, REG_OFFSET(9)(r30) /* restore link register and starting address register */
|
||||
l.lwz r11, REG_OFFSET(11)(r30)
|
||||
|
||||
l.lwz r10, REG_OFFSET(10)(r30) /* restore TLS register */
|
||||
|
||||
l.lwz r14, REG_OFFSET(14)(r30) /* restore r14-r30, even only */
|
||||
l.lwz r16, REG_OFFSET(16)(r30)
|
||||
l.lwz r18, REG_OFFSET(18)(r30)
|
||||
l.lwz r20, REG_OFFSET(20)(r30)
|
||||
l.lwz r22, REG_OFFSET(22)(r30)
|
||||
l.lwz r24, REG_OFFSET(24)(r30)
|
||||
l.lwz r26, REG_OFFSET(26)(r30)
|
||||
l.lwz r28, REG_OFFSET(28)(r30)
|
||||
l.lwz r30, REG_OFFSET(30)(r30)
|
||||
|
||||
l.jr r11 /* jump to new starting address */
|
||||
l.ori r11, r0, 0
|
||||
END(libucontext_swapcontext)
|
|
@ -0,0 +1,3 @@
|
|||
#include "defs.h"
|
||||
#include <libucontext/libucontext.h>
|
||||
#include "common-trampoline.c"
|
Loading…
Reference in New Issue