Bug#799478: glibc: revised atomic and new syscall patches for hppa
Source: glibc
Version: 13
Severity: normal
Tags: patch
Dear Maintainer,
Attached are two patches for hppa. Both use the register asm feature
of gcc to load arguments to specific registers prior to a syscall.
The updated atomic patch avoids the infamous "can't find a register in
class R1_REGS" and avoids the noinline function in the previous version.
The old hppa/local-atomic.diff patch needs to be deleted before applying
the hppa/submitted-atomic.diff change.
The syscall patch fixes the miscompilation of sched_setaffinity(). It
is similar to the fix applied to other archs.
Both patches have been submitted and applied to the upstream glibc source:
https://sourceware.org/bugzilla/show_bug.cgi?id=18787
https://sourceware.org/ml/libc-alpha/2015-08/msg00266.html
I would appreciate your adding these two changes to the set of hppa
changes.
I now need to look at 2.21...
Thanks,
Dave
-- System Information:
Debian Release: stretch/sid
APT prefers unreleased
APT policy: (500, 'unreleased'), (500, 'unstable')
Architecture: hppa (parisc64)
Kernel: Linux 3.18.21+ (SMP w/4 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) (ignored: LC_ALL set to en_CA.utf8)
Shell: /bin/sh linked to /bin/dash
Init: sysvinit (via /sbin/init)
Index: glibc-2.19/ports/sysdeps/unix/sysv/linux/hppa/bits/atomic.h
===================================================================
--- glibc-2.19.orig/ports/sysdeps/unix/sysv/linux/hppa/bits/atomic.h
+++ glibc-2.19/ports/sysdeps/unix/sysv/linux/hppa/bits/atomic.h
@@ -53,7 +53,7 @@ typedef uintmax_t uatomic_max_t;
#define _LWS "0xb0"
#define _LWS_CAS "0"
/* Note r31 is the link register. */
-#define _LWS_CLOBBER "r1", "r26", "r25", "r24", "r23", "r22", "r21", "r20", "r28", "r31", "memory"
+#define _LWS_CLOBBER "r1", "r23", "r22", "r20", "r31", "memory"
/* String constant for -EAGAIN. */
#define _ASM_EAGAIN "-11"
/* String constant for -EDEADLOCK. */
@@ -63,25 +63,23 @@ typedef uintmax_t uatomic_max_t;
/* The only basic operation needed is compare and exchange. */
# define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
({ \
- volatile int lws_errno; \
- volatile int lws_ret; \
+ register int lws_errno asm("r21"); \
+ register int lws_ret asm("r28"); \
+ register unsigned long lws_mem asm("r26") = (unsigned long)(mem); \
+ register unsigned long lws_old asm("r25") = (unsigned long)(oldval);\
+ register unsigned long lws_new asm("r24") = (unsigned long)(newval);\
asm volatile( \
"0: \n\t" \
- "copy %2, %%r26 \n\t" \
- "copy %3, %%r25 \n\t" \
- "copy %4, %%r24 \n\t" \
"ble " _LWS "(%%sr2, %%r0) \n\t" \
"ldi " _LWS_CAS ", %%r20 \n\t" \
- "ldi " _ASM_EAGAIN ", %%r24 \n\t" \
- "cmpb,=,n %%r24, %%r21, 0b \n\t" \
+ "ldi " _ASM_EAGAIN ", %%r20 \n\t" \
+ "cmpb,=,n %%r20, %%r21, 0b \n\t" \
"nop \n\t" \
- "ldi " _ASM_EDEADLOCK ", %%r25 \n\t" \
- "cmpb,=,n %%r25, %%r21, 0b \n\t" \
+ "ldi " _ASM_EDEADLOCK ", %%r20 \n\t" \
+ "cmpb,=,n %%r20, %%r21, 0b \n\t" \
"nop \n\t" \
- "stw %%r28, %0 \n\t" \
- "stw %%r21, %1 \n\t" \
- : "=m" (lws_ret), "=m" (lws_errno) \
- : "r" (mem), "r" (oldval), "r" (newval) \
+ : "=r" (lws_ret), "=r" (lws_errno) \
+ : "r" (lws_mem), "r" (lws_old), "r" (lws_new) \
: _LWS_CLOBBER \
); \
\
Index: glibc-2.19/ports/sysdeps/unix/sysv/linux/hppa/sysdep.h
===================================================================
--- glibc-2.19.orig/ports/sysdeps/unix/sysv/linux/hppa/sysdep.h
+++ glibc-2.19/ports/sysdeps/unix/sysv/linux/hppa/sysdep.h
@@ -361,9 +361,10 @@ L(pre_end): ASM_LINE_SEP \
({ \
long __sys_res; \
{ \
+ LOAD_ARGS_##nr(args) \
register unsigned long __res asm("r28"); \
PIC_REG_DEF \
- LOAD_ARGS_##nr(args) \
+ LOAD_REGS_##nr \
/* FIXME: HACK save/load r19 around syscall */ \
asm volatile( \
SAVE_ASM_PIC \
@@ -407,9 +408,10 @@ L(pre_end): ASM_LINE_SEP \
({ \
long __sys_res; \
{ \
+ LOAD_ARGS_##nr(args) \
register unsigned long __res asm("r28"); \
PIC_REG_DEF \
- LOAD_ARGS_##nr(args) \
+ LOAD_REGS_##nr \
/* FIXME: HACK save/load r19 around syscall */ \
asm volatile( \
SAVE_ASM_PIC \
@@ -432,9 +434,10 @@ L(pre_end): ASM_LINE_SEP \
({ \
long __sys_res; \
{ \
+ LOAD_ARGS_##nr(args) \
register unsigned long __res asm("r28"); \
PIC_REG_DEF \
- LOAD_ARGS_##nr(args) \
+ LOAD_REGS_##nr \
/* FIXME: HACK save/load r19 around syscall */ \
asm volatile( \
SAVE_ASM_PIC \
@@ -453,24 +456,43 @@ L(pre_end): ASM_LINE_SEP \
#define LOAD_ARGS_0()
-#define LOAD_ARGS_1(r26) \
- register unsigned long __r26 __asm__("r26") = (unsigned long)(r26); \
+#define LOAD_REGS_0
+#define LOAD_ARGS_1(a1) \
+ register unsigned long __x26 = (unsigned long)(a1); \
LOAD_ARGS_0()
-#define LOAD_ARGS_2(r26,r25) \
- register unsigned long __r25 __asm__("r25") = (unsigned long)(r25); \
- LOAD_ARGS_1(r26)
-#define LOAD_ARGS_3(r26,r25,r24) \
- register unsigned long __r24 __asm__("r24") = (unsigned long)(r24); \
- LOAD_ARGS_2(r26,r25)
-#define LOAD_ARGS_4(r26,r25,r24,r23) \
- register unsigned long __r23 __asm__("r23") = (unsigned long)(r23); \
- LOAD_ARGS_3(r26,r25,r24)
-#define LOAD_ARGS_5(r26,r25,r24,r23,r22) \
- register unsigned long __r22 __asm__("r22") = (unsigned long)(r22); \
- LOAD_ARGS_4(r26,r25,r24,r23)
-#define LOAD_ARGS_6(r26,r25,r24,r23,r22,r21) \
- register unsigned long __r21 __asm__("r21") = (unsigned long)(r21); \
- LOAD_ARGS_5(r26,r25,r24,r23,r22)
+#define LOAD_REGS_1 \
+ register unsigned long __r26 __asm__("r26") = __x26; \
+ LOAD_REGS_0
+#define LOAD_ARGS_2(a1,a2) \
+ register unsigned long __x25 = (unsigned long)(a2); \
+ LOAD_ARGS_1(a1)
+#define LOAD_REGS_2 \
+ register unsigned long __r25 __asm__("r25") = __x25; \
+ LOAD_REGS_1
+#define LOAD_ARGS_3(a1,a2,a3) \
+ register unsigned long __x24 = (unsigned long)(a3); \
+ LOAD_ARGS_2(a1,a2)
+#define LOAD_REGS_3 \
+ register unsigned long __r24 __asm__("r24") = __x24; \
+ LOAD_REGS_2
+#define LOAD_ARGS_4(a1,a2,a3,a4) \
+ register unsigned long __x23 = (unsigned long)(a4); \
+ LOAD_ARGS_3(a1,a2,a3)
+#define LOAD_REGS_4 \
+ register unsigned long __r23 __asm__("r23") = __x23; \
+ LOAD_REGS_3
+#define LOAD_ARGS_5(a1,a2,a3,a4,a5) \
+ register unsigned long __x22 = (unsigned long)(a5); \
+ LOAD_ARGS_4(a1,a2,a3,a4)
+#define LOAD_REGS_5 \
+ register unsigned long __r22 __asm__("r22") = __x22; \
+ LOAD_REGS_4
+#define LOAD_ARGS_6(a1,a2,a3,a4,a5,a6) \
+ register unsigned long __x21 = (unsigned long)(a6); \
+ LOAD_ARGS_5(a1,a2,a3,a4,a5)
+#define LOAD_REGS_6 \
+ register unsigned long __r21 __asm__("r21") = __x21; \
+ LOAD_REGS_5
/* Even with zero args we use r20 for the syscall number */
#define ASM_ARGS_0
Index: glibc-2.19/ports/sysdeps/unix/sysv/linux/hppa/sysdep.c
===================================================================
--- glibc-2.19.orig/ports/sysdeps/unix/sysv/linux/hppa/sysdep.c
+++ glibc-2.19/ports/sysdeps/unix/sysv/linux/hppa/sysdep.c
@@ -56,9 +56,10 @@ syscall (long int __sysno, ...)
va_end (args);
{
+ LOAD_ARGS_6 (arg0, arg1, arg2, arg3, arg4, arg5)
register unsigned long int __res asm("r28");
PIC_REG_DEF
- LOAD_ARGS_6 (arg0, arg1, arg2, arg3, arg4, arg5)
+ LOAD_REGS_6
asm volatile (SAVE_ASM_PIC
" ble 0x100(%%sr2, %%r0) \n"
" copy %1, %%r20 \n"
Reply to: