about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog40
-rw-r--r--elf/Makefile12
-rw-r--r--elf/dl-open.c16
-rw-r--r--elf/reldep6.c97
-rw-r--r--elf/reldep6mod0.c8
-rw-r--r--elf/reldep6mod1.c14
-rw-r--r--elf/reldep6mod2.c3
-rw-r--r--elf/reldep6mod3.c3
-rw-r--r--elf/reldep6mod4.c12
-rw-r--r--localedata/ChangeLog5
-rw-r--r--localedata/charmaps/SAMI-WS21
-rw-r--r--manual/charset.texi12
-rw-r--r--sysdeps/ieee754/ldbl-128/s_erfl.c2
-rw-r--r--sysdeps/sparc/sparc32/fpu/libm-test-ulps10
-rw-r--r--sysdeps/sparc/sparc64/dl-machine.h139
-rw-r--r--sysdeps/sparc/sparc64/fpu/libm-test-ulps10
-rw-r--r--sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h4
17 files changed, 332 insertions, 56 deletions
diff --git a/ChangeLog b/ChangeLog
index 9d7c828b54..5a4bf26fb6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,43 @@
+2001-09-29  Jes Sorensen  <jes@trained-monkey.org>
+
+	* sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h (struct sigcontext):
+	Add sc_loadrs and sc_rbs_bas to match current kernel.
+
+2001-09-27  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/sparc/sparc64/fpu/libm-test-ulps: Update.
+
+	* sysdeps/ieee754/ldbl-128/s_erfl.c (__erfcl): Fix erfc(-inf).
+
+2001-09-27  Jakub Jelinek  <jakub@redhat.com>
+
+	* elf/dl-open.c (dl_open_worker): If l_opencount of freshly loaded
+	object has been bumped because of relocation dependency, avoid
+	duplicates in l_scope.
+	(show_scope): Fix typos.
+	* elf/Makefile: Add rules to build and run reldep6.
+	* elf/reldep6.c: New file.
+	* elf/reldep6mod0.c: New file.
+	* elf/reldep6mod1.c: New file.
+	* elf/reldep6mod2.c: New file.
+	* elf/reldep6mod3.c: New file.
+	* elf/reldep6mod4.c: New file.
+
+2001-09-26  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/sparc/sparc64/dl-machine.h (elf_machine_fixup_plt): Call
+	sparc64_fixup_plt.
+	(sparc64_fixup_plt): Moved from elf_machine_fixup_plt. Optimize
+	near jumps and 0xfffff800XXXXXXXX target addresses, no thread safety
+	for non-lazy binding. Fix .plt[32768+] handling.
+	(elf_machine_plt_value): Don't add addend.
+	(elf_machine_rela): Call sparc64_fixup_plt instead of
+	elf_machine_fixup_plt.
+	(elf_machine_runtime_setup, TRAMPOLINE_TEMPLATE): Optimize for
+	dynamic linker at 0xfffff800XXXXXXXX.
+
+	* sysdeps/sparc/sparc32/fpu/libm-test-ulps: Update.
+
 2001-09-28  Ulrich Drepper  <drepper@redhat.com>
 
 	* elf/elf.h: Define SHF_GROUP and SHF_TLS.
diff --git a/elf/Makefile b/elf/Makefile
index d4fc54e010..91d7e3a508 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -107,7 +107,7 @@ tests = loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
 	reldep reldep2 reldep3 reldep4 $(tests-nodelete-$(have-z-nodelete)) \
 	$(tests-nodlopen-$(have-z-nodlopen)) neededtest neededtest2 \
 	neededtest3 neededtest4 unload2 lateglobal initfirst global \
-	restest2 next dblload dblunload reldep5
+	restest2 next dblload dblunload reldep5 reldep6
 test-srcs = tst-pathopt
 tests-vis-yes = vismain
 tests-nodelete-yes = nodelete
@@ -123,7 +123,8 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
 		neededobj1 neededobj2 neededobj3 neededobj4 \
 		neededobj5 neededobj6 firstobj globalmod1 \
 		unload2mod unload2dep ltglobmod1 ltglobmod2 pathoptobj \
