abcc04a5bf
Upstream commit: 224d8c1890b6c57c7e4e8ddbb792dd9552086704 - debug: Synchronize feature guards in fortified functions [BZ #28746] - debug: Autogenerate _FORTIFY_SOURCE tests - Enable _FORTIFY_SOURCE=3 for gcc 12 and above - fortify: Fix spurious warning with realpath - __glibc_unsafe_len: Fix comment - debug: Add tests for _FORTIFY_SOURCE=3 - Make sure that the fortified function conditionals are constant - Don't add access size hints to fortifiable functions - nss: Protect against errno changes in function lookup (bug 28953) - nss: Do not mention NSS test modules in <gnu/lib-names.h> - io: Add fsync call in tst-stat - hppa: Fix warnings from _dl_lookup_address - nptl: Fix cleanups for stack grows up [BZ# 28899] - hppa: Revise gettext trampoline design - hppa: Fix swapcontext - Fix elf/tst-audit2 on hppa - localedef: Handle symbolic links when generating locale-archive - NEWS: Add a bug fix entry for BZ #28896 - x86: Fix TEST_NAME to make it a string in tst-strncmp-rtm.c - x86: Test wcscmp RTM in the wcsncmp overflow case [BZ #28896] - x86: Fallback {str|wcs}cmp RTM in the ncmp overflow case [BZ #28896] - string: Add a testcase for wcsncmp with SIZE_MAX [BZ #28755] - linux: fix accuracy of get_nprocs and get_nprocs_conf [BZ #28865] - Add reference to BZ#28860 on NEWS - linux: Fix missing __convert_scm_timestamps (BZ #28860)
178 lines
5.9 KiB
Diff
178 lines
5.9 KiB
Diff
commit f610d2935f041c5f41ddcb96924ea42ca2fb5ea5
|
|
Author: John David Anglin <danglin@gcc.gnu.org>
|
|
Date: Tue Feb 22 17:28:46 2022 +0000
|
|
|
|
hppa: Revise gettext trampoline design
|
|
|
|
The current getcontext return trampoline is overly complex and it
|
|
unnecessarily clobbers several registers. By saving the context
|
|
pointer (r26) in the context, __getcontext_ret can restore any
|
|
registers not restored by setcontext. This allows getcontext to
|
|
save and restore the entire register context present when getcontext
|
|
is entered. We use the unused oR0 context slot for the return
|
|
from __getcontext_ret.
|
|
|
|
While this is not directly useful in C, it can be exploited in
|
|
assembly code. Registers r20, r23, r24 and r25 are not clobbered
|
|
in the call path to getcontext. This allows a small simplification
|
|
of swapcontext.
|
|
|
|
It also allows saving and restoring the 6-bit SAR register in the
|
|
LSB of the oSAR context slot. The getcontext flag value can be
|
|
stored in the MSB of the oSAR slot.
|
|
|
|
(cherry picked from commit 9e7e5fda38471e00d1190479ea91d7b08ae3e304)
|
|
|
|
diff --git a/sysdeps/unix/sysv/linux/hppa/getcontext.S b/sysdeps/unix/sysv/linux/hppa/getcontext.S
|
|
index c8b690aab8ecc47c..4f2e2587d60effc8 100644
|
|
--- a/sysdeps/unix/sysv/linux/hppa/getcontext.S
|
|
+++ b/sysdeps/unix/sysv/linux/hppa/getcontext.S
|
|
@@ -22,22 +22,28 @@
|
|
#include "ucontext_i.h"
|
|
|
|
|
|
- /* Trampoline function. Non-standard calling ABI. */
|
|
+ /* Trampoline function. Non-standard calling ABI. */
|
|
/* Can not use ENTRY(__getcontext_ret) here. */
|
|
.type __getcontext_ret, @function
|
|
.hidden __getcontext_ret
|
|
__getcontext_ret:
|
|
.proc
|
|
.callinfo FRAME=0,NO_CALLS
|
|
- /* r26-r23 contain original r3-r6, but because setcontext
|
|
- does not reload r3-r6 (it's using them as temporaries)
|
|
- we must save them elsewhere and swap them back in. */
|
|
- copy %r23, %r3
|
|
- copy %r24, %r4
|
|
- copy %r25, %r5
|
|
- copy %r26, %r6
|
|
- /* r20 contains original return pointer. */
|
|
- bv 0(%r20)
|
|
+ /* Because setcontext does not reload r3-r6 (it's using them
|
|
+ as temporaries), we must load them ourself. */
|
|
+ ldw oR3(%r26), %r3
|
|
+ ldw oR4(%r26), %r4
|
|
+ ldw oR5(%r26), %r5
|
|
+ ldw oR6(%r26), %r6
|
|
+
|
|
+ /* Also reload registers clobbered by $$dyncall. */
|
|
+ ldw oR21(%r26), %r21
|
|
+ ldw oR22(%r26), %r22
|
|
+ ldw oR31(%r26), %r31
|
|
+
|
|
+ /* oR0 contains original return pointer. */
|
|
+ ldw oR0(%r26), %rp
|
|
+ bv 0(%rp)
|
|
copy %r0, %ret0
|
|
.procend
|
|
.size __getcontext_ret, .-__getcontext_ret
|
|
@@ -65,13 +71,13 @@ ENTRY(__getcontext)
|
|
stw %r17, oR17(%r26)
|
|
stw %r18, oR18(%r26)
|
|
stw %r19, oR19(%r26)
|
|
- /* stw %r20, oR20(%r26) - used for trampoline. */
|
|
+ stw %r20, oR20(%r26)
|
|
stw %r21, oR21(%r26)
|
|
stw %r22, oR22(%r26)
|
|
- /* stw %r23, oR23(%r26) - used for trampoline. */
|
|
- /* stw %r24, oR24(%r26) - used for trampoline. */
|
|
- /* stw %r25, oR25(%r26) - used for trampoline. */
|
|
- /* stw %r26, oR26(%r26) - used for trampoline. */
|
|
+ stw %r23, oR23(%r26)
|
|
+ stw %r24, oR24(%r26)
|
|
+ stw %r25, oR25(%r26)
|
|
+ stw %r26, oR26(%r26)
|
|
stw %r27, oR27(%r26)
|
|
stw %r28, oR28(%r26)
|
|
stw %r29, oR29(%r26)
|
|
@@ -90,7 +96,10 @@ ENTRY(__getcontext)
|
|
stw %r0, oIASQ1(%r26)
|
|
stw %r0, oIAOQ0(%r26)
|
|
stw %r0, oIAOQ1(%r26)
|
|
- stw %r0, oSAR(%r26) /* used as flag in swapcontext(). */
|
|
+
|
|
+ /* Save SAR register. */
|
|
+ mfctl %sar, %r1
|
|
+ stw %r1, oSAR(%r26) /* MSB used as flag in swapcontext(). */
|
|
|
|
|
|
/* Store floating-point regs. */
|
|
@@ -142,13 +151,8 @@ ENTRY(__getcontext)
|
|
.cfi_offset 29, 4
|
|
|
|
/* Set up the trampoline registers.
|
|
- r20, r23, r24, r25, r26 and r2 are clobbered
|
|
- by call to getcontext() anyway. Reuse them. */
|
|
- stw %r2, oR20(%r26)
|
|
- stw %r3, oR23(%r26)
|
|
- stw %r4, oR24(%r26)
|
|
- stw %r5, oR25(%r26)
|
|
- stw %r6, oR26(%r26)
|
|
+ Use oR0 context slot to save return value. */
|
|
+ stw %r2, oR0(%r26)
|
|
#ifdef PIC
|
|
addil LT%__getcontext_ret, %r19
|
|
ldw RT%__getcontext_ret(%r1), %r1
|
|
diff --git a/sysdeps/unix/sysv/linux/hppa/setcontext.S b/sysdeps/unix/sysv/linux/hppa/setcontext.S
|
|
index e1ae3aefcaac198d..616405b80c61d531 100644
|
|
--- a/sysdeps/unix/sysv/linux/hppa/setcontext.S
|
|
+++ b/sysdeps/unix/sysv/linux/hppa/setcontext.S
|
|
@@ -76,7 +76,7 @@ ENTRY(__setcontext)
|
|
ldw oR18(%r3), %r18
|
|
ldw oR19(%r3), %r19
|
|
ldw oR20(%r3), %r20
|
|
- ldw oR21(%r3), %r21
|
|
+ ldw oR21(%r3), %r21 /* maybe clobbered by dyncall */
|
|
/* ldw oR22(%r3), %r22 - dyncall arg. */
|
|
ldw oR23(%r3), %r23
|
|
ldw oR24(%r3), %r24
|
|
@@ -88,6 +88,10 @@ ENTRY(__setcontext)
|
|
ldw oR30(%r3), %sp
|
|
/* ldw oR31(%r3), %r31 - dyncall scratch register */
|
|
|
|
+ /* Restore SAR register. */
|
|
+ ldw oSAR(%r3), %r22
|
|
+ mtsar %r22
|
|
+
|
|
/* Restore floating-point registers. */
|
|
ldo oFPREGS31(%r3), %r22
|
|
fldds 0(%r22), %fr31
|
|
diff --git a/sysdeps/unix/sysv/linux/hppa/swapcontext.c b/sysdeps/unix/sysv/linux/hppa/swapcontext.c
|
|
index 562f00ff0546177d..1664f68c7b9982e8 100644
|
|
--- a/sysdeps/unix/sysv/linux/hppa/swapcontext.c
|
|
+++ b/sysdeps/unix/sysv/linux/hppa/swapcontext.c
|
|
@@ -26,10 +26,6 @@ extern int __setcontext (const ucontext_t *ucp);
|
|
int
|
|
__swapcontext (ucontext_t *oucp, const ucontext_t *ucp)
|
|
{
|
|
- /* Save ucp in stack argument slot. */
|
|
- asm ("stw %r25,-40(%sp)");
|
|
- asm (".cfi_offset 25, -40");
|
|
-
|
|
/* Save rp for debugger. */
|
|
asm ("stw %rp,-20(%sp)");
|
|
asm (".cfi_offset 2, -20");
|
|
@@ -60,7 +56,7 @@ __swapcontext (ucontext_t *oucp, const ucontext_t *ucp)
|
|
asm ("bv,n %r0(%rp)");
|
|
|
|
/* Load sc_sar flag. */
|
|
- asm ("ldw %0(%%ret1),%%r20" : : "i" (oSAR));
|
|
+ asm ("ldb %0(%%ret1),%%r20" : : "i" (oSAR));
|
|
|
|
/* Return if oucp context has been reactivated. */
|
|
asm ("or,= %r0,%r20,%r0");
|
|
@@ -68,11 +64,11 @@ __swapcontext (ucontext_t *oucp, const ucontext_t *ucp)
|
|
|
|
/* Mark sc_sar flag. */
|
|
asm ("1: ldi 1,%r20");
|
|
- asm ("stw %%r20,%0(%%ret1)" : : "i" (oSAR));
|
|
+ asm ("stb %%r20,%0(%%ret1)" : : "i" (oSAR));
|
|
|
|
/* Activate the machine context in ucp. */
|
|
asm ("bl __setcontext,%rp");
|
|
- asm ("ldw -40(%sp),%r26");
|
|
+ asm ("ldw %0(%%ret1),%%r26" : : "i" (oR25));
|
|
|
|
/* Load return pointer. */
|
|
asm ("ldw %0(%%ret1),%%rp" : : "i" (oR28));
|