diff options
author | John David Anglin <danglin@gcc.gnu.org> | 2022-02-18 20:38:25 +0000 |
---|---|---|
committer | John David Anglin <danglin@gcc.gnu.org> | 2022-02-18 20:38:25 +0000 |
commit | 71b108d7eb33b2bf3e61d5e92d2a47f74c1f7d96 (patch) | |
tree | 7b6e41d7d80ea103e0f7a8279b63576634687388 /sysdeps/unix/sysv/linux/hppa/setcontext.S | |
parent | c6272098323153db373f2986c67786ea8c85f1cf (diff) | |
download | glibc-71b108d7eb33b2bf3e61d5e92d2a47f74c1f7d96.tar.gz glibc-71b108d7eb33b2bf3e61d5e92d2a47f74c1f7d96.tar.xz glibc-71b108d7eb33b2bf3e61d5e92d2a47f74c1f7d96.zip |
hppa: Fix swapcontext
This change fixes the failure of stdlib/tst-setcontext2 and stdlib/tst-setcontext7 on hppa. The implementation of swapcontext in C is broken. C saves the return pointer (rp) and any non call-clobbered registers (in this case r3, r4 and r5) on the stack. However, the setcontext call in swapcontext pops the stack and subsequent calls clobber the saved registers. When the context in oucp is restored, both tests fault. Here we rewrite swapcontext in assembly code to avoid using the stack for register values that need to be used after restoration. The getcontext and setcontext routines are revised to save and restore register ret1 for normal returns. We copy the oucp pointer to ret1. This allows access to the old context after calling getcontext and setcontext.
Diffstat (limited to 'sysdeps/unix/sysv/linux/hppa/setcontext.S')
-rw-r--r-- | sysdeps/unix/sysv/linux/hppa/setcontext.S | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/sysdeps/unix/sysv/linux/hppa/setcontext.S b/sysdeps/unix/sysv/linux/hppa/setcontext.S index bc4872c8e2..5da01c2f35 100644 --- a/sysdeps/unix/sysv/linux/hppa/setcontext.S +++ b/sysdeps/unix/sysv/linux/hppa/setcontext.S @@ -33,6 +33,8 @@ ENTRY(__setcontext) stw %r19, -32(%sp) .cfi_offset 19, 32 #endif + stw %ret1, -60(%sp) + .cfi_offset 29, 4 /* Save ucp. */ copy %r26, %r3 @@ -154,6 +156,7 @@ ENTRY(__setcontext) #ifdef PIC ldw -32(%r30), %r19 #endif + ldw -60(%r30), %ret1 bv %r0(%r2) ldwm -64(%r30), %r3 L(pseudo_end): |