-		dblloadmod1 dblloadmod2 dblloadmod3 reldepmod5 reldepmod6
+		dblloadmod1 dblloadmod2 dblloadmod3 reldepmod5 reldepmod6 \
+	        reldep6mod0 reldep6mod1 reldep6mod2 reldep6mod3 reldep6mod4
 modules-vis-yes = vismod1 vismod2 vismod3
 modules-nodelete-yes = nodelmod1 nodelmod2 nodelmod3 nodelmod4
 modules-nodlopen-yes = nodlopenmod
@@ -288,6 +289,10 @@ $(objpfx)dblloadmod1.so: $(objpfx)dblloadmod3.so
 $(objpfx)dblloadmod2.so: $(objpfx)dblloadmod3.so
 $(objpfx)reldepmod5.so: $(objpfx)reldepmod2.so
 $(objpfx)reldepmod6.so: $(objpfx)reldepmod2.so
+$(objpfx)reldep6mod1.so: $(objpfx)reldep6mod0.so
+$(objpfx)reldep6mod2.so: $(objpfx)reldep6mod1.so
+$(objpfx)reldep6mod3.so: $(objpfx)reldep6mod2.so
+$(objpfx)reldep6mod4.so: $(objpfx)reldep6mod1.so
 
 # filtmod1.so has a special rule
 $(filter-out $(objpfx)filtmod1.so, $(test-modules)): $(objpfx)%.so: $(objpfx)%.os
@@ -429,3 +434,6 @@ $(objpfx)dblunload.out: $(objpfx)dblloadmod1.so $(objpfx)dblloadmod2.so
 
 $(objpfx)reldep5: $(libdl)
 $(objpfx)reldep5.out: $(objpfx)reldepmod5.so $(objpfx)reldepmod5.so
+
+$(objpfx)reldep6: $(libdl)
+$(objpfx)reldep6.out: $(objpfx)reldep6mod3.so $(objpfx)reldep6mod4.so
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 3f2631a98b..c061cdeb0e 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -312,10 +312,20 @@ dl_open_worker (void *a)
 
 	while (*runp != NULL)
 	  {
+	    /* This can happen if imap was just loaded, but during
+	       relocation had l_opencount bumped because of relocation
+	       dependency.  Avoid duplicates in l_scope.  */
+	    if (__builtin_expect (*runp == &new->l_searchlist, 0))
+	      break;
+
 	    ++cnt;
 	    ++runp;
 	  }
 
+	if (*runp != NULL)
+	  /* Avoid duplicates.  */
+	  continue;
+
 	if (__builtin_expect (cnt + 1 >= imap->l_scope_max, 0))
 	  {
 	    /* The 'r_scope' array is too small.  Allocate a new one
@@ -478,11 +488,11 @@ show_scope (struct link_map *new)
 
       for (cnt = 0; cnt < new->l_scope[scope_cnt]->r_nlist; ++cnt)
 	if (*new->l_scope[scope_cnt]->r_list[cnt]->l_name)
-	  _dl_printf (" %s", new->l_scope[scope_cnt]->r_list[cnt]->l_name)
+	  _dl_printf (" %s", new->l_scope[scope_cnt]->r_list[cnt]->l_name);
 	else
-	  _dl_printf (" <main>", NULL);
+	  _dl_printf (" <main>");
 
-      _dl_printf ("\n", NULL);
+      _dl_printf ("\n");
     }
 }
 #endif
diff --git a/elf/reldep6.c b/elf/reldep6.c
new file mode 100644
index 0000000000..bf80ec5773
--- /dev/null
+++ b/elf/reldep6.c
@@ -0,0 +1,97 @@
+#include <dlfcn.h>
+#include <mcheck.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef int (*fn)(void);
+#define CHUNKS 1024
+#define REPEAT 64
+
+int
+main (void)
+{
+  void *h1;
+  void *h2;
+  fn **foopp;
+  fn bar, baz;
+  int i, j;
+  int n;
+  void *allocs[REPEAT][CHUNKS];
+
+  mtrace ();
+
+  /* Open the two objects.  */
+  h1 = dlopen ("reldep6mod3.so", RTLD_LAZY);
+  if (h1 == NULL)
+    {
+      printf ("cannot open reldep6mod3.so: %s\n", dlerror ());
+      exit (1);
+    }
+
+  foopp = dlsym (h1, "foopp");
+  if (foopp == NULL)
+    {
+      printf ("cannot get address of \"foopp\": %s\n", dlerror ());
+      exit (1);
+    }
+  n = (**foopp) ();
+  if (n != 20)
+    {
+      printf ("(**foopp)() return %d, not return 20\n", n);
+      exit (1);
+    }
+
+  h2 = dlopen ("reldep6mod4.so", RTLD_LAZY);
+  if (h2 == NULL)
+    {
+      printf ("cannot open reldep6mod4.so: %s\n", dlerror ());
+      exit (1);
+    }
+
+  if (dlclose (h1) != 0)
+    {
+      printf ("closing h1 failed: %s\n", dlerror ());
+      exit (1);
+    }
+
+  /* Clobber memory.  */
+  for (i = 0; i < REPEAT; ++i)
+    for (j = 0; j < CHUNKS; ++j)
+      allocs[i][j] = calloc (1, j + 1);
+
+  bar = dlsym (h2, "bar");
+  if (bar == NULL)
+    {
+      printf ("cannot get address of \"bar\": %s\n", dlerror ());
+      exit (1);
+    }
+  if (bar () != 40)
+    {
+      printf ("bar() did not return 40\n");
+      exit (1);
+    }
+
+  baz = dlsym (h2, "baz");
+  if (baz == NULL)
+    {
+      printf ("cannot get address of \"baz\": %s\n", dlerror ());
+      exit (1);
+    }
+  if (baz () != 31)
+    {
+      printf ("baz() did not return 31\n");
+      exit (1);
+    }
+
+  for (i = 0; i < REPEAT; ++i)
+    for (j = 0; j < CHUNKS; ++j)
+      free (allocs[i][j]);
+
+  if (dlclose (h2) != 0)
+    {
+      printf ("closing h2 failed: %s\n", dlerror ());
+      exit (1);
+    }
+
+  return 0;
+}
diff --git a/elf/reldep6mod0.c b/elf/reldep6mod0.c
new file mode 100644
index 0000000000..58f3745fb4
--- /dev/null
+++ b/elf/reldep6mod0.c
@@ -0,0 +1,8 @@
+int bar (void);
+extern void free (void *);
+
+int bar (void)
+{
+  free (0);
+  return 40;
+}
diff --git a/elf/reldep6mod1.c b/elf/reldep6mod1.c
new file mode 100644
index 0000000000..037a73a198
--- /dev/null
+++ b/elf/reldep6mod1.c
@@ -0,0 +1,14 @@
+int foo (void);
+int baz (void);
+extern int weak (void);
+asm (".weak weak");
+
+int foo (void)
+{
+  return 20;
+}
+
+int baz (void)
+{
+  return weak () + 1;
+}
diff --git a/elf/reldep6mod2.c b/elf/reldep6mod2.c
new file mode 100644
index 0000000000..c2ef3f9bc0
--- /dev/null
+++ b/elf/reldep6mod2.c
@@ -0,0 +1,3 @@
+extern int foo (void);
+
+void *foop = (void *) foo;
diff --git a/elf/reldep6mod3.c b/elf/reldep6mod3.c
new file mode 100644
index 0000000000..881828ef6e
--- /dev/null
+++ b/elf/reldep6mod3.c
@@ -0,0 +1,3 @@
+extern void *foop;
+
+void **foopp = &foop;
diff --git a/elf/reldep6mod4.c b/elf/reldep6mod4.c
new file mode 100644
index 0000000000..8fa89de64b
--- /dev/null
+++ b/elf/reldep6mod4.c
@@ -0,0 +1,12 @@
+int foo (void);
+int weak (void);
+
+int foo (void)
+{
+  return 10;
+}
+
+int weak (void)
+{
+  return 30;
+}
diff --git a/localedata/ChangeLog b/localedata/ChangeLog
index 96d84b0d9b..cf8acf09b1 100644
--- a/localedata/ChangeLog
+++ b/localedata/ChangeLog
@@ -1,3 +1,8 @@
+2001-09-30  Ulrich Drepper  <drepper@redhat.com>
+
+	* charmaps/SAMI-WS2: Add Euro sign.
+	Patch by Petter Reinholdtsen <pere@hungry.com>.
+
 2001-08-17  Ulrich Drepper  <drepper@redhat.com>
 
 	* Makefile: Add rules to build and run tst-xlocale2.
