summaryrefslogtreecommitdiff
path: root/system/libucontext/ppc64-assembly.patch
diff options
context:
space:
mode:
Diffstat (limited to 'system/libucontext/ppc64-assembly.patch')
-rw-r--r--system/libucontext/ppc64-assembly.patch331
1 files changed, 331 insertions, 0 deletions
diff --git a/system/libucontext/ppc64-assembly.patch b/system/libucontext/ppc64-assembly.patch
new file mode 100644
index 000000000..66fb3104d
--- /dev/null
+++ b/system/libucontext/ppc64-assembly.patch
@@ -0,0 +1,331 @@
+From 7b864e86e3e8e64fe69363137384ee9b858fe78d Mon Sep 17 00:00:00 2001
+From: Bobby Bingham <koorogi@koorogi.info>
+Date: Sat, 23 Feb 2019 17:12:37 -0600
+Subject: [PATCH 2/3] ppc64: rewrite get/set/swapcontext in assembly
+
+If getcontext makes any function call, which it does to call syscall, then
+it must spill its return address to the stack. After it returns to its
+caller, that return address can be clobbered. When setcontext is called
+to resume this saved context, the correct return address is not available.
+---
+ Makefile | 10 ++-------
+ arch/ppc64/getcontext.S | 25 +++++++++++++++++++++
+ arch/ppc64/getcontext.c | 45 -------------------------------------
+ arch/ppc64/retfromsyscall.c | 24 ++++++++++++++++++++
+ arch/ppc64/setcontext.S | 26 +++++++++++++++++++++
+ arch/ppc64/setcontext.c | 45 -------------------------------------
+ arch/ppc64/swapcontext.S | 28 +++++++++++++++++++++++
+ arch/ppc64/swapcontext.c | 45 -------------------------------------
+ 8 files changed, 105 insertions(+), 143 deletions(-)
+ create mode 100644 arch/ppc64/getcontext.S
+ delete mode 100644 arch/ppc64/getcontext.c
+ create mode 100644 arch/ppc64/retfromsyscall.c
+ 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/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/getcontext.c
+deleted file mode 100644
+index 5da9dfb..0000000
+--- a/arch/ppc64/getcontext.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
+-__getcontext(ucontext_t *ucp)
+-{
+-#ifdef SYS_swapcontext
+- int r;
+-
+- r = syscall(SYS_swapcontext, ucp, NULL, sizeof(ucontext_t));
+- if (r < 0)
+- {
+- errno = -r;
+- return -1;
+- }
+-
+- return 0;
+-#else
+- errno = ENOSYS;
+- return -1;
+-#endif
+-}
+-
+-
+-extern __typeof(__getcontext) getcontext __attribute__((weak, __alias__("__getcontext")));
+diff --git a/arch/ppc64/retfromsyscall.c b/arch/ppc64/retfromsyscall.c
+new file mode 100644
+index 0000000..22c5134
+--- /dev/null
++++ b/arch/ppc64/retfromsyscall.c
+@@ -0,0 +1,24 @@
++/*
++ * 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.
++ */
++
++#include <errno.h>
++
++__attribute__ ((visibility ("hidden")))
++int __retfromsyscall(long retval)
++{
++ if (retval < 0) {
++ errno = -retval;
++ return -1;
++ }
++ return 0;
++}
++
+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")));
+--
+2.19.2
+