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"