diff --git a/localedata/charmaps/SAMI-WS2 b/localedata/charmaps/SAMI-WS2
index 24428ec210..55b8ea6ab7 100644
--- a/localedata/charmaps/SAMI-WS2
+++ b/localedata/charmaps/SAMI-WS2
@@ -139,6 +139,7 @@ CHARMAP
 <U007D>     /x7d         RIGHT CURLY BRACKET
 <U007E>     /x7e         TILDE
 <U007F>     /x7f         DELETE (DEL)
+<U20AC>     /x80         EURO SIGN
 <U010C>     /x82         LATIN CAPITAL LETTER C WITH CARON
 <U0192>     /x83         LATIN SMALL LETTER F WITH HOOK
 <U010D>     /x84         LATIN SMALL LETTER C WITH CARON
diff --git a/manual/charset.texi b/manual/charset.texi
index 39e2062ca0..bb9cc64b8d 100644
--- a/manual/charset.texi
+++ b/manual/charset.texi
@@ -218,8 +218,7 @@ the environment and for the texts to be handled.  There exist a variety
 of different character sets which can be used for this external
 encoding. Information which will not be exhaustively presented
 here--instead, a description of the major groups will suffice.  All of
-the ASCII-based character sets [_bkoz_: do you mean Roman character
-sets? If not, what do you mean here?]  fulfill one requirement: they are
+the ASCII-based character sets fulfill one requirement: they are
 "filesystem safe".  This means that the character @code{'/'} is used in
 the encoding @emph{only} to represent itself.  Things are a bit
 different for character sets like EBCDIC (Extended Binary Coded Decimal
@@ -229,11 +228,12 @@ system calls have to be converted first anyhow.
 
 @itemize @bullet
 @item
-The simplest character sets are single-byte character sets.  There can be
-only up to 256 characters (for @w{8 bit} character sets) which is not
+The simplest character sets are single-byte character sets.  There can
+be only up to 256 characters (for @w{8 bit} character sets) which is not
 sufficient to cover all languages but might be sufficient to handle a
-specific text.  Another reason to choose this is because of constraints
-from interaction with other programs (which might not be 8-bit clean).
+specific text.  Handling of @w{8 bit} character sets is simple.  This is
+not true for the other kinds presented later and therefore the
+application one uses might require the use of @w{8 bit} character sets.
 
 @cindex ISO 2022
 @item
diff --git a/sysdeps/ieee754/ldbl-128/s_erfl.c b/sysdeps/ieee754/ldbl-128/s_erfl.c
index b021cd890d..57202253a6 100644
--- a/sysdeps/ieee754/ldbl-128/s_erfl.c
+++ b/sysdeps/ieee754/ldbl-128/s_erfl.c
@@ -816,7 +816,7 @@ weak_alias (__erf, erfl)
   if (ix >= 0x7fff0000)
     {				/* erfc(nan)=nan */
       /* erfc(+-inf)=0,2 */
-      return (long double) (((sign & 0xffff) >> 15) << 1) + one / x;
+      return (long double) (((u_int32_t) sign >> 31) << 1) + one / x;
     }
 
   if (ix < 0x3ffd0000) /* |x| <1/4 */
diff --git a/sysdeps/sparc/sparc32/fpu/libm-test-ulps b/sysdeps/sparc/sparc32/fpu/libm-test-ulps
index c953aa2b54..f2cdf89c91 100644
--- a/sysdeps/sparc/sparc32/fpu/libm-test-ulps
+++ b/sysdeps/sparc/sparc32/fpu/libm-test-ulps
@@ -451,6 +451,16 @@ ifloat: 1
 Test "j0 (2.0) == 0.22389077914123566805":
 float: 2
 ifloat: 2
+Test "j0 (4.0) == -3.9714980986384737228659076845169804197562E-1"
+double: 1
+idouble: 1
+float: 1
+ifloat: 1
+Test "j0 (-4.0) == -3.9714980986384737228659076845169804197562E-1"
+double: 1
+idouble: 1
+float: 1
+ifloat: 1
 Test "j0 (8.0) == 0.17165080713755390609":
 float: 1
 ifloat: 1
diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h
index 1ef11fdafb..9d2f2187ae 100644
--- a/sysdeps/sparc/sparc64/dl-machine.h
+++ b/sysdeps/sparc/sparc64/dl-machine.h
@@ -84,41 +84,51 @@ elf_machine_load_address (void)
 
 /* We have 4 cases to handle.  And we code different code sequences
    for each one.  I love V9 code models...  */
-static inline Elf64_Addr
-elf_machine_fixup_plt (struct link_map *map, lookup_t t,
-		       const Elf64_Rela *reloc,
-		       Elf64_Addr *reloc_addr, Elf64_Addr value)
+static inline void
+sparc64_fixup_plt (struct link_map *map, const Elf64_Rela *reloc,
+		   Elf64_Addr *reloc_addr, Elf64_Addr value,
+		   Elf64_Addr high, int t)
 {
   unsigned int *insns = (unsigned int *) reloc_addr;
   Elf64_Addr plt_vaddr = (Elf64_Addr) reloc_addr;
+  Elf64_Sxword disp = value - plt_vaddr;
 
   /* Now move plt_vaddr up to the call instruction.  */
-  plt_vaddr += (2 * 4);
+  plt_vaddr += ((t + 1) * 4);
 
   /* PLT entries .PLT32768 and above look always the same.  */
-  if (__builtin_expect (reloc->r_addend, 0) != 0)
+  if (__builtin_expect (high, 0) != 0)
     {
       *reloc_addr = value - map->l_addr;
     }
+  /* Near destination.  */
+  else if (disp >= -0x800000 && disp < 0x800000)
+    {
+      /* As this is just one instruction, it is thread safe and so
+	 we can avoid the unnecessary sethi FOO, %g1.
+	 b,a target  */
+      insns[0] = 0x30800000 | ((disp >> 2) & 0x3fffff);
+      __asm __volatile ("flush %0" : : "r" (insns));
+    }
   /* 32-bit Sparc style, the target is in the lower 32-bits of
      address space.  */
-  else if ((value >> 32) == 0)
+  else if (insns += t, (value >> 32) == 0)
     {
       /* sethi	%hi(target), %g1
 	 jmpl	%g1 + %lo(target), %g0  */
 
-      insns[2] = 0x81c06000 | (value & 0x3ff);
-      __asm __volatile ("flush %0 + 8" : : "r" (insns));
-
-      insns[1] = 0x03000000 | ((unsigned int)(value >> 10));
+      insns[1] = 0x81c06000 | (value & 0x3ff);
       __asm __volatile ("flush %0 + 4" : : "r" (insns));
+
+      insns[0] = 0x03000000 | ((unsigned int)(value >> 10));
+      __asm __volatile ("flush %0" : : "r" (insns));
     }
   /* We can also get somewhat simple sequences if the distance between
      the target and the PLT entry is within +/- 2GB.  */
   else if ((plt_vaddr > value
-	    && ((plt_vaddr - value) >> 32) == 0)
+	    && ((plt_vaddr - value) >> 31) == 0)
 	   || (value > plt_vaddr
-	       && ((value - plt_vaddr) >> 32) == 0))
+	       && ((value - plt_vaddr) >> 31) == 0))
     {
       unsigned int displacement;
 
@@ -131,14 +141,14 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
 	 call	displacement
 	  mov	%g1, %o7  */
 
-      insns[3] = 0x9e100001;
-      __asm __volatile ("flush %0 + 12" : : "r" (insns));
-
-      insns[2] = 0x40000000 | (displacement >> 2);
+      insns[2] = 0x9e100001;
       __asm __volatile ("flush %0 + 8" : : "r" (insns));
 
-      insns[1] = 0x8210000f;
+      insns[1] = 0x40000000 | (displacement >> 2);
       __asm __volatile ("flush %0 + 4" : : "r" (insns));
+
+      insns[t] = 0x8210000f;
+      __asm __volatile ("flush %0" : : "r" (insns));
     }
   /* Worst case, ho hum...  */
   else
