Skip to content
Open
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
30 changes: 30 additions & 0 deletions arm64-ucontext.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#define setcontext(u) _setmcontext(&(u)->mc)
#define getcontext(u) _getmcontext(&(u)->mc)
typedef struct mcontext mcontext_t;
typedef struct ucontext ucontext_t;
struct mcontext
{
ulong gpr[10]; /* x19-x28 */
ulong fp; /* x29 */
ulong lr; /* x30 */
ulong sp; /* stack pointer */
ulong x0; /* return value / first argument */
ulong x1; /* second argument */
ulong fpr[8]; /* d8-d15 */
};

struct ucontext
{
struct {
void *ss_sp;
uint ss_size;
} uc_stack;
sigset_t uc_sigmask;
mcontext_t mc;
};

void makecontext(ucontext_t*, void(*)(void), int, ...);
int swapcontext(ucontext_t*, const ucontext_t*);
int _getmcontext(mcontext_t*);
void _setmcontext(const mcontext_t*);

77 changes: 76 additions & 1 deletion asm.S
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@
#endif

#if defined(__APPLE__)
#if defined(__i386__)
#if defined(__aarch64__) || defined(__arm64__)
#define NEEDARM64CONTEXT 1
#define SET __setmcontext
#define GET __getmcontext
#elif defined(__i386__)
#define NEEDX86CONTEXT 1
#define SET _setmcontext
#define GET _getmcontext
Expand Down Expand Up @@ -46,6 +50,77 @@
#define GET getmcontext
#endif

#ifdef NEEDARM64CONTEXT

.text
.p2align 2

.globl GET
GET:
/* Save callee-saved general-purpose registers */
stp x19, x20, [x0, #0]
stp x21, x22, [x0, #16]
stp x23, x24, [x0, #32]
stp x25, x26, [x0, #48]
stp x27, x28, [x0, #64]

/* Save frame pointer and link register */
stp x29, x30, [x0, #80]

/* Save stack pointer */
mov x9, sp
str x9, [x0, #96]

/* Return 1 when this context is restored */
mov x9, #1
str x9, [x0, #104]
str x1, [x0, #112]

/* Save callee-saved floating-point registers */
stp d8, d9, [x0, #120]
stp d10, d11, [x0, #136]
stp d12, d13, [x0, #152]
stp d14, d15, [x0, #168]

/* First getcontext call returns 0 */
mov w0, #0
ret


.globl SET
SET:
/* x0 points to mcontext */
mov x9, x0

/* Restore general-purpose registers */
ldp x19, x20, [x9, #0]
ldp x21, x22, [x9, #16]
ldp x23, x24, [x9, #32]
ldp x25, x26, [x9, #48]
ldp x27, x28, [x9, #64]

/* Restore frame pointer and return address */
ldp x29, x30, [x9, #80]

/* Restore stack pointer */
ldr x10, [x9, #96]

/* Restore floating-point registers */
ldp d8, d9, [x9, #120]
ldp d10, d11, [x9, #136]
ldp d12, d13, [x9, #152]
ldp d14, d15, [x9, #168]

mov sp, x10

/* Restore return value / task arguments */
ldr x0, [x9, #104]
ldr x1, [x9, #112]

ret

#endif

#ifdef NEEDX86CONTEXT
.globl SET
SET:
Expand Down
36 changes: 35 additions & 1 deletion context.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
#include "taskimpl.h"

#if defined(__APPLE__)
#if defined(__i386__)
#if defined(__aarch64__) || defined(__arm64__)
#define NEEDARM64MAKECONTEXT
#define NEEDSWAPCONTEXT
#elif defined(__i386__)
#define NEEDX86MAKECONTEXT
#define NEEDSWAPCONTEXT
#elif defined(__x86_64__)
Expand Down Expand Up @@ -40,6 +43,37 @@
#define NEEDMIPSMAKECONTEXT
#endif

#ifdef NEEDARM64MAKECONTEXT

void
makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
{
uintptr_t sp;
va_list arg;

if(argc != 2){
fprint(2, "makecontext: expected 2 arguments\n");
abort();
}

sp = (uintptr_t)ucp->uc_stack.ss_sp
+ ucp->uc_stack.ss_size;

sp &= ~(uintptr_t)0xF;

memset(&ucp->mc, 0, sizeof ucp->mc);

ucp->mc.sp = (ulong)sp;
ucp->mc.lr = (ulong)(uintptr_t)func;

va_start(arg, argc);
ucp->mc.x0 = va_arg(arg, uint);
ucp->mc.x1 = va_arg(arg, uint);
va_end(arg);
}

#endif

#ifdef NEEDPOWERMAKECONTEXT
void
makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
Expand Down
2 changes: 2 additions & 0 deletions taskimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ extern void makecontext(ucontext_t*, void(*)(), int, ...);
# include "386-ucontext.h"
# elif defined(__x86_64__)
# include "amd64-ucontext.h"
# elif defined(__aarch64__) || defined (__arm64__)
# include "arm64-ucontext.h"
# else
# include "power-ucontext.h"
# endif
Expand Down