Package: glibc
Version: 2.19-18
Severity: normal
Tags: patch

Attached are five new patches to be imported to the hppa patch directory.

The submitted-fpu-r2.diff patch is a replacement for hppa/local-fpu.diff.
The hppa/local-fpu.diff patch must be deleted before applying
submitted-fpu-r2.diff.  The submitted-fpu-r2.diff patch improves the
handling of the floating point status register.  The patch has been
applied to trunk.

The submitted-fpu2.diff is from Carlos O'Donnel and has been applied
to trunk.  It contains further improvements to the handling of the
floating point context.

The local-fptr-table-size.diff patch improves the determination of the
size of the string table in the dynamic loader.  This help fix some
issues with the libgomp testsuite in gcc.  Again the patch is from
Carlos.

The local-setcontext.diff patch corrects a minor issue in __setcontext.
It should exit using "exit" so that the registered handlers are run.
This has been installed as part of a larger change on the trunk.

The submitted-start.diff patch fixes a PIE problem.  The Scrt1 object
needs to be position independent when generating PIE code.  The patch
adjusts the sections and relocations used when SHARED is defined so that
the generated code doesn't contain dynamic relocations in read-only
sections.  This patch is from Alan Modra.

I would greatly appreciat the application of these patches.

-- System Information:
Debian Release: stretch/sid
  APT prefers unreleased
  APT policy: (500, 'unreleased'), (500, 'unstable')
Architecture: hppa (parisc64)

Kernel: Linux 3.17.8+ (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)
2015-03-07  John David Anglin  <dang...@gcc.gnu.org>

	* ports/sysdeps/hppa/fpu/feholdexcpt.c (feholdexcept): Don't modify
	bufptr in asms.
	* ports/sysdeps/hppa/fpu/fesetenv.c (fesetenv): Likewise.

Index: glibc-2.19/ports/sysdeps/hppa/fpu/feholdexcpt.c
===================================================================
--- glibc-2.19.orig/ports/sysdeps/hppa/fpu/feholdexcpt.c
+++ glibc-2.19/ports/sysdeps/hppa/fpu/feholdexcpt.c
@@ -29,8 +29,8 @@ feholdexcept (fenv_t *envp)
   /* Store the environment.  */
   bufptr = clear.buf;
   __asm__ (
-	   "fstd,ma %%fr0,8(%1)\n"
-	   : "=m" (clear), "+r" (bufptr) : : "%r0");
+	   "fstd %%fr0,0(%1)\n"
+	   : "=m" (clear) : "r" (bufptr) : "%r0");
   memcpy (envp, &clear.env, sizeof (fenv_t));
 
   /* Clear exception queues */
@@ -40,11 +40,9 @@ feholdexcept (fenv_t *envp)
   /* Now clear all flags  */
   clear.env.__status_word &= ~(FE_ALL_EXCEPT << 27);
 
-  /* Load the new environment. Note: fr0 must load last to enable T-bit
-     Thus we start bufptr at the end and work backwards */
-  bufptr = (unsigned long long *)((unsigned int)(clear.buf) + sizeof(unsigned int)*4);
+  /* Load the new environment. Note: fr0 must load last to enable T-bit.  */
   __asm__ (
-	   "fldd,mb -8(%0),%%fr0\n"
+	   "fldd 0(%0),%%fr0\n"
 	   : : "r" (bufptr), "m" (clear) : "%r0");
 
   return 0;