@@ -149,33 +159,62 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
       /* ??? Some tricks can be stolen from the sparc64 egcs backend
 	     constant formation code I wrote.  -DaveM  */
 
-      /* sethi	%hh(value), %g1
-	 sethi	%lm(value), %g5
-	 or	%g1, %hm(value), %g1
-	 or	%g5, %lo(value), %g5
-	 sllx	%g1, 32, %g1
-	 jmpl	%g1 + %g5, %g0
-	  nop  */
+      if (__builtin_expect (high32 & 0x3ff, 0))
+	{
+	  /* sethi	%hh(value), %g1
+	     sethi	%lm(value), %g5
+	     or		%g1, %hm(value), %g1
+	     or		%g5, %lo(value), %g5
+	     sllx	%g1, 32, %g1
+	     jmpl	%g1 + %g5, %g0
+	      nop  */
 
-      insns[6] = 0x81c04005;
-      __asm __volatile ("flush %0 + 24" : : "r" (insns));
+	  insns[5] = 0x81c04005;
+	  __asm __volatile ("flush %0 + 20" : : "r" (insns));
 
-      insns[5] = 0x83287020;
-      __asm __volatile ("flush %0 + 20" : : "r" (insns));
+	  insns[4] = 0x83287020;
+	  __asm __volatile ("flush %0 + 16" : : "r" (insns));
 
-      insns[4] = 0x8a116000 | (low32 & 0x3ff);
-      __asm __volatile ("flush %0 + 16" : : "r" (insns));
+	  insns[3] = 0x8a116000 | (low32 & 0x3ff);
+	  __asm __volatile ("flush %0 + 12" : : "r" (insns));
 
-      insns[3] = 0x82106000 | (high32 & 0x3ff);
-      __asm __volatile ("flush %0 + 12" : : "r" (insns));
+	  insns[2] = 0x82106000 | (high32 & 0x3ff);
+	}
+      else
+	{
+	  /* sethi	%hh(value), %g1
+	     sethi	%lm(value), %g5
+	     sllx	%g1, 32, %g1
+	     or		%g5, %lo(value), %g5
+	     jmpl	%g1 + %g5, %g0
+	      nop  */
+
+	  insns[4] = 0x81c04005;
+	  __asm __volatile ("flush %0 + 16" : : "r" (insns));
+
+	  insns[3] = 0x8a116000 | (low32 & 0x3ff);
+	  __asm __volatile ("flush %0 + 12" : : "r" (insns));
+
+	  insns[2] = 0x83287020;
+	}
 
