diff options
Diffstat (limited to 'system/libucontext/powerpc.patch')
-rw-r--r-- | system/libucontext/powerpc.patch | 1121 |
1 files changed, 1121 insertions, 0 deletions
diff --git a/system/libucontext/powerpc.patch b/system/libucontext/powerpc.patch new file mode 100644 index 000000000..ed7604d7b --- /dev/null +++ b/system/libucontext/powerpc.patch @@ -0,0 +1,1121 @@ +From 94216c60c43a30e39fbc4f347450768699c6c77c Mon Sep 17 00:00:00 2001 +From: Bobby Bingham <koorogi@koorogi.info> +Date: Mon, 1 Apr 2019 23:02:12 -0500 +Subject: [PATCH] test ability to pass 10 args through makecontext + +--- + test_libucontext.c | 23 +++++++++++++++++++++-- + 1 file changed, 21 insertions(+), 2 deletions(-) + +diff --git a/test_libucontext.c b/test_libucontext.c +index 121cc3e..e5eac83 100644 +--- a/test_libucontext.c ++++ b/test_libucontext.c +@@ -6,13 +6,32 @@ + #include <stdio.h> + #include <ucontext.h> + #include <stdint.h> ++#include <stdlib.h> + #include <string.h> + + + static ucontext_t ctx[3]; + + +-static void f1 (void) { ++static void check_arg(int actual, int expected) { ++ if (actual == expected) return; ++ fprintf(stderr, "argument has wrong value. got %d, expected %d.\n", actual, expected); ++ abort(); ++} ++ ++ ++static void f1 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j) { ++ check_arg(a, 1); ++ check_arg(b, 2); ++ check_arg(c, 3); ++ check_arg(d, 4); ++ check_arg(e, 5); ++ check_arg(f, 6); ++ check_arg(g, 7); ++ check_arg(h, 8); ++ check_arg(i, 9); ++ check_arg(j, 10); ++ + printf("start f1\n"); + swapcontext(&ctx[1], &ctx[2]); + printf("finish f1\n"); +@@ -40,7 +59,7 @@ int main (int argc, const char *argv[]) { + ctx[1].uc_stack.ss_sp = st1; + ctx[1].uc_stack.ss_size = sizeof st1; + ctx[1].uc_link = &ctx[0]; +- makecontext(&ctx[1], f1, 0); ++ makecontext(&ctx[1], f1, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + + + getcontext(&ctx[2]); +From cb59e7ee957b389578a3f973484ae3198f6cfed1 Mon Sep 17 00:00:00 2001 +From: Bobby Bingham <koorogi@koorogi.info> +Date: Mon, 1 Apr 2019 23:03:21 -0500 +Subject: [PATCH] test calls to getcontext without makecontext + +--- + test_libucontext.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/test_libucontext.c b/test_libucontext.c +index e5eac83..a4a9b4c 100644 +--- a/test_libucontext.c ++++ b/test_libucontext.c +@@ -48,6 +48,7 @@ static void f2 (void) { + int main (int argc, const char *argv[]) { + char st1[8192]; + char st2[8192]; ++ volatile int done = 0; + + + /* poison each coroutine's stack memory for debugging purposes */ +@@ -70,5 +71,16 @@ int main (int argc, const char *argv[]) { + + + swapcontext(&ctx[0], &ctx[2]); ++ ++ ++ /* test ability to use getcontext/setcontext without makecontext */ ++ getcontext(&ctx[1]); ++ printf("done = %d\n", done); ++ if (done++ == 0) setcontext(&ctx[1]); ++ if (done != 2) { ++ fprintf(stderr, "wrong value for done. got %d, expected 2\n", done); ++ abort(); ++ } ++ + return 0; + } +From b6a9b5e279123f16569e0fd9f8ff14ff04bed7a3 Mon Sep 17 00:00:00 2001 +From: Bobby Bingham <koorogi@koorogi.info> +Date: Fri, 5 Apr 2019 13:32:03 -0500 +Subject: [PATCH] ppc32: fix stack alignment + +The stack should be 16-byte aligned, not 8 mod 16. +--- + arch/ppc/makecontext.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/ppc/makecontext.c b/arch/ppc/makecontext.c +index c562ea5..1b9efdf 100644 +--- a/arch/ppc/makecontext.c ++++ b/arch/ppc/makecontext.c +@@ -37,7 +37,7 @@ __makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) + + sp = (greg_t *) ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size); + sp -= (uc_link + 1); +- sp = (greg_t *) (((uintptr_t) sp & -16L) - 8); ++ sp = (greg_t *) ((uintptr_t) sp & -16L); + + ucp->uc_mcontext.gregs[REG_NIP] = (uintptr_t) func; + ucp->uc_mcontext.gregs[REG_LNK] = (uintptr_t) &__start_context; +From b9bd4045fb34f060d6cf37fc7da7ab13b91462de Mon Sep 17 00:00:00 2001 +From: Bobby Bingham <koorogi@koorogi.info> +Date: Fri, 5 Apr 2019 13:35:00 -0500 +Subject: [PATCH] ppc32/64: fix back chain pointer + +The ABI states that sp[0] should point to the previous stack frame, or be +zero if there is no previous stack frame. makecontext previously set this +slot to point to the __start_context function, rather than to a valid +stack frame. +--- + arch/ppc/makecontext.c | 2 +- + arch/ppc64/makecontext.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/ppc/makecontext.c b/arch/ppc/makecontext.c +index 1b9efdf..729f465 100644 +--- a/arch/ppc/makecontext.c ++++ b/arch/ppc/makecontext.c +@@ -44,7 +44,7 @@ __makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) + ucp->uc_mcontext.gregs[REG_R31] = (uintptr_t) ucp->uc_link; + ucp->uc_mcontext.gregs[REG_SP] = (uintptr_t) sp; + +- sp[0] = (uintptr_t) &__start_context; ++ sp[0] = 0; + sp[uc_link] = (uintptr_t) ucp->uc_link; + argp = &sp[2]; + +diff --git a/arch/ppc64/makecontext.c b/arch/ppc64/makecontext.c +index 9d6b998..91fb579 100644 +--- a/arch/ppc64/makecontext.c ++++ b/arch/ppc64/makecontext.c +@@ -45,7 +45,7 @@ __makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) + ucp->uc_mcontext.gp_regs[REG_ENTRY] = (uintptr_t) func; + ucp->uc_mcontext.gp_regs[REG_R31] = (uintptr_t) ucp->uc_link; + +- sp[0] = (uintptr_t) &__start_context; ++ sp[0] = 0; + sp[uc_link] = (uintptr_t) ucp->uc_link; + argp = &sp[2]; + +From b500b054c7cf412a6042496afa08b4302f7ed929 Mon Sep 17 00:00:00 2001 +From: Bobby Bingham <koorogi@koorogi.info> +Date: Fri, 5 Apr 2019 13:38:36 -0500 +Subject: [PATCH] ppc32/64: don't store uc_link on the stack + +This was previously stored either in the CR (ppc64) or LR (ppc32) save +area of the stack, or to one of the parameter save slots. + +In either case, the saved value was unused. This value is also passed +to __start_context via r31, so there's no need to pass it on the stack. +--- + arch/ppc/makecontext.c | 6 ++---- + arch/ppc64/makecontext.c | 6 ++---- + 2 files changed, 4 insertions(+), 8 deletions(-) + +diff --git a/arch/ppc/makecontext.c b/arch/ppc/makecontext.c +index 729f465..2b7ea67 100644 +--- a/arch/ppc/makecontext.c ++++ b/arch/ppc/makecontext.c +@@ -30,13 +30,12 @@ __makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) + greg_t *sp, *argp; + va_list va; + int i; +- unsigned int uc_link, stack_args; ++ unsigned int stack_args; + + stack_args = argc > 8 ? argc - 8 : 0; +- uc_link = stack_args + 1; + + sp = (greg_t *) ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size); +- sp -= (uc_link + 1); ++ sp -= stack_args + 2; + sp = (greg_t *) ((uintptr_t) sp & -16L); + + ucp->uc_mcontext.gregs[REG_NIP] = (uintptr_t) func; +@@ -45,7 +44,6 @@ __makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) + ucp->uc_mcontext.gregs[REG_SP] = (uintptr_t) sp; + + sp[0] = 0; +- sp[uc_link] = (uintptr_t) ucp->uc_link; + argp = &sp[2]; + + va_start(va, argc); +diff --git a/arch/ppc64/makecontext.c b/arch/ppc64/makecontext.c +index 91fb579..b060371 100644 +--- a/arch/ppc64/makecontext.c ++++ b/arch/ppc64/makecontext.c +@@ -30,13 +30,12 @@ __makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) + greg_t *sp, *argp; + va_list va; + int i; +- unsigned int uc_link, stack_args; ++ unsigned int stack_args; + + stack_args = argc > 8 ? argc - 8 : 0; +- uc_link = stack_args + 1; + + sp = (greg_t *) ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size); +- sp -= (uc_link + 1); ++ sp -= stack_args + 2; + sp = (greg_t *) (((uintptr_t) sp & -16L)); + + ucp->uc_mcontext.gp_regs[REG_NIP] = (uintptr_t) func; +@@ -46,7 +45,6 @@ __makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) + ucp->uc_mcontext.gp_regs[REG_R31] = (uintptr_t) ucp->uc_link; + + sp[0] = 0; +- sp[uc_link] = (uintptr_t) ucp->uc_link; + argp = &sp[2]; + + va_start(va, argc); +From 55168fcb1809dde45c99450f1f3be27716c473db Mon Sep 17 00:00:00 2001 +From: Bobby Bingham <koorogi@koorogi.info> +Date: Fri, 5 Apr 2019 13:57:53 -0500 +Subject: [PATCH] ppc32/64: simplify storage of stack parameters + +The switch statement is simpler as an if/else, and removing the argp +variable makes the code more symmetric between the register and stack +parameter cases. +--- + arch/ppc/makecontext.c | 24 ++++++------------------ + arch/ppc64/makecontext.c | 24 ++++++------------------ + 2 files changed, 12 insertions(+), 36 deletions(-) + +diff --git a/arch/ppc/makecontext.c b/arch/ppc/makecontext.c +index 2b7ea67..4a404a4 100644 +--- a/arch/ppc/makecontext.c ++++ b/arch/ppc/makecontext.c +@@ -27,7 +27,7 @@ extern void __start_context(void); + void + __makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) + { +- greg_t *sp, *argp; ++ greg_t *sp; + va_list va; + int i; + unsigned int stack_args; +@@ -44,27 +44,15 @@ __makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) + ucp->uc_mcontext.gregs[REG_SP] = (uintptr_t) sp; + + sp[0] = 0; +- argp = &sp[2]; + + va_start(va, argc); + +- for (i = 0; i < argc; i++) +- switch (i) +- { +- case 0: +- case 1: +- case 2: +- case 3: +- case 4: +- case 5: +- case 6: +- case 7: ++ for (i = 0; i < argc; i++) { ++ if (i < 8) + ucp->uc_mcontext.gregs[i + 3] = va_arg (va, greg_t); +- break; +- default: +- *argp++ = va_arg (va, greg_t); +- break; +- } ++ else ++ sp[i-8 + 2] = va_arg (va, greg_t); ++ } + + va_end(va); + } +diff --git a/arch/ppc64/makecontext.c b/arch/ppc64/makecontext.c +index b060371..962f98a 100644 +--- a/arch/ppc64/makecontext.c ++++ b/arch/ppc64/makecontext.c +@@ -27,7 +27,7 @@ extern void __start_context(void); + void + __makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) + { +- greg_t *sp, *argp; ++ greg_t *sp; + va_list va; + int i; + unsigned int stack_args; +@@ -45,27 +45,15 @@ __makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) + ucp->uc_mcontext.gp_regs[REG_R31] = (uintptr_t) ucp->uc_link; + + sp[0] = 0; +- argp = &sp[2]; + + va_start(va, argc); + +- for (i = 0; i < argc; i++) +- switch (i) +- { +- case 0: +- case 1: +- case 2: +- case 3: +- case 4: +- case 5: +- case 6: +- case 7: ++ for (i = 0; i < argc; i++) { ++ if (i < 8) + ucp->uc_mcontext.gp_regs[i + 3] = va_arg (va, greg_t); +- break; +- default: +- *argp++ = va_arg (va, greg_t); +- break; +- } ++ else ++ sp[i-8 + 2] = va_arg (va, greg_t); ++ } + + va_end(va); + } +From 8ea5f548b9146ffeea2074a33a06bbbd07a74402 Mon Sep 17 00:00:00 2001 +From: Bobby Bingham <koorogi@koorogi.info> +Date: Fri, 5 Apr 2019 14:01:10 -0500 +Subject: [PATCH] ppc64: fix makecontext with more than 8 parameters + +The ELFv2 ABI used on PPC64 differs from the ELFv1 ABI used on PPC32 here. +On PPC64, once there are any parameters that need to be passed on the +stack, space needs to be reserved on the stack to pass all parameters. +Parameters 0-7 are still only passed by register, but if the callee needs +to spill them, it can use the stack space reserved for the corresponding +parameter to do so. +--- + arch/ppc64/makecontext.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/ppc64/makecontext.c b/arch/ppc64/makecontext.c +index 962f98a..ea980e9 100644 +--- a/arch/ppc64/makecontext.c ++++ b/arch/ppc64/makecontext.c +@@ -32,7 +32,7 @@ __makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) + int i; + unsigned int stack_args; + +- stack_args = argc > 8 ? argc - 8 : 0; ++ stack_args = argc > 8 ? argc : 0; + + sp = (greg_t *) ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size); + sp -= stack_args + 2; +@@ -52,7 +52,7 @@ __makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) + if (i < 8) + ucp->uc_mcontext.gp_regs[i + 3] = va_arg (va, greg_t); + else +- sp[i-8 + 2] = va_arg (va, greg_t); ++ sp[i + 2] = va_arg (va, greg_t); + } + + va_end(va); +From a00a05ce2950ca3b306f8ccc3e817ea8cd675015 Mon Sep 17 00:00:00 2001 +From: Bobby Bingham <koorogi@koorogi.info> +Date: Fri, 5 Apr 2019 14:03:47 -0500 +Subject: [PATCH] ppc64: fix incorrect position of parameters within stack + frame + +On PPC64, there are 4 register-sized stack slots below the parameter save +area, which is different from the 2 stack slots on PPC32. +--- + arch/ppc64/makecontext.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/ppc64/makecontext.c b/arch/ppc64/makecontext.c +index ea980e9..a4c1bf9 100644 +--- a/arch/ppc64/makecontext.c ++++ b/arch/ppc64/makecontext.c +@@ -35,7 +35,7 @@ __makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) + stack_args = argc > 8 ? argc : 0; + + sp = (greg_t *) ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size); +- sp -= stack_args + 2; ++ sp -= stack_args + 4; + sp = (greg_t *) (((uintptr_t) sp & -16L)); + + ucp->uc_mcontext.gp_regs[REG_NIP] = (uintptr_t) func; +@@ -52,7 +52,7 @@ __makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) + if (i < 8) + ucp->uc_mcontext.gp_regs[i + 3] = va_arg (va, greg_t); + else +- sp[i + 2] = va_arg (va, greg_t); ++ sp[i + 4] = va_arg (va, greg_t); + } + + va_end(va); +From 40d07758a5677e8869d7a62a499236bb6ed01897 Mon Sep 17 00:00:00 2001 +From: Bobby Bingham <koorogi@koorogi.info> +Date: Fri, 5 Apr 2019 14:09:25 -0500 +Subject: [PATCH] ppc32/64: correct signature of function parameter to + makecontext + +Because makecontext can pass a set of integer arguments to the provided +function, it is incorrect to require that this function accept no +parameters. +--- + arch/ppc/makecontext.c | 2 +- + arch/ppc64/makecontext.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/ppc/makecontext.c b/arch/ppc/makecontext.c +index 4a404a4..0633c0f 100644 +--- a/arch/ppc/makecontext.c ++++ b/arch/ppc/makecontext.c +@@ -25,7 +25,7 @@ extern void __start_context(void); + + + void +-__makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) ++__makecontext(ucontext_t *ucp, void (*func)(), int argc, ...) + { + greg_t *sp; + va_list va; +diff --git a/arch/ppc64/makecontext.c b/arch/ppc64/makecontext.c +index a4c1bf9..8a293b5 100644 +--- a/arch/ppc64/makecontext.c ++++ b/arch/ppc64/makecontext.c +@@ -25,7 +25,7 @@ extern void __start_context(void); + + + void +-__makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) ++__makecontext(ucontext_t *ucp, void (*func)(), int argc, ...) + { + greg_t *sp; + va_list va; +From edf69879eadaec0c72ba7ef5e7d2389946c6644b Mon Sep 17 00:00:00 2001 +From: Bobby Bingham <koorogi@koorogi.info> +Date: Fri, 5 Apr 2019 14:09:39 -0500 +Subject: [PATCH] ppc64: remove unnecessary parentheses + +--- + arch/ppc64/makecontext.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/ppc64/makecontext.c b/arch/ppc64/makecontext.c +index 8a293b5..84d390a 100644 +--- a/arch/ppc64/makecontext.c ++++ b/arch/ppc64/makecontext.c +@@ -36,7 +36,7 @@ __makecontext(ucontext_t *ucp, void (*func)(), int argc, ...) + + sp = (greg_t *) ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size); + sp -= stack_args + 4; +- sp = (greg_t *) (((uintptr_t) sp & -16L)); ++ sp = (greg_t *) ((uintptr_t) sp & -16L); + + ucp->uc_mcontext.gp_regs[REG_NIP] = (uintptr_t) func; + ucp->uc_mcontext.gp_regs[REG_LNK] = (uintptr_t) &__start_context; +From 29eac4259adfd85e0f4946a1080bb9e3f8c0cc2e Mon Sep 17 00:00:00 2001 +From: Bobby Bingham <koorogi@koorogi.info> +Date: Fri, 5 Apr 2019 14:10:28 -0500 +Subject: [PATCH] ppc32/64: remove unused includes + +--- + arch/ppc/makecontext.c | 2 -- + arch/ppc64/makecontext.c | 2 -- + 2 files changed, 4 deletions(-) + +diff --git a/arch/ppc/makecontext.c b/arch/ppc/makecontext.c +index 0633c0f..7214a40 100644 +--- a/arch/ppc/makecontext.c ++++ b/arch/ppc/makecontext.c +@@ -11,10 +11,8 @@ + */ + + #define _GNU_SOURCE +-#include <stddef.h> + #include <stdarg.h> + #include <signal.h> +-#include <string.h> + #include <stdint.h> + + +diff --git a/arch/ppc64/makecontext.c b/arch/ppc64/makecontext.c +index 84d390a..2650f56 100644 +--- a/arch/ppc64/makecontext.c ++++ b/arch/ppc64/makecontext.c +@@ -11,10 +11,8 @@ + */ + + #define _GNU_SOURCE +-#include <stddef.h> + #include <stdarg.h> + #include <signal.h> +-#include <string.h> + #include <stdint.h> + + +From 90ff6330e62c8f836016668c9f769af365b257cb Mon Sep 17 00:00:00 2001 +From: Bobby Bingham <koorogi@koorogi.info> +Date: Fri, 5 Apr 2019 14:11:21 -0500 +Subject: [PATCH] ppc32/64: update copyright + +--- + arch/ppc/makecontext.c | 1 + + arch/ppc64/makecontext.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/ppc/makecontext.c b/arch/ppc/makecontext.c +index 7214a40..51c492f 100644 +--- a/arch/ppc/makecontext.c ++++ b/arch/ppc/makecontext.c +@@ -1,5 +1,6 @@ + /* + * Copyright (c) 2018 William Pitcock <nenolod@dereferenced.org> ++ * Copyright (c) 2019 Bobby Bingham <koorogi@koorogi.info> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above +diff --git a/arch/ppc64/makecontext.c b/arch/ppc64/makecontext.c +index 2650f56..43da557 100644 +--- a/arch/ppc64/makecontext.c ++++ b/arch/ppc64/makecontext.c +@@ -1,5 +1,6 @@ + /* + * Copyright (c) 2018 William Pitcock <nenolod@dereferenced.org> ++ * Copyright (c) 2019 Bobby Bingham <koorogi@koorogi.info> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above +From 2610c7faa7b9c4114d53bb659264a6be238cd2a3 Mon Sep 17 00:00:00 2001 +From: Bobby Bingham <koorogi@koorogi.info> +Date: Sat, 23 Feb 2019 17:12:37 -0600 +Subject: [PATCH] ppc32/64: rewrite get/set/swapcontext in assembly + +getcontext cannot be correctly implemented in C. + +If this calls another function, as it does to call syscall, it needs to +first spill its return address to the stack. If, after getcontext returns, +its caller then calls other functions, this saved return address can be +clobbered. When the context saved by getcontext is later restored, the +(now clobbered) return address will be reloaded from the stack, and the +second return from getcontext will return to the wrong location. + +Because the powerpc swapcontext syscall allows either the old context or +new context pointers to be null, it is usable for implementing all of +get/set/swapcontext. + +We therefore rewrite swapcontext in assembly, and get/setcontext as simple +assembly function wrappers around swapcontext. + +The one piece we keep in C is the code to check the return value of the +system call and to set errno. This code was actually unnecessary before -- +libc does this within syscall. However, now that the system call is made +directly in assembly, bypassing libc, it is truly necessary. Because errno +is thread-local and the details of how to set it can vary by libc, this +code remains written in C. +--- + Makefile | 10 +---- + README.md | 2 +- + arch/ppc/getcontext.S | 20 +++++++++ + arch/ppc/{getcontext.c => retfromsyscall.c} | 30 +++---------- + arch/ppc/setcontext.S | 21 +++++++++ + arch/ppc/setcontext.c | 45 ------------------- + arch/ppc/swapcontext.S | 23 ++++++++++ + arch/ppc/swapcontext.c | 45 ------------------- + arch/ppc64/getcontext.S | 25 +++++++++++ + arch/ppc64/{getcontext.c => retfromsyscall.c} | 30 +++---------- + arch/ppc64/setcontext.S | 26 +++++++++++ + arch/ppc64/setcontext.c | 45 ------------------- + arch/ppc64/swapcontext.S | 28 ++++++++++++ + arch/ppc64/swapcontext.c | 45 ------------------- + 14 files changed, 156 insertions(+), 239 deletions(-) + create mode 100644 arch/ppc/getcontext.S + rename arch/ppc/{getcontext.c => retfromsyscall.c} (53%) + create mode 100644 arch/ppc/setcontext.S + delete mode 100644 arch/ppc/setcontext.c + create mode 100644 arch/ppc/swapcontext.S + delete mode 100644 arch/ppc/swapcontext.c + create mode 100644 arch/ppc64/getcontext.S + rename arch/ppc64/{getcontext.c => retfromsyscall.c} (53%) + create mode 100644 arch/ppc64/setcontext.S + delete mode 100644 arch/ppc64/setcontext.c + create mode 100644 arch/ppc64/swapcontext.S + delete mode 100644 arch/ppc64/swapcontext.c + +diff --git a/Makefile b/Makefile +index 51365a3..d6ff1b0 100644 +--- a/Makefile ++++ b/Makefile +@@ -2,14 +2,8 @@ ARCH := $(shell uname -m) + + CFLAGS = -ggdb3 -O2 -Wall -Iarch/${ARCH} + +-LIBUCONTEXT_C_SRC = \ +- arch/${ARCH}/makecontext.c +- +-LIBUCONTEXT_S_SRC = \ +- arch/${ARCH}/getcontext.S \ +- arch/${ARCH}/setcontext.S \ +- arch/${ARCH}/swapcontext.S \ +- arch/${ARCH}/startcontext.S ++LIBUCONTEXT_C_SRC = $(wildcard arch/${ARCH}/*.c) ++LIBUCONTEXT_S_SRC = $(wildcard arch/${ARCH}/*.S) + + LIBUCONTEXT_OBJ = ${LIBUCONTEXT_C_SRC:.c=.o} ${LIBUCONTEXT_S_SRC:.S=.o} + LIBUCONTEXT_SOVERSION = 0 +diff --git a/README.md b/README.md +index 6bd4493..27d3d0b 100644 +--- a/README.md ++++ b/README.md +@@ -19,7 +19,7 @@ Right now these archs are supported and should work on bare metal: + * aarch64 + * s390x + +-These archs require kernel assistance and use a syscall (the only assembly is the trampoline): ++These archs require kernel assistance and use a syscall: + + * ppc + * ppc64 (ELFv2 ABI spec only, ELFv1 not supported) +diff --git a/arch/ppc/getcontext.S b/arch/ppc/getcontext.S +new file mode 100644 +index 0000000..beffaf5 +--- /dev/null ++++ b/arch/ppc/getcontext.S +@@ -0,0 +1,20 @@ ++/* ++ * Copyright (c) 2019 Bobby Bingham <koorogi@koorogi.info> ++ * ++ * 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. ++ */ ++ ++.global __getcontext ++.hidden __swapcontext ++__getcontext: ++ li 4, 0 ++ b __swapcontext@local ++ ++.weak getcontext ++getcontext = __getcontext +diff --git a/arch/ppc/getcontext.c b/arch/ppc/retfromsyscall.c +similarity index 53% +rename from arch/ppc/getcontext.c +rename to arch/ppc/retfromsyscall.c +index 5da9dfb..3ad43c0 100644 +--- a/arch/ppc/getcontext.c ++++ b/arch/ppc/retfromsyscall.c +@@ -1,5 +1,6 @@ + /* + * Copyright (c) 2018 William Pitcock <nenolod@dereferenced.org> ++ * Copyright (c) 2019 Bobby Bingham <koorogi@koorogi.info> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above +@@ -10,36 +11,15 @@ + * from the use of this software. + */ + +-#define _GNU_SOURCE +-#include <stddef.h> +-#include <stdarg.h> +-#include <signal.h> +-#include <string.h> +-#include <stdint.h> + #include <errno.h> +-#include <unistd.h> +-#include <sys/syscall.h> + +- +-int +-__getcontext(ucontext_t *ucp) ++__attribute__ ((visibility ("hidden"))) ++int __retfromsyscall(long retval) + { +-#ifdef SYS_swapcontext +- int r; +- +- r = syscall(SYS_swapcontext, ucp, NULL, sizeof(ucontext_t)); +- if (r < 0) +- { +- errno = -r; ++ if (retval < 0) { ++ errno = -retval; + return -1; + } +- + return 0; +-#else +- errno = ENOSYS; +- return -1; +-#endif + } + +- +-extern __typeof(__getcontext) getcontext __attribute__((weak, __alias__("__getcontext"))); +diff --git a/arch/ppc/setcontext.S b/arch/ppc/setcontext.S +new file mode 100644 +index 0000000..89e6de0 +--- /dev/null ++++ b/arch/ppc/setcontext.S +@@ -0,0 +1,21 @@ ++/* ++ * Copyright (c) 2019 Bobby Bingham <koorogi@koorogi.info> ++ * ++ * 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. ++ */ ++ ++.global __setcontext ++.hidden __swapcontext ++__setcontext: ++ mr 4, 3 ++ li 3, 0 ++ b __swapcontext@local ++ ++.weak setcontext ++setcontext = __setcontext +diff --git a/arch/ppc/setcontext.c b/arch/ppc/setcontext.c +deleted file mode 100644 +index 59c65b4..0000000 +--- a/arch/ppc/setcontext.c ++++ /dev/null +@@ -1,45 +0,0 @@ +-/* +- * Copyright (c) 2018 William Pitcock <nenolod@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. +- */ +- +-#define _GNU_SOURCE +-#include <stddef.h> +-#include <stdarg.h> +-#include <signal.h> +-#include <string.h> +-#include <stdint.h> +-#include <errno.h> +-#include <unistd.h> +-#include <sys/syscall.h> +- +- +-int +-__setcontext(const ucontext_t *ucp) +-{ +-#ifdef SYS_swapcontext +- int r; +- +- r = syscall(SYS_swapcontext, NULL, (void *) ucp, sizeof(ucontext_t)); +- if (r < 0) +- { +- errno = -r; +- return -1; +- } +- +- return r; +-#else +- errno = ENOSYS; +- return -1; +-#endif +-} +- +- +-extern __typeof(__setcontext) setcontext __attribute__((weak, __alias__("__setcontext"))); +diff --git a/arch/ppc/swapcontext.S b/arch/ppc/swapcontext.S +new file mode 100644 +index 0000000..24b6655 +--- /dev/null ++++ b/arch/ppc/swapcontext.S +@@ -0,0 +1,23 @@ ++/* ++ * Copyright (c) 2019 Bobby Bingham <koorogi@koorogi.info> ++ * ++ * 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. ++ */ ++ ++.global __swapcontext ++__swapcontext: ++ li 0, 249 # SYS_swapcontext ++ li 5, 1184 # sizeof(ucontext_t) ++ sc ++ ++.hidden __retfromsyscall ++ b __retfromsyscall@local ++ ++.weak swapcontext ++swapcontext = __swapcontext +diff --git a/arch/ppc/swapcontext.c b/arch/ppc/swapcontext.c +deleted file mode 100644 +index af14bc2..0000000 +--- a/arch/ppc/swapcontext.c ++++ /dev/null +@@ -1,45 +0,0 @@ +-/* +- * Copyright (c) 2018 William Pitcock <nenolod@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. +- */ +- +-#define _GNU_SOURCE +-#include <stddef.h> +-#include <stdarg.h> +-#include <signal.h> +-#include <string.h> +-#include <stdint.h> +-#include <errno.h> +-#include <unistd.h> +-#include <sys/syscall.h> +- +- +-int +-__swapcontext(ucontext_t *oucp, const ucontext_t *ucp) +-{ +-#ifdef SYS_swapcontext +- int r; +- +- r = syscall(SYS_swapcontext, oucp, ucp, sizeof(ucontext_t)); +- if (r < 0) +- { +- errno = -r; +- return -1; +- } +- +- return r; +-#else +- errno = ENOSYS; +- return -1; +-#endif +-} +- +- +-extern __typeof(__swapcontext) swapcontext __attribute__((weak, __alias__("__swapcontext"))); +diff --git a/arch/ppc64/getcontext.S b/arch/ppc64/getcontext.S +new file mode 100644 +index 0000000..935edd2 +--- /dev/null ++++ b/arch/ppc64/getcontext.S +@@ -0,0 +1,25 @@ ++/* ++ * Copyright (c) 2019 Bobby Bingham <koorogi@koorogi.info> ++ * ++ * 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. ++ */ ++ ++.global __getcontext ++.hidden __swapcontext ++__getcontext: ++ addis 2, 12, .TOC.-__getcontext@ha ++ addi 2, 12, .TOC.-__getcontext@l ++ ++ .localentry __getcontext,.-__getcontext ++ ++ li 4, 0 ++ b __swapcontext ++ ++.weak getcontext ++getcontext = __getcontext +diff --git a/arch/ppc64/getcontext.c b/arch/ppc64/retfromsyscall.c +similarity index 53% +rename from arch/ppc64/getcontext.c +rename to arch/ppc64/retfromsyscall.c +index 5da9dfb..3ad43c0 100644 +--- a/arch/ppc64/getcontext.c ++++ b/arch/ppc64/retfromsyscall.c +@@ -1,5 +1,6 @@ + /* + * Copyright (c) 2018 William Pitcock <nenolod@dereferenced.org> ++ * Copyright (c) 2019 Bobby Bingham <koorogi@koorogi.info> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above +@@ -10,36 +11,15 @@ + * from the use of this software. + */ + +-#define _GNU_SOURCE +-#include <stddef.h> +-#include <stdarg.h> +-#include <signal.h> +-#include <string.h> +-#include <stdint.h> + #include <errno.h> +-#include <unistd.h> +-#include <sys/syscall.h> + +- +-int +-__getcontext(ucontext_t *ucp) ++__attribute__ ((visibility ("hidden"))) ++int __retfromsyscall(long retval) + { +-#ifdef SYS_swapcontext +- int r; +- +- r = syscall(SYS_swapcontext, ucp, NULL, sizeof(ucontext_t)); +- if (r < 0) +- { +- errno = -r; ++ if (retval < 0) { ++ errno = -retval; + return -1; + } +- + return 0; +-#else +- errno = ENOSYS; +- return -1; +-#endif + } + +- +-extern __typeof(__getcontext) getcontext __attribute__((weak, __alias__("__getcontext"))); +diff --git a/arch/ppc64/setcontext.S b/arch/ppc64/setcontext.S +new file mode 100644 +index 0000000..5a0cde3 +--- /dev/null ++++ b/arch/ppc64/setcontext.S +@@ -0,0 +1,26 @@ ++/* ++ * Copyright (c) 2019 Bobby Bingham <koorogi@koorogi.info> ++ * ++ * 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. ++ */ ++ ++.global __setcontext ++.hidden __swapcontext ++__setcontext: ++ addis 2, 12, .TOC.-__setcontext@ha ++ addi 2, 12, .TOC.-__setcontext@l ++ ++ .localentry __setcontext,.-__setcontext ++ ++ mr 4, 3 ++ li 3, 0 ++ b __swapcontext ++ ++.weak setcontext ++setcontext = __setcontext +diff --git a/arch/ppc64/setcontext.c b/arch/ppc64/setcontext.c +deleted file mode 100644 +index 59c65b4..0000000 +--- a/arch/ppc64/setcontext.c ++++ /dev/null +@@ -1,45 +0,0 @@ +-/* +- * Copyright (c) 2018 William Pitcock <nenolod@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. +- */ +- +-#define _GNU_SOURCE +-#include <stddef.h> +-#include <stdarg.h> +-#include <signal.h> +-#include <string.h> +-#include <stdint.h> +-#include <errno.h> +-#include <unistd.h> +-#include <sys/syscall.h> +- +- +-int +-__setcontext(const ucontext_t *ucp) +-{ +-#ifdef SYS_swapcontext +- int r; +- +- r = syscall(SYS_swapcontext, NULL, (void *) ucp, sizeof(ucontext_t)); +- if (r < 0) +- { +- errno = -r; +- return -1; +- } +- +- return r; +-#else +- errno = ENOSYS; +- return -1; +-#endif +-} +- +- +-extern __typeof(__setcontext) setcontext __attribute__((weak, __alias__("__setcontext"))); +diff --git a/arch/ppc64/swapcontext.S b/arch/ppc64/swapcontext.S +new file mode 100644 +index 0000000..982537a +--- /dev/null ++++ b/arch/ppc64/swapcontext.S +@@ -0,0 +1,28 @@ ++/* ++ * Copyright (c) 2019 Bobby Bingham <koorogi@koorogi.info> ++ * ++ * 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. ++ */ ++ ++.global __swapcontext ++__swapcontext: ++ addis 2, 12, .TOC.-__swapcontext@ha ++ addi 2, 12, .TOC.-__swapcontext@l ++ ++ .localentry __swapcontext,.-__swapcontext ++ ++ li 0, 249 # SYS_swapcontext ++ li 5, 1696 # sizeof(ucontext_t) ++ sc ++ ++.hidden __retfromsyscall ++ b __retfromsyscall ++ ++.weak swapcontext ++swapcontext = __swapcontext +diff --git a/arch/ppc64/swapcontext.c b/arch/ppc64/swapcontext.c +deleted file mode 100644 +index af14bc2..0000000 +--- a/arch/ppc64/swapcontext.c ++++ /dev/null +@@ -1,45 +0,0 @@ +-/* +- * Copyright (c) 2018 William Pitcock <nenolod@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. +- */ +- +-#define _GNU_SOURCE +-#include <stddef.h> +-#include <stdarg.h> +-#include <signal.h> +-#include <string.h> +-#include <stdint.h> +-#include <errno.h> +-#include <unistd.h> +-#include <sys/syscall.h> +- +- +-int +-__swapcontext(ucontext_t *oucp, const ucontext_t *ucp) +-{ +-#ifdef SYS_swapcontext +- int r; +- +- r = syscall(SYS_swapcontext, oucp, ucp, sizeof(ucontext_t)); +- if (r < 0) +- { +- errno = -r; +- return -1; +- } +- +- return r; +-#else +- errno = ENOSYS; +- return -1; +-#endif +-} +- +- +-extern __typeof(__swapcontext) swapcontext __attribute__((weak, __alias__("__swapcontext"))); |