From c47e78b10f6b18532951fb6f6b0c5a2e8afcf88e Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Mon, 1 Oct 2001 00:14:14 +0000 Subject: [PATCH] Update. 2001-09-29 Jes Sorensen * 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 * sysdeps/sparc/sparc64/fpu/libm-test-ulps: Update. * sysdeps/ieee754/ldbl-128/s_erfl.c (__erfcl): Fix erfc(-inf). 2001-09-27 Jakub Jelinek * 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 * 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. --- ChangeLog | 40 +++++ elf/Makefile | 12 +- elf/dl-open.c | 16 +- elf/reldep6.c | 97 ++++++++++++ elf/reldep6mod0.c | 8 + elf/reldep6mod1.c | 14 ++ elf/reldep6mod2.c | 3 + elf/reldep6mod3.c | 3 + elf/reldep6mod4.c | 12 ++ localedata/ChangeLog | 5 + localedata/charmaps/SAMI-WS2 | 1 + manual/charset.texi | 12 +- sysdeps/ieee754/ldbl-128/s_erfl.c | 2 +- sysdeps/sparc/sparc32/fpu/libm-test-ulps | 10 ++ sysdeps/sparc/sparc64/dl-machine.h | 139 ++++++++++++------ sysdeps/sparc/sparc64/fpu/libm-test-ulps | 10 ++ .../unix/sysv/linux/ia64/bits/sigcontext.h | 4 +- 17 files changed, 332 insertions(+), 56 deletions(-) create mode 100644 elf/reldep6.c create mode 100644 elf/reldep6mod0.c create mode 100644 elf/reldep6mod1.c create mode 100644 elf/reldep6mod2.c create mode 100644 elf/reldep6mod3.c create mode 100644 elf/reldep6mod4.c diff --git a/ChangeLog b/ChangeLog index 9d7c828b54..5a4bf26fb6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,43 @@ +2001-09-29 Jes Sorensen + + * 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 + + * sysdeps/sparc/sparc64/fpu/libm-test-ulps: Update. + + * sysdeps/ieee754/ldbl-128/s_erfl.c (__erfcl): Fix erfc(-inf). + +2001-09-27 Jakub Jelinek + + * 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 + + * 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 * 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 ("
", NULL); + _dl_printf ("
"); - _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 +#include +#include +#include + +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 + + * charmaps/SAMI-WS2: Add Euro sign. + Patch by Petter Reinholdtsen . + 2001-08-17 Ulrich Drepper * 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 /x7d RIGHT CURLY BRACKET /x7e TILDE /x7f DELETE (DEL) + /x80 EURO SIGN /x82 LATIN CAPITAL LETTER C WITH CARON /x83 LATIN SMALL LETTER F WITH HOOK /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. */