-      insns[2] = 0x0b000000 | (low32 >> 10);
       __asm __volatile ("flush %0 + 8" : : "r" (insns));
 
-      insns[1] = 0x03000000 | (high32 >> 10);
+      insns[1] = 0x0b000000 | (low32 >> 10);
       __asm __volatile ("flush %0 + 4" : : "r" (insns));
+
+      insns[0] = 0x03000000 | (high32 >> 10);
+      __asm __volatile ("flush %0" : : "r" (insns));
     }
+}
 
+static inline Elf64_Addr
+elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+		       const Elf64_Rela *reloc,
+		       Elf64_Addr *reloc_addr, Elf64_Addr value)
+{
+  sparc64_fixup_plt (map, reloc, reloc_addr, value + reloc->r_addend,
+		     reloc->r_addend, 1);
   return value;
 }
 
@@ -184,7 +223,10 @@ static inline Elf64_Addr
 elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
 		       Elf64_Addr value)
 {
-  return value + reloc->r_addend;
+  /* Don't add addend here, but in elf_machine_fixup_plt instead.
+     value + reloc->r_addend is the value which should actually be
+     stored into .plt data slot.  */
+  return value;
 }
 
 #ifdef RESOLVE
@@ -329,7 +371,8 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
 	  break;
 #endif
 	case R_SPARC_JMP_SLOT:
-	  elf_machine_fixup_plt(map, 0, reloc, reloc_addr, value);
+	  sparc64_fixup_plt (map, reloc, reloc_addr, value,
+			     reloc->r_addend, 0);
 	  break;
 #ifndef RTLD_BOOTSTRAP
 	case R_SPARC_UA16:
