From 247f30400c6b6b4fe614c25ce6a0391052fd0c40 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Wed, 31 Jan 2018 04:11:46 +0000 Subject: [PATCH] arch: arm: add armv6+ port --- arch/arm/getcontext.S | 27 +++++++++++++++++ arch/arm/makecontext.c | 65 +++++++++++++++++++++++++++++++++++++++++ arch/arm/setcontext.S | 26 +++++++++++++++++ arch/arm/startcontext.S | 23 +++++++++++++++ arch/arm/swapcontext.S | 30 +++++++++++++++++++ 5 files changed, 171 insertions(+) create mode 100644 arch/arm/getcontext.S create mode 100644 arch/arm/makecontext.c create mode 100644 arch/arm/setcontext.S create mode 100644 arch/arm/startcontext.S create mode 100644 arch/arm/swapcontext.S diff --git a/arch/arm/getcontext.S b/arch/arm/getcontext.S new file mode 100644 index 0000000..c6ca5ae --- /dev/null +++ b/arch/arm/getcontext.S @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2018 William Pitcock + * + * 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. + */ + +.globl __getcontext; +__getcontext: + /* copy all of the current registers into the ucontext structure */ + add r1, r0, #48 + stmia r1, {r4-r12} + str r13, [r0,#84] + str r14, [r0,#92] + + /* return 0 */ + mov r0, #0 + mov pc, lr + + +.weak getcontext; +getcontext = __getcontext; diff --git a/arch/arm/makecontext.c b/arch/arm/makecontext.c new file mode 100644 index 0000000..14e6203 --- /dev/null +++ b/arch/arm/makecontext.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2018 William Pitcock + * + * 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. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include + + +extern void __start_context(void); + + +void +__makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) +{ + unsigned long *sp; + unsigned long *regp; + va_list va; + int i; + + sp = (unsigned long *) ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size); + sp = (unsigned long *) (((uintptr_t) sp & -16L) - 8); + + if (argc > 4) + sp -= (argc - 4); + + ucp->uc_mcontext.arm_sp = (uintptr_t) sp; + ucp->uc_mcontext.arm_pc = (uintptr_t) func; + ucp->uc_mcontext.arm_r4 = (uintptr_t) ucp->uc_link; + ucp->uc_mcontext.arm_lr = (uintptr_t) &__start_context; + + va_start(va, argc); + + regp = &(ucp->uc_mcontext.arm_r0); + + for (i = 0; (i < argc && i < 4); i++) + *regp++ = va_arg (va, unsigned long); + + for (; i < argc; i++) + *sp++ = va_arg (va, unsigned long); + + va_end(va); + +/* + printf("R4 offset = %d\n", offsetof(ucontext_t, uc_mcontext.arm_r4)); + printf("SP offset = %d\n", offsetof(ucontext_t, uc_mcontext.arm_sp)); + printf("LR offset = %d\n", offsetof(ucontext_t, uc_mcontext.arm_lr)); + printf("PC offset = %d\n", offsetof(ucontext_t, uc_mcontext.arm_pc)); + */ +} + + +extern __typeof(__makecontext) makecontext __attribute__((weak, __alias__("__makecontext"))); diff --git a/arch/arm/setcontext.S b/arch/arm/setcontext.S new file mode 100644 index 0000000..341fc02 --- /dev/null +++ b/arch/arm/setcontext.S @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2018 William Pitcock + * + * 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. + */ + +.globl __setcontext; +__setcontext: + /* copy all of the current registers into the ucontext structure */ + add r14, r0, #32 + ldmia r14, {r0-r12} + ldr r13, [r14, #52] + add r14, r14, #56 + + /* load link register and jump to new context */ + ldmia r14, {r14, pc} + + +.weak setcontext; +setcontext = __setcontext; diff --git a/arch/arm/startcontext.S b/arch/arm/startcontext.S new file mode 100644 index 0000000..45430c7 --- /dev/null +++ b/arch/arm/startcontext.S @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2018 William Pitcock + * + * 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. + */ + +.globl __start_context; +.fnstart +.cantunwind + nop +__start_context: + /* get the proper context into position and test for NULL */ + movs r0, r4 + bne __setcontext@plt + + /* we are returning into a null context, it seems, so maybe we should exit */ + b exit@plt diff --git a/arch/arm/swapcontext.S b/arch/arm/swapcontext.S new file mode 100644 index 0000000..e257647 --- /dev/null +++ b/arch/arm/swapcontext.S @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018 William Pitcock + * + * 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. + */ + +.globl __swapcontext; +__swapcontext: + /* copy all of the current registers into the ucontext structure */ + add r2, r0, #32 + stmia r2, {r0-r12} + str r13, [r0,#84] + str r14, [r0,#92] + + /* load new registers from the second ucontext structure */ + add r14, r1, #32 + ldmia r14, {r0-r12} + ldr r13, [r14, #52] + add r14, r14, #56 + ldmia r14, {r14, pc} + + +.weak swapcontext; +swapcontext = __swapcontext;