Index: glibc-2.19/ports/sysdeps/hppa/fpu/fesetenv.c
===================================================================
--- glibc-2.19.orig/ports/sysdeps/hppa/fpu/fesetenv.c
+++ glibc-2.19/ports/sysdeps/hppa/fpu/fesetenv.c
@@ -33,7 +33,7 @@ fesetenv (const fenv_t *envp)
      we want to use from the environment specified by the parameter.  */
   bufptr = temp.buf;
   __asm__ (
-	   "fstd,ma %%fr0,8(%1)\n"
+	   "fstd %%fr0,0(%1)\n"
 	   : "=m" (temp) : "r" (bufptr) : "%r0");
 
   temp.env.__status_word &= ~(FE_ALL_EXCEPT
@@ -54,7 +54,7 @@ fesetenv (const fenv_t *envp)
      we take advantage of that to load in reverse order so fr0
      is loaded last and T-Bit is enabled. */
   __asm__ (
-	   "fldd,mb -8(%1),%%fr0\n"
+	   "fldd 0(%1),%%fr0\n"
 	   : : "m" (temp), "r" (bufptr) : "%r0" );
 
   /* Success.  */
Index: glibc-2.19/ports/sysdeps/hppa/fpu/feupdateenv.c
===================================================================
--- glibc-2.19.orig/ports/sysdeps/hppa/fpu/feupdateenv.c
+++ glibc-2.19/ports/sysdeps/hppa/fpu/feupdateenv.c
@@ -29,9 +29,22 @@ feupdateenv (const fenv_t *envp)
   __asm__ ("fstd %%fr0,0(%1)	\n\t"
            "fldd 0(%1),%%fr0	\n\t"
 	   : "=m" (s.l) : "r" (&s.l));
-  memcpy(&temp, envp, sizeof(fenv_t));
-  /* Currently raised exceptions not cleared */
-  temp.__status_word |= s.sw[0] & (FE_ALL_EXCEPT << 27);
+
+  /* Given environment with exception flags not cleared.  */
+  if ((envp != FE_DFL_ENV) && (envp != FE_NOMASK_ENV))
+    {
+      memcpy(&temp, envp, sizeof(fenv_t));
+      temp.__status_word |= s.sw[0] & (FE_ALL_EXCEPT << 27);
+    }
+
+  /* Default environment with exception flags not cleared.  */
+  if (envp == FE_DFL_ENV)
+    temp.__status_word = s.sw[0] & (FE_ALL_EXCEPT << 27);
+
+  /* All traps enabled and current exception flags not cleared.  */
+  if (envp == FE_NOMASK_ENV)
+    temp.__status_word = (s.sw[0] & (FE_ALL_EXCEPT << 27)) | FE_ALL_EXCEPT;
+
   /* Install new environment.  */
   fesetenv (&temp);
   /* Success.  */
Index: glibc-2.19/ports/sysdeps/hppa/fpu/fpu_control.h
===================================================================
--- glibc-2.19.orig/ports/sysdeps/hppa/fpu/fpu_control.h
+++ glibc-2.19/ports/sysdeps/hppa/fpu/fpu_control.h
@@ -19,7 +19,7 @@
 #ifndef _FPU_CONTROL_H
 #define _FPU_CONTROL_H
 
-/* Masking of interrupts */
+/* Masking of interrupts.  */
 #define _FPU_MASK_PM	0x00000001	/* Inexact (I) */
 #define _FPU_MASK_UM	0x00000002	/* Underflow (U) */
 #define _FPU_MASK_OM	0x00000004	/* Overflow (O) */
@@ -30,6 +30,8 @@
 #define _FPU_HPPA_MASK_RM	0x00000600	/* Rounding mode mask */
 /* Masking of interrupt enable bits.  */
 #define _FPU_HPPA_MASK_INT	0x0000001f	/* Interrupt mask */
+/* Shift by 27 to install flag bits.  */
+#define _FPU_HPPA_SHIFT_FLAGS  27
 
 /* There are no reserved bits in the PA fpsr (though some are undefined).  */
 #define _FPU_RESERVED	0x00000000
@@ -45,7 +47,7 @@ typedef unsigned int fpu_control_t;
 #define _FPU_GETCW(cw) \
 ({										\
   union { __extension__ unsigned long long __fpreg; unsigned int __halfreg[2]; } __fullfp; \
-  /* Get the current status word. */						\
+  /* Get the current status word.  */						\
   __asm__ ("fstd %%fr0,0(%1)\n\t"						\
            "fldd 0(%1),%%fr0\n\t"						\
 	   : "=m" (__fullfp.__fpreg) : "r" (&__fullfp.__fpreg) : "%r0");	\
@@ -54,7 +56,10 @@ typedef unsigned int fpu_control_t;
 
 #define _FPU_SETCW(cw) \
 ({										\
-  union { __extension__ unsigned long long __fpreg; unsigned int __halfreg[2]; } __fullfp;	\
+  union { __extension__ unsigned long long __fpreg; unsigned int __halfreg[2]; } __fullfp; \
+  /* Get the current status word and set the control word.  */			\
+  __asm__ ("fstd %%fr0,0(%1)\n\t"						\
+	   : "=m" (__fullfp.__fpreg) : "r" (&__fullfp.__fpreg) : "%r0");	\
   __fullfp.__halfreg[0] = cw;							\
   __asm__ ("fldd 0(%1),%%fr0\n\t"						\
 	   : : "m" (__fullfp.__fpreg), "r" (&__fullfp.__fpreg) : "%r0" );	\
Index: glibc-2.19/ports/sysdeps/hppa/fpu/fsetexcptflg.c
===================================================================
--- glibc-2.19.orig/ports/sysdeps/hppa/fpu/fsetexcptflg.c
+++ glibc-2.19/ports/sysdeps/hppa/fpu/fsetexcptflg.c
@@ -18,19 +18,25 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <fenv.h>
-#include <math.h>
+#include <fpu_control.h>
 
 int
 fesetexceptflag (const fexcept_t *flagp, int excepts)
 {
-  union { unsigned long long l; unsigned int sw[2]; } s;
+  fpu_control_t fpsr;
+  fpu_control_t fpsr_new;
 
   /* Get the current status word. */
-  __asm__ ("fstd %%fr0,0(%1)" : "=m" (s.l) : "r" (&s.l) : "%r0");
-  /* Install new raised trap bits */
-  s.sw[0] |= (*flagp & excepts & FE_ALL_EXCEPT) << 27;
+  _FPU_GETCW (fpsr);
+  excepts &= FE_ALL_EXCEPT;
+
+  /* Install new raised flags.  */
+  fpsr_new = fpsr & ~(excepts << _FPU_HPPA_SHIFT_FLAGS);
+  fpsr_new |= (*flagp & excepts) << _FPU_HPPA_SHIFT_FLAGS;
+
   /* Store the new status word.  */
-  __asm__ ("fldd 0(%0),%%fr0" : : "r" (&s.l), "m" (s.l) : "%r0");
+  if (fpsr != fpsr_new)
+    _FPU_SETCW (fpsr_new);
 
   /* Success.  */
   return 0;
Index: glibc-2.19/ports/sysdeps/hppa/dl-fptr.c
===================================================================
--- glibc-2.19.orig/ports/sysdeps/hppa/dl-fptr.c
+++ glibc-2.19/ports/sysdeps/hppa/dl-fptr.c
@@ -27,6 +27,7 @@
 #include <elf/dynamic-link.h>
 #include <dl-fptr.h>
 #include <atomic.h>
+#include <libc-internal.h>
 
 #ifndef ELF_MACHINE_BOOT_FPTR_TABLE_LEN
 /* ELF_MACHINE_BOOT_FPTR_TABLE_LEN should be greater than the number of
@@ -180,24 +181,29 @@ make_fdesc (ElfW(Addr) ip, ElfW(Addr) gp
 static inline ElfW(Addr) * __attribute__ ((always_inline))
 make_fptr_table (struct link_map *map)
 {
-  const ElfW(Sym) *symtab
-    = (const void *) D_PTR (map, l_info[DT_SYMTAB]);
+  const ElfW(Sym) *symtab = (const void *) D_PTR (map, l_info[DT_SYMTAB]);
   const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
   ElfW(Addr) *fptr_table;
   size_t size;
   size_t len;
+  const ElfW(Sym) *symtabend;
 
-  /* XXX Apparently the only way to find out the size of the dynamic
-     symbol section is to assume that the string table follows right
-     afterwards...  */
-  len = ((strtab - (char *) symtab)
+  /* Determine the end of the dynamic symbol table using the hash.  */
+  if (map->l_info[DT_HASH] != NULL)
+    symtabend = (symtab + ((Elf_Symndx *) D_PTR (map, l_info[DT_HASH]))[1]);
+  else
+  /* There is no direct way to determine the number of symbols in the
+     dynamic symbol table and no hash table is present.  The ELF
+     binary is ill-formed but what shall we do?  Use the beginning of
+     the string table which generally follows the symbol table.  */
+    symtabend = (const ElfW(Sym) *) strtab;
+
+  len = (((char *) symtabend - (char *) symtab)
 	 / map->l_info[DT_SYMENT]->d_un.d_val);
-  size = ((len * sizeof (fptr_table[0]) + GLRO(dl_pagesize) - 1)
-	  & -GLRO(dl_pagesize));
-  /* XXX We don't support here in the moment systems without MAP_ANON.
-     There probably are none for IA-64.  In case this is proven wrong
-     we will have to open /dev/null here and use the file descriptor
-     instead of the hard-coded -1.  */
+  size = ALIGN_UP (len * sizeof (fptr_table[0]), GLRO(dl_pagesize));
+
+  /* We don't support systems without MAP_ANON.  We avoid using malloc
+     because this might get called before malloc is setup.  */
   fptr_table = __mmap (NULL, size,
 		       PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,
 		       -1, 0);
Index: glibc-2.19/ports/sysdeps/unix/sysv/linux/hppa/setcontext.S
===================================================================
--- glibc-2.19.orig/ports/sysdeps/unix/sysv/linux/hppa/setcontext.S
+++ glibc-2.19/ports/sysdeps/unix/sysv/linux/hppa/setcontext.S
@@ -139,8 +139,8 @@ ENTRY(__setcontext)
 	nop
 
 	/* No further context available. Exit now.  */
-	bl	_exit, %r2
-	ldi	-1, %r26
+	bl	HIDDEN_JUMPTARGET(exit), %r2
+	ldi	0, %r26
 
 
 .Lerror:
Index: glibc-2.19/ports/sysdeps/hppa/start.S
===================================================================
--- glibc-2.19.orig/ports/sysdeps/hppa/start.S
+++ glibc-2.19/ports/sysdeps/hppa/start.S
@@ -42,7 +42,11 @@
 	/* Have the linker create plabel words so we get PLABEL32
 	   relocs and not 21/14.  The use of 21/14 relocs is only
 	   supported in the latest dynamic linker.  */
-	.section	.rodata
+#ifdef SHARED
+	.section	.data.rel.ro,"aw",@progbits
+#else
+	.section	.rodata,"a",@progbits
+#endif
 	.align 4
 .Lpmain:
 	.word P%main
@@ -52,6 +56,10 @@
 	.word P%__libc_csu_fini
 .Lp__libc_csu_init:
 	.word P%__libc_csu_init
+#ifdef SHARED
+.Lp__global:
+	.word $global$
+#endif
 
 	.text
 	.align 4
@@ -122,10 +130,14 @@ _start:
 	/* void *stack_end (7th argument) */
 	stw	%sp, -60(%sp)
 
+#ifdef SHARED
+	addil	LT'.Lp__global, %r19
+	ldw	RT'.Lp__global(%r1), %dp
+#else
 	/* load global */
 	ldil	L%$global$, %dp
 	ldo	R%$global$(%dp), %dp
-
+#endif
 	bl	__libc_start_main,%r2
 	nop
 	/* die horribly if it returned (it shouldn't) */

Reply via email to