@@ -425,6 +468,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
       extern void _dl_runtime_profile_1 (void);
       Elf64_Addr res0_addr, res1_addr;
       unsigned int *plt = (void *) D_PTR (l, l_info[DT_PLTGOT]);
+      int i = 0;
 
       if (! profile)
 	{
@@ -473,13 +517,21 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
        */
 
       plt[8 + 0] = 0x9de3bf40;
+      if (__builtin_expect (((res1_addr + 4) >> 32) & 0x3ff, 0))
+	i = 1;
+      else
+	res1_addr += 4;
       plt[8 + 1] = 0x21000000 | (res1_addr >> (64 - 22));
       plt[8 + 2] = 0x23000000 | ((res1_addr >> 10) & 0x003fffff);
-      plt[8 + 3] = 0xa0142000 | ((res1_addr >> 32) & 0x3ff);
+      if (__builtin_expect (i, 0))
+	plt[8 + 3] = 0xa0142000 | ((res1_addr >> 32) & 0x3ff);
+      else
+	plt[8 + 3] = 0xa12c3020;
       plt[8 + 4] = 0xa2146000 | (res1_addr & 0x3ff);
-      plt[8 + 5] = 0xa12c3020;
-      plt[8 + 6] = 0xadc40011;
-      plt[8 + 7] = 0x9330700c;
+      if (__builtin_expect (i, 0))
+	plt[8 + 5] = 0xa12c3020;
+      plt[8 + 5 + i] = 0xadc40011;
+      plt[8 + 6 + i] = 0x9330700c;
 
       /* Now put the magic cookie at the beginning of .PLT2
 	 Entry .PLT3 is unused by this implementation.  */
@@ -526,10 +578,11 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
 "\n"							\
 "	.globl	" #tramp_name "_1\n"			\
 "	.type	" #tramp_name "_1, @function\n"		\
-"	.align	32\n"					\
+"	! tramp_name_1 + 4 needs to be .align 32\n"	\
 "\t" #tramp_name "_1:\n"				\
+"	sub	%l6, 4, %l6\n"				\
 "	! srlx	%g1, 12, %o1 - Done in .PLT1\n"		\
-"	ldx	[%l6 + 8], %o0\n"			\
+"	ldx	[%l6 + 12], %o0\n"			\
 "	add	%o1, %o1, %o3\n"			\
 "	sub	%o1, 96, %o1	! No thanks to Sun for not obeying their own ABI\n" \
 "	mov	%i7, %o2\n"				\
diff --git a/sysdeps/sparc/sparc64/fpu/libm-test-ulps b/sysdeps/sparc/sparc64/fpu/libm-test-ulps
index 2bacd03900..01e9060fd0 100644
--- a/sysdeps/sparc/sparc64/fpu/libm-test-ulps
+++ b/sysdeps/sparc/sparc64/fpu/libm-test-ulps
@@ -562,6 +562,16 @@ ifloat: 1
 Test "j0 (2.0) == 0.22389077914123566805":
 float: 2
 ifloat: 2
+Test "j0 (4.0) == -3.9714980986384737228659076845169804197562E-1"
+double: 1
+idouble: 1
+float: 1
+ifloat: 1
+Test "j0 (-4.0) == -3.9714980986384737228659076845169804197562E-1"
+double: 1
+idouble: 1
+float: 1
+ifloat: 1
 Test "j0 (8.0) == 0.17165080713755390609":
 float: 1
 ifloat: 1
diff --git a/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h b/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h
index d86bf66b81..8a87375e77 100644
--- a/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h
+++ b/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h
@@ -48,7 +48,9 @@ struct sigcontext
   unsigned long int sc_br[8];	/* branch registers */
   unsigned long int sc_gr[32];	/* general registers (static partition) */
   struct ia64_fpreg sc_fr[128];	/* floating-point registers */
-  unsigned long int sc_rsvd[16];/* reserved for future use */
+  unsigned long int sc_rbs_base;/* NULL or new base of sighandler's rbs */
+  unsigned long int sc_loadrs;	/* see description above */
+  unsigned long int sc_rsvd[14];/* reserved for future use */
 
   /* sc_mask is actually an sigset_t but we don't want to
    * include the kernel headers here. */