summaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1998-09-16 17:54:34 +0000
committerUlrich Drepper <drepper@redhat.com>1998-09-16 17:54:34 +0000
commit9c4c002459bd2665ac1ad544e56952ec7797e8dd (patch)
tree9d2faf3588e279b3b99748cdf7ccdceefe6a7092 /sysdeps
parenta8125d855218832508af812df585c5fac5093bc3 (diff)
Update.
1998-09-14 Andreas Jaeger <aj@arthur.rhein-neckar.de> * sysdeps/mach/hurd/dl-cache.c (_dl_unload_cache): New dummy function. Reported by okuji@kuicr.kyoto-u.ac.jp [PR libc/789]. 1998-09-15 David S. Miller <davem@pierdol.cobaltmicro.com> * sysdeps/sparc/sparc32/dl-machine.h (elf_machine_runtime_setup): Add profiling support. (TRAMPOLINE_TEMPLATE): New macro. (ELF_MACHINE_RUNTIME_TRAMPOLINE): Define in terms of that. (RTLD_START): Prettify, and set __libc_stack_end properly. (elf_machine_rela) [R_SPARC_COPY]: Remove RTLD_BOOTSTRAP ifndef and check for sym being NULL instead. * sysdeps/sparc/sparc64/addmul_1.S: Adjust to allocate 192 bytes of stack space. * sysdeps/sparc/sparc64/lshift.S: Likewise. * sysdeps/sparc/sparc64/mul_1.S: Likewise. * sysdeps/sparc/sparc64/rshift.S: Likewise. * sysdeps/sparc/sparc64/submul_1.S: Likewise. * sysdeps/sparc/sparc64/elf/crtbegin.S: Likewise and remove old MEDANY code model %g4 usage. * sysdeps/sparc/sparc64/elf/crtend.S: Likewise and remove old MEDANY code model %g4 usage. * sysdeps/sparc/sparc64/elf/start.S: Rework to not use old FULLANY code model address formation. * sysdeps/sparc/sparc64/dl-machine.h: Don't include link.h, do include elf/ldsodefs.h (DT_SPARC): Remove. (elf_machine_matches_host): It is now EM_SPARCV9. (elf_machine_dynamic): Clean up to remove ugly cast. (elf_machine_fixup_plt): Rework for new V9 ABI, add support for new PLT formats. (elf_machine_rela): Don't do anything at all for R_SPARC_NONE. Prettify rest of function. [R_SPARC_COPY]: Check for sym being NULL. [R_SPARC_32]: Handle it. [R_SPARC_H44, R_SPARC_M44, R_SPARC_L44]: Handle them for the MEDMID code model. [R_SPARC_HH22, R_SPARC_HM10, R_SPARC_LM22]: Handle them for the MEDANY code model. [R_SPARC_NONE]: Remove this case, as it is now checked earlier. (elf_machine_runtime_setup): Rewrite for new V9 ABI plt formats. Add profiling support. (TRAMPOLINE_TEMPLATE): New macro. (ELF_MACHINE_RUNTIME_TRAMPOLINE): Define in terms of that. (RTLD_START): Prettify and set __libc_stack_end. * sysdeps/unix/sysv/linux/sparc/bits/sigaction.h (SA_SIGINFO): Define. * sysdeps/unix/sysv/linux/sparc/bits/signum.h (_NSIG): Set to 64. (SIGRTMIN, SIGRTMAX, __SIGRTMIN, __SIGRTMAX): Define. * sysdeps/unix/sysv/linux/sparc/sparc32/brk.c (__brk): Remove unused variable scratch. * sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c (__syscall_rt_sigaction, __rt_sigreturn_stub, __sigreturn_stub): Declare. (__sigaction): Rewrite rt_sigaction case to pass correct sigreturn stub to rt_sigaction syscalls. Rewrite non-rt case to use correct old format kernel sigaction structures. * sysdeps/unix/sysv/linux/sparc/sparc64/ucontext.h: Move... * sysdeps/unix/sysv/linux/sparc/sparc64/sys/ucontext.h: to here. * sysdeps/unix/sysv/linux/sparc/sparc64/Dist: Remove ucontext.h * sysdeps/unix/sysv/linux/sparc/sparc64/bits/setjmp.h: Fix ucontext include. (_JMPBUF_UNWINDS): Define. * sysdeps/unix/sysv/linux/sparc/sparc64/bits/statfs.h: Declare statfs64 structure, which is exactly the same as the normal one. * sysdeps/unix/sysv/linux/sparc/sparc64/brk.S: Allocate 192 bytes of stack. Use correct syscall trap number. Add branch prediction settings to branch instructions. Remove old MEDANY code model %g4 referneces for non-PIC. * sysdeps/unix/sysv/linux/sparc/sparc64/clone.S: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/init-first.h: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S: Add __libc_longjmp and __libc_siglongjmp strong aliases. * sysdeps/unix/sysv/linux/sparc/sparc64/readdir.c (__readdir64): Also define to __no__readdir64_decl around readdir.c inclusion. (__readdir64): Add strong alias. * sysdeps/unix/sysv/linux/sparc/sparc64/socket.S: New file. * sysdeps/unix/sysv/linux/sparc/sparc64/syscalls.list (getrlimit): Set strong and weak names properly. 1998-09-16 11:25 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * manual/Makefile (AWK): Default to gawk if standalone. 1998-09-15 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * Makefile (distribute): Undo last change. * Make-dist (+tsrc) [not subdir]: Also include indirection headers for sysdep headers. (+subdir-headers): Removed, unused. 1998-09-15 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * stdio-common/Makefile ($(inst_includedir)/bits/stdio_lim.h): Use $(do-install). 1998-09-15 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * Makerules ($(+sysdir_pfx)sysd-Makefile): Don't check for absolute name in $(config-sysdirs), can never happen. ($(+sysdir_pfx)sysd-rules): Likewise. * Makeconfig (full-config-sysdirs): Likewise. (all-Subdirs-files): Prepend $(..). * configure.in: Don't check for absolute name in $add_ons_pfx, can not happen. Let --enable-add-ons=yes work if no add-ons actually exist. 1998-09-15 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * Rules ($(common-objpfx)bits/stdio_%.h): Remove extra continuations in command. 1998-09-15 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * libio/oldstdfiles.c (_IO_stdin_used): Update declaration.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/mach/hurd/dl-cache.c5
-rw-r--r--sysdeps/sparc/sparc32/dl-machine.h77
-rw-r--r--sysdeps/sparc/sparc64/addmul_1.S2
-rw-r--r--sysdeps/sparc/sparc64/dl-machine.h330
-rw-r--r--sysdeps/sparc/sparc64/elf/crtbegin.S3
-rw-r--r--sysdeps/sparc/sparc64/elf/crtend.S3
-rw-r--r--sysdeps/sparc/sparc64/elf/start.S24
-rw-r--r--sysdeps/sparc/sparc64/lshift.S2
-rw-r--r--sysdeps/sparc/sparc64/mul_1.S2
-rw-r--r--sysdeps/sparc/sparc64/rshift.S2
-rw-r--r--sysdeps/sparc/sparc64/submul_1.S2
-rw-r--r--sysdeps/unix/sysv/linux/sparc/bits/sigaction.h2
-rw-r--r--sysdeps/unix/sysv/linux/sparc/bits/signum.h13
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/brk.c2
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c92
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/Dist1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/bits/setjmp.h7
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/bits/statfs.h16
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/brk.S15
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/clone.S7
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/init-first.h7
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S2
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S2
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/readdir.c3
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/sys/ucontext.h (renamed from sysdeps/unix/sysv/linux/sparc/sparc64/ucontext.h)6
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S2
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/syscalls.list2
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h53
28 files changed, 507 insertions, 177 deletions
diff --git a/sysdeps/mach/hurd/dl-cache.c b/sysdeps/mach/hurd/dl-cache.c
index e7aca39aee..8b47cf073b 100644
--- a/sysdeps/mach/hurd/dl-cache.c
+++ b/sysdeps/mach/hurd/dl-cache.c
@@ -22,3 +22,8 @@ _dl_load_cache_lookup (const char *name)
{
return 0;
}
+
+void
+_dl_unload_cache (void)
+{
+}
diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h
index da15e94a69..e1fb2b68ce 100644
--- a/sysdeps/sparc/sparc32/dl-machine.h
+++ b/sysdeps/sparc/sparc32/dl-machine.h
@@ -101,14 +101,26 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
{
Elf32_Addr *plt;
extern void _dl_runtime_resolve (Elf32_Word);
+ extern void _dl_runtime_profile (Elf32_Word);
if (l->l_info[DT_JMPREL] && lazy)
{
+ Elf32_Addr rfunc;
+
/* The entries for functions in the PLT have not yet been filled in.
Their initial contents will arrange when called to set the high 22
bits of %g1 with an offset into the .rela.plt section and jump to
the beginning of the PLT. */
plt = (Elf32_Addr *) (l->l_addr + l->l_info[DT_PLTGOT]->d_un.d_ptr);
+ if (! profile)
+ rfunc = (Elf32_Addr) &_dl_runtime_resolve;
+ else
+ {
+ rfunc = (Elf32_Addr) &_dl_runtime_profile;
+
+ if (_dl_name_match_p (_dl_profile, l))
+ _dl_profile_map = l;
+ }
/* The beginning of the PLT does:
@@ -123,8 +135,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
plt[0] = OPCODE_SAVE_SP;
/* Construct PC-relative word address. */
- plt[1] = OPCODE_CALL | (((Elf32_Addr) &_dl_runtime_resolve -
- (Elf32_Addr) &plt[1]) >> 2);
+ plt[1] = OPCODE_CALL | ((rfunc - (Elf32_Addr) &plt[1]) >> 2);
plt[2] = OPCODE_NOP; /* Fill call delay slot. */
plt[3] = (Elf32_Addr) l;
}
@@ -134,20 +145,36 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
/* This code is used in dl-runtime.c to call the `fixup' function
and then redirect to the address it returns. */
-#define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\
- .globl _dl_runtime_resolve
- .type _dl_runtime_resolve, @function
-_dl_runtime_resolve:
+#define TRAMPOLINE_TEMPLATE(tramp_name, fixup_name) \
+ asm ( "\
+ .text
+ .globl " #tramp_name "
+ .type " #tramp_name ", @function
+ .align 32
+" #tramp_name ":
/* Set up the arguments to fixup --
%o0 = link_map out of plt0
- %o1 = offset of reloc entry */
+ %o1 = offset of reloc entry
+ %o2 = return address */
ld [%o7 + 8], %o0
srl %g1, 10, %o1
- call fixup
+ mov %i7, %o2
+ call " #fixup_name "
sub %o1, 4*12, %o1
jmp %o0
restore
- .size _dl_runtime_resolve, . - _dl_runtime_resolve");
+ .size " #tramp_name ", . - " #tramp_name "
+ .previous")
+
+#ifndef PROF
+#define ELF_MACHINE_RUNTIME_TRAMPOLINE \
+ TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup); \
+ TRAMPOLINE_TEMPLATE (_dl_runtime_profile, profile_fixup);
+#else
+#define ELF_MACHINE_RUNTIME_TRAMPOLINE \
+ TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup); \
+ TRAMPOLINE_TEMPLATE (_dl_runtime_profile, fixup);
+#endif
/* Nonzero iff TYPE should not be allowed to resolve to one of
the main executable's symbols, as for a COPY reloc. */
@@ -171,9 +198,10 @@ _dl_runtime_resolve:
its return value is the user program's entry point. */
#define RTLD_START __asm__ ("\
-.text
- .globl _start
- .type _start,@function
+ .text
+ .globl _start
+ .type _start, @function
+ .align 32
_start:
/* Allocate space for functions to drop their arguments. */
sub %sp, 6*4, %sp
@@ -181,8 +209,8 @@ _start:
call _dl_start
add %sp, 22*4, %o0
/* FALTHRU */
- .globl _dl_start_user
- .type _dl_start_user,@function
+ .globl _dl_start_user
+ .type _dl_start_user, @function
_dl_start_user:
/* Load the PIC register. */
1: call 2f
@@ -191,6 +219,12 @@ _dl_start_user:
add %l7, %o7, %l7
/* Save the user entry point address in %l0 */
mov %o0, %l0
+ /* Store the highest stack address. */
+ sethi %hi(__libc_stack_end), %g2
+ or %g2, %lo(__libc_stack_end), %g2
+ ld [%l7 + %g2], %l1
+ add %sp, 6*4, %l2
+ st %l2, [%l1]
/* See if we were run as a command with the executable file name as an
extra leading argument. If so, adjust the contents of the stack. */
sethi %hi(_dl_skip_args), %g2
@@ -230,7 +264,7 @@ _dl_start_user:
st %i4, [%i1+4]
bne 23b
add %i1, 8, %i1
- /* Load _dl_main_searchlist to pass to _dl_init_next. */
+ /* Load searchlist of the main object to pass to _dl_init_next. */
3: sethi %hi(_dl_main_searchlist), %g1
or %g1, %lo(_dl_main_searchlist), %g1
ld [%l7+%g1], %l1
@@ -242,8 +276,7 @@ _dl_start_user:
beq 5f
nop
jmpl %o0, %o7
- nop
- ba,a 4b
+ sub %o7, 28, %o7
/* Clear the startup flag. */
5: sethi %hi(_dl_starting_up), %g1
or %g1, %lo(_dl_starting_up), %g1
@@ -256,8 +289,8 @@ _dl_start_user:
/* Jump to the user's entry point and deallocate the extra stack we got. */
jmp %l0
add %sp, 6*4, %sp
- .size _dl_start_user,.-_dl_start_user
-.previous");
+ .size _dl_start_user, . - _dl_start_user
+ .previous");
static inline void
elf_machine_fixup_plt (struct link_map *map, const Elf32_Rela *reloc,
@@ -343,7 +376,10 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
switch (ELF32_R_TYPE (reloc->r_info))
{
case R_SPARC_COPY:
-#ifndef RTLD_BOOTSTRAP
+ if (sym == NULL)
+ /* This can happen in trace mode if an object could not be
+ found. */
+ break;
if (sym->st_size > refsym->st_size
|| (_dl_verbose && sym->st_size < refsym->st_size))
{
@@ -359,7 +395,6 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
}
memcpy (reloc_addr, (void *) value, MIN (sym->st_size,
refsym->st_size));
-#endif
break;
case R_SPARC_GLOB_DAT:
case R_SPARC_32:
diff --git a/sysdeps/sparc/sparc64/addmul_1.S b/sysdeps/sparc/sparc64/addmul_1.S
index 260481230f..6782db77df 100644
--- a/sysdeps/sparc/sparc64/addmul_1.S
+++ b/sysdeps/sparc/sparc64/addmul_1.S
@@ -32,7 +32,7 @@
ENTRY(__mpn_addmul_1)
!#PROLOGUE# 0
- save %sp,-128,%sp
+ save %sp,-192,%sp
!#PROLOGUE# 1
sub %g0,%i2,%o7
diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h
index 788e239779..33def6b455 100644
--- a/sysdeps/sparc/sparc64/dl-machine.h
+++ b/sysdeps/sparc/sparc64/dl-machine.h
@@ -21,19 +21,15 @@
#include <assert.h>
#include <string.h>
-#include <link.h>
#include <sys/param.h>
+#include <elf/ldsodefs.h>
#include <sysdep.h>
-
-/* Translate a processor-specific dynamic tag to the index into l_info. */
-#define DT_SPARC(x) (DT_SPARC_##x - DT_LOPROC + DT_NUM)
-
/* Return nonzero iff E_MACHINE is compatible with the running host. */
static inline int
elf_machine_matches_host (Elf64_Half e_machine)
{
- return e_machine == EM_SPARC64;
+ return e_machine == EM_SPARCV9;
}
/* Return the link-time address of _DYNAMIC. Conveniently, this is the
@@ -42,12 +38,11 @@ elf_machine_matches_host (Elf64_Half e_machine)
static inline Elf64_Addr
elf_machine_dynamic (void)
{
- register Elf64_Addr elf_pic_register __asm__("%l7");
+ register Elf64_Addr *elf_pic_register __asm__("%l7");
- return *(Elf64_Addr *)elf_pic_register;
+ return *elf_pic_register;
}
-
/* Return the run-time load address of the shared object. */
static inline Elf64_Addr
elf_machine_load_address (void)
@@ -67,21 +62,92 @@ elf_machine_load_address (void)
return pc - *(Elf64_Addr *)(elf_pic_register + la);
}
+/* We have 3 cases to handle. And we code different code sequences
+ for each one. I love V9 code models... */
static inline void
elf_machine_fixup_plt(struct link_map *map, const Elf64_Rela *reloc,
Elf64_Addr *reloc_addr, Elf64_Addr value)
{
- Elf64_Dyn *pltfmt = map->l_info[DT_SPARC(PLTFMT)];
- switch (pltfmt ? pltfmt->d_un.d_val : 0)
+ unsigned int *insns = (unsigned int *) reloc_addr;
+ Elf64_Addr plt_vaddr = (Elf64_Addr) reloc_addr;
+
+ /* Now move plt_vaddr up to the call instruction. */
+ plt_vaddr += (2 * 4);
+
+ /* 32-bit Sparc style, the target is in the lower 32-bits of
+ address space. */
+ if ((value >> 32) == 0)
{
- case 1: /* .got.plt with absolute addresses */
- *reloc_addr = value;
- break;
- case 2: /* .got.plt with got-relative addresses */
- *reloc_addr = value - (map->l_info[DT_PLTGOT]->d_un.d_ptr + map->l_addr);
- break;
- default:
- assert (! "unexpected .plt format type");
+ /* 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));
+ __asm __volatile ("flush %0 + 4" : : "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)
+ || (value > plt_vaddr
+ && ((value - plt_vaddr) >> 32) == 0))
+ {
+ unsigned int displacement;
+
+ if (plt_vaddr > value)
+ displacement = (0 - (plt_vaddr - value));
+ else
+ displacement = value - plt_vaddr;
+
+ /* mov %o7, %g1
+ call displacement
+ mov %g1, %o7 */
+
+ insns[3] = 0x9e100001;
+ __asm __volatile ("flush %0 + 12" : : "r" (insns));
+
+ insns[2] = 0x40000000 | (displacement >> 2);
+ __asm __volatile ("flush %0 + 8" : : "r" (insns));
+
+ insns[1] = 0x8210000f;
+ __asm __volatile ("flush %0 + 4" : : "r" (insns));
+ }
+ /* Worst case, ho hum... */
+ else
+ {
+ unsigned int high32 = (value >> 32);
+ unsigned int low32 = (unsigned int) value;
+
+ /* ??? Some tricks can be stolen from the sparc64 egcs backend
+ constant formation code I wrote. -DaveM */
+
+ /* sethi %hh(value), %g1
+ sethi %lm(value), %g2
+ or %g1, %hl(value), %g1
+ or %g2, %lo(value), %g2
+ sllx %g1, 32, %g1
+ jmpl %g1 + %g2, %g0
+ nop */
+
+ insns[6] = 0x81c04002;
+ __asm __volatile ("flush %0 + 24" : : "r" (insns));
+
+ insns[5] = 0x83287020;
+ __asm __volatile ("flush %0 + 20" : : "r" (insns));
+
+ insns[4] = 0x8410a000 | (low32 & 0x3ff);
+ __asm __volatile ("flush %0 + 16" : : "r" (insns));
+
+ insns[3] = 0x82106000 | (high32 & 0x3ff);
+ __asm __volatile ("flush %0 + 12" : : "r" (insns));
+
+ insns[2] = 0x05000000 | (low32 >> 10);
+ __asm __volatile ("flush %0 + 8" : : "r" (insns));
+
+ insns[1] = 0x03000000 | (high32 >> 10);
+ __asm __volatile ("flush %0 + 4" : : "r" (insns));
}
}
@@ -119,7 +185,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
#endif
*reloc_addr = map->l_addr + reloc->r_addend;
}
- else
+ else if (ELF64_R_TYPE (reloc->r_info) != R_SPARC_NONE) /* Who is Wilbur? */
{
const Elf64_Sym *const refsym = sym;
Elf64_Addr value;
@@ -137,6 +203,10 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
switch (ELF64_R_TYPE (reloc->r_info))
{
case R_SPARC_COPY:
+ if (sym == NULL)
+ /* This can happen in trace mode if an object could not be
+ found. */
+ break;
if (sym->st_size > refsym->st_size
|| (_dl_verbose && sym->st_size < refsym->st_size))
{
@@ -164,6 +234,9 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
case R_SPARC_16:
*(short *) reloc_addr = value;
break;
+ case R_SPARC_32:
+ *(unsigned int *) reloc_addr = value;
+ break;
case R_SPARC_DISP8:
*(char *) reloc_addr = (value - (Elf64_Addr) reloc_addr);
break;
@@ -171,27 +244,64 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
*(short *) reloc_addr = (value - (Elf64_Addr) reloc_addr);
break;
case R_SPARC_DISP32:
- *(unsigned int *)reloc_addr = (value - (Elf64_Addr) reloc_addr);
- break;
- case R_SPARC_LO10:
- *(unsigned *)reloc_addr = (*(unsigned *)reloc_addr & ~0x3ff)
- | (value & 0x3ff);
+ *(unsigned int *) reloc_addr = (value - (Elf64_Addr) reloc_addr);
break;
case R_SPARC_WDISP30:
- *(unsigned *)reloc_addr = ((*(unsigned *)reloc_addr & 0xc0000000)
- | ((value - (Elf64_Addr) reloc_addr) >> 2));
+ *(unsigned int *) reloc_addr =
+ ((*(unsigned int *)reloc_addr & 0xc0000000) |
+ ((value - (Elf64_Addr) reloc_addr) >> 2));
+ break;
+
+ /* MEDLOW code model relocs */
+ case R_SPARC_LO10:
+ *(unsigned int *) reloc_addr =
+ ((*(unsigned int *)reloc_addr & ~0x3ff) |
+ (value & 0x3ff));
break;
case R_SPARC_HI22:
- *(unsigned *)reloc_addr = (*(unsigned *)reloc_addr & 0xffc00000)
- | (value >> 10);
+ *(unsigned int *) reloc_addr =
+ ((*(unsigned int *)reloc_addr & 0xffc00000) |
+ (value >> 10));
+ break;
+
+ /* MEDMID code model relocs */
+ case R_SPARC_H44:
+ *(unsigned int *) reloc_addr =
+ ((*(unsigned int *)reloc_addr & 0xffc00000) |
+ (value >> 22));
+ break;
+ case R_SPARC_M44:
+ *(unsigned int *) reloc_addr =
+ ((*(unsigned int *)reloc_addr & ~0x3ff) |
+ ((value >> 12) & 0x3ff));
+ break;
+ case R_SPARC_L44:
+ *(unsigned int *) reloc_addr =
+ ((*(unsigned int *)reloc_addr & ~0xfff) |
+ (value & 0xfff));
+ break;
+
+ /* MEDANY code model relocs */
+ case R_SPARC_HH22:
+ *(unsigned int *) reloc_addr =
+ ((*(unsigned int *)reloc_addr & 0xffc00000) |
+ (value >> 42));
+ break;
+ case R_SPARC_HM10:
+ *(unsigned int *) reloc_addr =
+ ((*(unsigned int *)reloc_addr & ~0x3ff) |
+ ((value >> 32) & 0x3ff));
+ break;
+ case R_SPARC_LM22:
+ *(unsigned int *) reloc_addr =
+ ((*(unsigned int *)reloc_addr & 0xffc00000) |
+ ((value >> 10) & 0x003fffff));
break;
case R_SPARC_JMP_SLOT:
elf_machine_fixup_plt(map, reloc, reloc_addr, value);
break;
- case R_SPARC_NONE: /* Alright, Wilbur. */
- break;
default:
assert (! "unexpected dynamic reloc type");
break;
@@ -239,16 +349,63 @@ elf_machine_lazy_rel (Elf64_Addr l_addr, const Elf64_Rela *reloc)
static inline int
elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
{
- Elf64_Addr *got;
- extern void _dl_runtime_resolve (void);
-
if (l->l_info[DT_JMPREL] && lazy)
{
- got = (Elf64_Addr *) (l->l_addr + l->l_info[DT_PLTGOT]->d_un.d_ptr);
- /* This function will get called to fix up the GOT entry indicated by
- the offset on the stack, and then jump to the resolved address. */
- got[1] = (Elf64_Addr) &_dl_runtime_resolve;
- got[2] = (Elf64_Addr) l; /* Identify this shared object. */
+ extern void _dl_runtime_resolve_0 (void);
+ extern void _dl_runtime_resolve_1 (void);
+ extern void _dl_runtime_profile_0 (void);
+ extern void _dl_runtime_profile_1 (void);
+ Elf64_Addr res0_addr, res1_addr;
+ unsigned int *plt = (unsigned int *)
+ (l->l_addr + l->l_info[DT_PLTGOT]->d_un.d_ptr);
+
+ if (! profile)
+ {
+ res0_addr = (Elf64_Addr) &_dl_runtime_resolve_0;
+ res1_addr = (Elf64_Addr) &_dl_runtime_resolve_1;
+ }
+ else
+ {
+ res0_addr = (Elf64_Addr) &_dl_runtime_profile_0;
+ res1_addr = (Elf64_Addr) &_dl_runtime_profile_1;
+ if (_dl_name_match_p (_dl_profile, l))
+ _dl_profile_map = l;
+ }
+
+ /* PLT0 looks like:
+
+ save %sp, -192, %sp
+ sethi %hh(_dl_runtime_{resolve,profile}_0), %g3
+ sethi %lm(_dl_runtime_{resolve,profile}_0), %g4
+ or %g3, %hm(_dl_runtime_{resolve,profile}_0), %g3
+ or %g4, %lo(_dl_runtime_{resolve,profile}_0), %g4
+ sllx %g3, 32, %g3
+ jmpl %g3 + %g4, %o0
+ nop
+
+ PLT1 is similar except we jump to _dl_runtime_{resolve,profile}_1. */
+
+ plt[0] = 0x9de3bf40;
+ plt[1] = 0x07000000 | (res0_addr >> (64 - 22));
+ plt[2] = 0x09000000 | ((res0_addr >> 10) & 0x003fffff);
+ plt[3] = 0x8610e000 | ((res0_addr >> 32) & 0x3ff);
+ plt[4] = 0x88112000 | (res0_addr & 0x3ff);
+ plt[5] = 0x8728f020;
+ plt[6] = 0x91c0c004;
+ plt[7] = 0x01000000;
+
+ plt[8 + 0] = 0x9de3bf40;
+ plt[8 + 1] = 0x07000000 | (res1_addr >> (64 - 22));
+ plt[8 + 2] = 0x09000000 | ((res1_addr >> 10) & 0x003fffff);
+ plt[8 + 3] = 0x8610e000 | ((res1_addr >> 32) & 0x3ff);
+ plt[8 + 4] = 0x88112000 | (res1_addr & 0x3ff);
+ plt[8 + 5] = 0x8728f020;
+ plt[8 + 6] = 0x91c0c004;
+ plt[8 + 7] = 0x01000000;
+
+ /* Now put the magic cookie at the beginning of .PLT3
+ Entry .PLT4 is unused by this implementation. */
+ *((struct link_map **)(&plt[16 + 0])) = l;
}
return lazy;
@@ -256,23 +413,68 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
/* This code is used in dl-runtime.c to call the `fixup' function
and then redirect to the address it returns. */
-#define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\
- .globl _dl_runtime_resolve
- .type _dl_runtime_resolve, @function
-_dl_runtime_resolve:
- save %sp, -160, %sp
- mov %g1, %o0
- call fixup
- mov %g2, %o1
- jmp %o0
+#define TRAMPOLINE_TEMPLATE(tramp_name, fixup_name) \
+ asm ("\
+ .text
+ .globl " #tramp_name "_0
+ .type " #tramp_name "_0, @function
+ .align 32
+" #tramp_name "_0:
+ ldx [%o0 + 32 + 8], %l0
+ sethi %hi(1048576), %g2
+ sub %g1, %o0, %o0
+ xor %g2, -20, %g2
+ sethi %hi(5120), %g3
+ add %o0, %g2, %o0
+ sethi %hi(32768), %o2
+ udivx %o0, %g3, %g3
+ sllx %g3, 2, %g1
+ add %g1, %g3, %g1
+ sllx %g1, 10, %g2
+ sllx %g1, 5, %g1
+ sub %o0, %g2, %o0
+ udivx %o0, 24, %o0
+ add %o0, %o2, %o0
+ add %g1, %o0, %g1
+ sllx %g1, 1, %o1
+ mov %l0, %o0
+ add %o1, %g1, %o1
+ mov %i7, %o2
+ call " #fixup_name "
+ sllx %o1, 3, %o1
+ jmp %o0
+ restore
+ .size " #tramp_name "_0, . - " #tramp_name "_0
+
+ .globl " #tramp_name "_1
+ .type " #tramp_name "_1, @function
+ .align 32
+" #tramp_name "_1:
+ srlx %g1, 15, %o1
+ ldx [%o0 + 8], %o0
+ sllx %o1, 1, %o3
+ add %o1, %o3, %o1
+ mov %i7, %o2
+ call " #fixup_name "
+ sllx %o1, 3, %o1
+ jmp %o0
restore
- .size _dl_runtime_resolve, .-_dl_runtime_resolve
-");
+ .size " #tramp_name "_1, . - " #tramp_name "_1
+ .previous");
+
+#ifndef PROF
+#define ELF_MACHINE_RUNTIME_TRAMPOLINE \
+ TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup); \
+ TRAMPOLINE_TEMPLATE (_dl_runtime_profile, profile_fixup);
+#else
+#define ELF_MACHINE_RUNTIME_TRAMPOLINE \
+ TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup); \
+ TRAMPOLINE_TEMPLATE (_dl_runtime_profile, fixup);
+#endif
/* The PLT uses Elf64_Rela relocs. */
#define elf_machine_relplt elf_machine_rela
-
/* Initial entry point code for the dynamic linker.
The C function `_dl_start' is the real entry point;
its return value is the user program's entry point. */
@@ -281,8 +483,10 @@ _dl_runtime_resolve:
#define __S(x) __S1(x)
#define RTLD_START __asm__ ( "\
- .global _start
- .type _start, @function
+ .text
+ .global _start
+ .type _start, @function
+ .align 32
_start:
/* Make room for functions to drop their arguments on the stack. */
sub %sp, 6*8, %sp
@@ -292,8 +496,8 @@ _start:
/* FALLTHRU */
.size _start, .-_start
- .global _dl_start_user
- .type _dl_start_user, @function
+ .global _dl_start_user
+ .type _dl_start_user, @function
_dl_start_user:
/* Load the GOT register. */
1: call 11f
@@ -302,6 +506,12 @@ _dl_start_user:
add %l7,%o7,%l7
/* Save the user entry point address in %l0. */
mov %o0,%l0
+ /* Store the highest stack address. */
+ sethi %hi(__libc_stack_end), %g2
+ or %g2, %lo(__libc_stack_end), %g2
+ ldx [%l7 + %g2], %l1
+ add %sp, 6*8, %l2
+ stx %l2, [%l1]
/* See if we were run as a command with the executable file name as an
extra leading argument. If so, we must shift things around since we
must keep the stack doubleword aligned. */
@@ -338,7 +548,7 @@ _dl_start_user:
stx %i4, [%i1+8]
brnz,pt %i3, 13b
add %i1, 16, %i1
- /* Load _dl_main_searchlist to pass to _dl_init_next. */
+ /* Load searchlist of the main object to pass to _dl_init_next. */
2: sethi %hi(_dl_main_searchlist), %g2
or %g2, %lo(_dl_main_searchlist), %g2
ldx [%l7+%g2], %g2
@@ -349,8 +559,7 @@ _dl_start_user:
brz,pn %o0, 4f
nop
jmpl %o0, %o7
- nop
- ba,a 3b
+ sub %o7, 24, %o7
/* Clear the startup flag. */
4: sethi %hi(_dl_starting_up), %g2
or %g2, %lo(_dl_starting_up), %g2
@@ -360,7 +569,8 @@ _dl_start_user:
sethi %hi(_dl_fini), %g1
or %g1, %lo(_dl_fini), %g1
ldx [%l7+%g1], %g1
- /* Jump to the user's entry point & undo the allocation of the xtra regs. */
+ /* Jump to the user's entry point and deallocate the extra stack we got. */
jmp %l0
add %sp, 6*8, %sp
- .size _dl_start_user, .-_dl_start_user");
+ .size _dl_start_user, . - _dl_start_user
+ .previous");
diff --git a/sysdeps/sparc/sparc64/elf/crtbegin.S b/sysdeps/sparc/sparc64/elf/crtbegin.S
index 318e7a6a3f..c2fe01f6b0 100644
--- a/sysdeps/sparc/sparc64/elf/crtbegin.S
+++ b/sysdeps/sparc/sparc64/elf/crtbegin.S
@@ -40,7 +40,7 @@ __DTOR_LIST__:
.align 4
.type __do_global_dtors_aux,#function
__do_global_dtors_aux:
- save %sp,-160,%sp
+ save %sp,-192,%sp
#ifdef PIC
1: call 11f
@@ -53,7 +53,6 @@ __do_global_dtors_aux:
#else
sethi %hi(__DTOR_LIST__), %l0
or %l0, %lo(__DTOR_LIST__), %l0
- add %l0, %g4, %l0
#endif
ba 3f
diff --git a/sysdeps/sparc/sparc64/elf/crtend.S b/sysdeps/sparc/sparc64/elf/crtend.S
index 7a5c067b07..db0ac87ecd 100644
--- a/sysdeps/sparc/sparc64/elf/crtend.S
+++ b/sysdeps/sparc/sparc64/elf/crtend.S
@@ -40,7 +40,7 @@ __DTOR_END__:
.align 4
.type __do_global_ctors_aux,#function
__do_global_ctors_aux:
- save %sp,-160,%sp
+ save %sp,-192,%sp
#ifdef PIC
1: call 11f
@@ -53,7 +53,6 @@ __do_global_ctors_aux:
#else
sethi %hi(__CTOR_END__), %l0
or %l0, %lo(__CTOR_END__), %l0
- add %l0, %g4, %l0
#endif
ba 3f
diff --git a/sysdeps/sparc/sparc64/elf/start.S b/sysdeps/sparc/sparc64/elf/start.S
index 140cd366e5..1fc24619cf 100644
--- a/sysdeps/sparc/sparc64/elf/start.S
+++ b/sysdeps/sparc/sparc64/elf/start.S
@@ -38,24 +38,12 @@ _start:
add %sp, STACK_BIAS+23*8, %o2
/* Load the addresses of the user entry points. */
- sethi %uhi(main), %o0
- sethi %uhi(_init), %o3
- sethi %uhi(_fini), %o4
- or %o0, %ulo(main), %o0
- or %o3, %ulo(_init), %o3
- or %o4, %ulo(_fini), %o4
- sethi %hi(main), %i0
- sethi %hi(_init), %i3
- sethi %hi(_fini), %i4
- sllx %o0, 32, %o0
- or %i0, %lo(main), %i0
- sllx %o3, 32, %o3
- or %i3, %lo(_init), %i3
- sllx %o4, 32, %o4
- or %i4, %lo(_fini), %i4
- or %o0, %i0, %o0
- or %o3, %i3, %o3
- or %o4, %i4, %o4
+ sethi %hi(main), %o0
+ sethi %hi(_init), %o3
+ sethi %hi(_fini), %o4
+ or %o0, %lo(main), %o0
+ or %o3, %lo(_init), %o3
+ or %o4, %lo(_fini), %o4
/* When starting a binary via the dynamic linker, %g1 contains the
address of the shared library termination function, which will be
diff --git a/sysdeps/sparc/sparc64/lshift.S b/sysdeps/sparc/sparc64/lshift.S
index 1678991529..f211924ddb 100644
--- a/sysdeps/sparc/sparc64/lshift.S
+++ b/sysdeps/sparc/sparc64/lshift.S
@@ -28,7 +28,7 @@
cnt %i3 */
ENTRY(__mpn_lshift)
- save %sp, -128, %sp
+ save %sp, -192, %sp
sllx %i2,3,%g1
add %i1,%g1,%i1 ! make %i1 point at end of src
diff --git a/sysdeps/sparc/sparc64/mul_1.S b/sysdeps/sparc/sparc64/mul_1.S
index 87e441d7eb..757856b4cd 100644
--- a/sysdeps/sparc/sparc64/mul_1.S
+++ b/sysdeps/sparc/sparc64/mul_1.S
@@ -31,7 +31,7 @@
ENTRY(__mpn_mul_1)
!#PROLOGUE# 0
- save %sp,-128,%sp
+ save %sp,-192,%sp
!#PROLOGUE# 1
sub %g0,%i2,%o7
diff --git a/sysdeps/sparc/sparc64/rshift.S b/sysdeps/sparc/sparc64/rshift.S
index e1b3aca112..51eb4af3ab 100644
--- a/sysdeps/sparc/sparc64/rshift.S
+++ b/sysdeps/sparc/sparc64/rshift.S
@@ -28,7 +28,7 @@
cnt %i3 */
ENTRY(__mpn_rshift)
- save %sp, -128, %sp
+ save %sp, -192, %sp
ldx [%i1],%g2 ! load first limb
sub %g0,%i3,%i5 ! negate shift count
diff --git a/sysdeps/sparc/sparc64/submul_1.S b/sysdeps/sparc/sparc64/submul_1.S
index 3cc0e3bb08..ce9a80464f 100644
--- a/sysdeps/sparc/sparc64/submul_1.S
+++ b/sysdeps/sparc/sparc64/submul_1.S
@@ -31,7 +31,7 @@
ENTRY(__mpn_submul_1)
!#PROLOGUE# 0
- save %sp,-128,%sp
+ save %sp,-192,%sp
!#PROLOGUE# 1
sub %g0,%i2,%o7
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/sigaction.h b/sysdeps/unix/sysv/linux/sparc/bits/sigaction.h
index 1858ef4857..3e4e855915 100644
--- a/sysdeps/unix/sysv/linux/sparc/bits/sigaction.h
+++ b/sysdeps/unix/sysv/linux/sparc/bits/sigaction.h
@@ -40,6 +40,8 @@ struct sigaction
/* Bits in `sa_flags'. */
#define SA_NOCLDSTOP 0x00000008 /* Don't send SIGCHLD when children stop. */
+#define SA_SIGINFO 0x00000200 /* Invoke signal-catching function with
+ three arguments instead of one. */
#ifdef __USE_MISC
# define SA_STACK 0x00000001 /* Use signal stack by using `sa_restorer'. */
# define SA_RESTART 0x00000002 /* Restart syscall on signal return. */
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/signum.h b/sysdeps/unix/sysv/linux/sparc/bits/signum.h
index fae3826023..976eef2758 100644
--- a/sysdeps/unix/sysv/linux/sparc/bits/signum.h
+++ b/sysdeps/unix/sysv/linux/sparc/bits/signum.h
@@ -32,8 +32,6 @@
* Linux/SPARC has different signal numbers that Linux/i386: I'm trying
* to make it OSF/1 binary compatible, at least for normal binaries.
*/
-#define _NSIG 32 /* Biggest signal number + 1. */
-
#define SIGHUP 1
#define SIGINT 2
#define SIGQUIT 3
@@ -70,4 +68,15 @@
#define SIGUSR1 30
#define SIGUSR2 31
+#define _NSIG 64 /* Biggest signal number + 1
+ (including real-time signals). */
+
+#define SIGRTMIN (__libc_current_sigrtmin ())
+#define SIGRTMAX (__libc_current_sigrtmax ())
+
+/* These are the hard limits of the kernel. These values should not be
+ used directly at user level. */
+#define __SIGRTMIN 32
+#define __SIGRTMAX (_NSIG - 1)
+
#endif /* <signal.h> included. */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/brk.c b/sysdeps/unix/sysv/linux/sparc/sparc32/brk.c
index 7e784cab8f..4d38631a19 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/brk.c
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/brk.c
@@ -33,7 +33,7 @@ weak_alias (__curbrk, ___brk_addr)
int
__brk (void *addr)
{
- void *newbrk, *scratch;
+ void *newbrk;
{
register void *o0 __asm__("%o0") = addr;
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c b/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c
index 742ac5583c..ae44328fad 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c
@@ -23,6 +23,13 @@
#include <errno.h>
#include <kernel_sigaction.h>
+extern int __syscall_rt_sigaction (int, const struct kernel_sigaction *,
+ struct kernel_sigaction *, unsigned long,
+ size_t);
+
+static void __rt_sigreturn_stub (void);
+static void __sigreturn_stub (void);
+
/* The variable is shared between all wrappers around signal handling
functions which have RT equivalents. */
int __libc_missing_rt_sigs;
@@ -30,8 +37,49 @@ int __libc_missing_rt_sigs;
int
__sigaction (int sig, __const struct sigaction *act, struct sigaction *oact)
{
+ struct old_kernel_sigaction k_sigact, k_osigact;
int ret;
- struct kernel_sigaction k_sigact, k_osigact;
+
+ /* First try the RT signals. */
+ if (!__libc_missing_rt_sigs)
+ {
+ struct kernel_sigaction kact, koact;
+ unsigned long stub = 0;
+ int saved_errno = errno;
+
+ if (act)
+ {
+ kact.k_sa_handler = act->sa_handler;
+ memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t));
+ if (((kact.sa_flags = act->sa_flags) & SA_SIGINFO) != 0)
+ stub = (unsigned long) &__rt_sigreturn_stub;
+ else
+ stub = (unsigned long) &__sigreturn_stub;
+ stub -= 8;
+ kact.sa_restorer = NULL;
+ }
+
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ ret = __syscall_rt_sigaction (sig, act ? &kact : 0,
+ oact ? &koact : 0,
+ stub, _NSIG / 8);
+
+ if (ret >= 0 || errno != ENOSYS)
+ {
+ if (oact && ret >= 0)
+ {
+ oact->sa_handler = koact.k_sa_handler;
+ memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t));
+ oact->sa_flags = koact.sa_flags;
+ oact->sa_restorer = koact.sa_restorer;
+ }
+ return ret;
+ }
+
+ __set_errno (saved_errno);
+ __libc_missing_rt_sigs = 1;
+ }
/* Magic to tell the kernel we are using "new-style" signals, in that
the signal table is not kept in userspace. Not the same as the
@@ -41,15 +89,16 @@ __sigaction (int sig, __const struct sigaction *act, struct sigaction *oact)
if (act)
{
k_sigact.k_sa_handler = act->sa_handler;
- memcpy (&k_sigact.sa_mask, &act->sa_mask, sizeof (sigset_t));
+ k_sigact.sa_mask = act->sa_mask.__val[0];
k_sigact.sa_flags = act->sa_flags;
+ k_sigact.sa_restorer = NULL;
}
{
register int r_syscallnr __asm__("%g1") = __NR_sigaction;
register int r_sig __asm__("%o0") = sig;
- register struct kernel_sigaction *r_act __asm__("%o1");
- register struct kernel_sigaction *r_oact __asm__("%o2");
+ register struct old_kernel_sigaction *r_act __asm__("%o1");
+ register struct old_kernel_sigaction *r_oact __asm__("%o2");
r_act = act ? &k_sigact : NULL;
r_oact = oact ? &k_osigact : NULL;
@@ -57,7 +106,7 @@ __sigaction (int sig, __const struct sigaction *act, struct sigaction *oact)
__asm__ __volatile__("t 0x10\n\t"
"bcc 1f\n\t"
" nop\n\t"
- " sub %%g0,%%o0,%%o0\n"
+ "sub %%g0,%%o0,%%o0\n"
"1:"
: "=r"(r_sig)
: "r"(r_syscallnr), "r"(r_act), "r"(r_oact),
@@ -66,16 +115,13 @@ __sigaction (int sig, __const struct sigaction *act, struct sigaction *oact)
ret = r_sig;
}
- if (ret >= 0)
+ if (oact && ret >= 0)
{
- if (oact)
- {
- oact->sa_handler = k_osigact.k_sa_handler;
- memcpy (&oact->sa_mask, &k_osigact.sa_mask, sizeof (sigset_t));
- oact->sa_flags = k_osigact.sa_flags;
- oact->sa_restorer = NULL;
- }
- return 0;
+ oact->sa_handler = k_osigact.k_sa_handler;
+ oact->sa_mask.__val[0] = k_osigact.sa_mask;
+ oact->sa_flags = k_osigact.sa_flags;
+ oact->sa_restorer = NULL;
+ return ret;
}
__set_errno (-ret);
@@ -83,3 +129,21 @@ __sigaction (int sig, __const struct sigaction *act, struct sigaction *oact)
}
weak_alias (__sigaction, sigaction);
+
+static void
+__rt_sigreturn_stub (void)
+{
+ __asm__ ("mov %0, %%g1\n\t"
+ "ta 0x10\n\t"
+ : /* no outputs */
+ : "i" (__NR_rt_sigreturn));
+}
+
+static void
+__sigreturn_stub (void)
+{
+ __asm__ ("mov %0, %%g1\n\t"
+ "ta 0x10\n\t"
+ : /* no outputs */
+ : "i" (__NR_sigreturn));
+}
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/Dist b/sysdeps/unix/sysv/linux/sparc/sparc64/Dist
index 50f83311cd..c22b73ebd2 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/Dist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/Dist
@@ -4,5 +4,4 @@ kernel_stat.h
getcontext.S
setcontext.S
sizes.h
-ucontext.h
init-first.h
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/bits/setjmp.h b/sysdeps/unix/sysv/linux/sparc/sparc64/bits/setjmp.h
index b200b718d2..e51f81a5a0 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/bits/setjmp.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/bits/setjmp.h
@@ -21,6 +21,11 @@
# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
#endif
-#include <ucontext.h>
+#include <sys/ucontext.h>
typedef ucontext_t __jmp_buf[1];
+
+/* Test if longjmp to JMPBUF would unwind the frame
+ containing a local variable at ADDRESS. */
+#define _JMPBUF_UNWINDS(jmpbuf, address) \
+ ((unsigned long int) (address) < (jmpbuf)->uc_mcontext.mc_fp)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/bits/statfs.h b/sysdeps/unix/sysv/linux/sparc/sparc64/bits/statfs.h
index 9027eca2ac..b6178f5a8e 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/bits/statfs.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/bits/statfs.h
@@ -39,4 +39,20 @@ struct statfs
long int f_spare[6];
};
+/* We already use 64-bit types in the normal structure,
+ so this is the same as the above. */
+struct statfs64
+ {
+ long int f_type;
+ long int f_bsize;
+ long int f_blocks;
+ long int f_bfree;
+ long int f_bavail;
+ long int f_files;
+ long int f_ffree;
+ __fsid_t f_fsid;
+ long int f_namelen;
+ long int f_spare[6];
+ };
+
#endif /* bits/statfs.h */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S b/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S
index 333f9916f8..e21b60d637 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S
@@ -38,7 +38,7 @@ __curbrk: .skip 8
.text
ENTRY(__brk)
- save %sp, -160, %sp
+ save %sp, -192, %sp
#ifdef PIC
1: call 2f
sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7
@@ -49,24 +49,23 @@ ENTRY(__brk)
LOADSYSCALL(brk)
mov %i0, %o0
- ta 0x11
+ ta 0x6d
/* All the ways we can fail... */
bcs,pn %xcc, .Lerr1
nop
- brz %i0, .Lok
+ brz,pt %i0, .Lok
subcc %i0, %o0, %g0
bne,pn %xcc, .Lerr0
+ nop
/* Update __curbrk and return cleanly. */
.Lok: sethi %hi(__curbrk), %g1
or %g1, %lo(__curbrk), %g1
#ifdef PIC
ldx [%l7+%g1], %g1
- stx %o0, [%g1]
-#else
- stx %o0, [%g4+%g1]
#endif
+ stx %o0, [%g1]
mov %g0, %i0
/* Don't use "ret" cause the preprocessor will eat it. */
@@ -81,10 +80,8 @@ ENTRY(__brk)
or %g1, %lo(errno), %g1
#ifdef PIC
ldx [%l7+%g1], %g1
- st %o0, [%g1]
-#else
- st %o0, [%g4+%g1]
#endif
+ st %o0, [%g1]
#else
call __errno_location
mov %o0,%l1
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S b/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S
index 6c619fcdc3..d7506b7c72 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S
@@ -30,7 +30,7 @@
.type __clone,@function
__clone:
- save %sp,-160,%sp
+ save %sp, -192, %sp
/* sanity check arguments */
brz,pn %i0, 99f
@@ -42,10 +42,10 @@ __clone:
mov %i1, %o1
mov %i2, %o0
set __NR_clone, %g1
- ta 0x11
+ ta 0x6d
bcs,pn %xcc, 99f
nop
- brnz %o0, __thread_start
+ brnz,pn %o0, __thread_start
mov %o0, %i0
ret
restore
@@ -62,7 +62,6 @@ __clone:
st %i0, [%l7+%g2]
#else
sethi %hi(errno), %g2
- add %g2, %g4, %g2
set EINVAL, %i0
st %i0, [%g2+%lo(errno)]
#endif
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/init-first.h b/sysdeps/unix/sysv/linux/sparc/sparc64/init-first.h
index 955714dc4f..ece284ab44 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/init-first.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/init-first.h
@@ -33,7 +33,7 @@
.global " #NAME "
.type " #NAME ",@function
" #NAME ":
- save %sp, -128, %sp
+ save %sp, -192, %sp
1: call 11f
sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7
11: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7
@@ -73,11 +73,10 @@
or %g2, %lo(_dl_starting_up), %g2
brz,pt %g2, 3f
sethi %hi(__libc_multiple_libcs), %g3
- ld [%g4+%g2], %g1
+ ld [%g2], %g1
mov %g0, %g2
movrz %g1, 1, %g2
-3: or %g3, %lo(__libc_multiple_libcs), %g3
- st %g2, [%g3+%g4]
+3: st %g2, [%g3 + %lo(__libc_multiple_libcs)]
/* If so, argc et al are in %o0-%o2 already. Otherwise, load them. */
brnz,pn %g2, " #INIT "
nop
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S b/sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S
index d63762cb15..963aa6d89d 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S
@@ -44,5 +44,7 @@ ENTRY(longjmp)
END(longjmp)
strong_alias(longjmp, __longjmp)
+strong_alias(longjmp, __libc_longjmp)
+strong_alias(longjmp, __libc_siglongjmp)
weak_alias(longjmp, _longjmp)
weak_alias(longjmp, siglongjmp)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S b/sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S
index 82ff4eae3c..38a6f8f8b8 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S
@@ -22,7 +22,7 @@
ENTRY (__libc_pipe)
mov %o0, %o2 /* Save PIPEDES. */
LOADSYSCALL(pipe)
- ta 0x11
+ ta 0x6d
bcc,pn %xcc, 2f
nop
SYSCALL_ERROR_HANDLER
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/readdir.c b/sysdeps/unix/sysv/linux/sparc/sparc64/readdir.c
index 96a6a76945..300ebb2629 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/readdir.c
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/readdir.c
@@ -1,4 +1,7 @@
#define readdir64 __no_readdir64_decl
+#define __readdir64 __no___readdir64_decl
#include <sysdeps/unix/readdir.c>
+#undef __readdir64
+strong_alias (__readdir, __readdir64)
#undef readdir64
weak_alias (__readdir, readdir64)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/ucontext.h b/sysdeps/unix/sysv/linux/sparc/sparc64/sys/ucontext.h
index 160e2fc43a..f62b542b2f 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/ucontext.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sys/ucontext.h
@@ -1,5 +1,5 @@
-#ifndef _UCONTEXT_H
-#define _UCONTEXT_H
+#ifndef _SYS_UCONTEXT_H
+#define _SYS_UCONTEXT_H
#include <signal.h>
@@ -64,4 +64,4 @@ struct ucontext {
};
typedef struct ucontext ucontext_t;
-#endif /* ucontext.h */
+#endif /* sys/ucontext.h */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S b/sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S
index 30dace5903..5864bfcbc3 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S
@@ -28,7 +28,7 @@ ENTRY (syscall)
mov %o4,%o3
mov %o5,%o4
- ta 0x11
+ ta 0x6d
bcc,pt %xcc,1f
nop
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/syscalls.list b/sysdeps/unix/sysv/linux/sparc/sparc64/syscalls.list
index fcf556b818..1ec42fa42e 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/syscalls.list
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/syscalls.list
@@ -6,7 +6,7 @@ pread - pread 4 __pread pread __pread64 pread64
pwrite - pwrite 4 __pwrite pwrite __pwrite64 pwrite64
fstatfs - fstatfs 2 __fstatfs fstatfs fstatfs64
statfs - statfs 2 __statfs statfs statfs64
-getrlimit - getrlimit 2 getrlimit getrlimit64
+getrlimit - getrlimit 2 __getrlimit getrlimit getrlimit64
setrlimit - setrlimit 2 setrlimit setrlimit64
ftruncate - ftruncate 2 __ftruncate ftruncate ftruncate64
truncate - truncate 2 truncate truncate64
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h b/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h
index 2cc8547c1a..5a9a4e249b 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h
@@ -46,49 +46,48 @@
#ifdef PIC
# ifdef _LIBC_REENTRANT
# define SYSCALL_ERROR_HANDLER \
- save %sp,-160,%sp; \
- call __errno_location; \
+ save %sp, -192, %sp; \
+ call __errno_location; \
nop; \
- st %i0,[%o0]; \
- sub %g0,1,%i0; \
- jmpl %i7+8, %g0; \
+ st %i0,[%o0]; \
+ sub %g0,1,%i0; \
+ jmpl %i7+8, %g0; \
restore
# else
# define SYSCALL_ERROR_HANDLER \
.global C_SYMBOL_NAME(errno); \
.type C_SYMBOL_NAME(errno),@object; \
- mov %o7,%g3; \
- 101: call 102f; \
- sethi %hi(_GLOBAL_OFFSET_TABLE_-(101b-.)),%g2; \
- 102: or %g2,%lo(_GLOBAL_OFFSET_TABLE_-(101b-.)),%g2; \
- sethi %hi(errno),%o1; \
- add %g2,%o7,%l7; \
- or %o1,%lo(errno),%o1; \
- mov %g3,%o7; \
- ldx [%l7+%o1],%g2; \
- st %o0,[%g2]; \
+ mov %o7, %g3; \
+ 101: call 102f; \
+ sethi %hi(_GLOBAL_OFFSET_TABLE_-(101b-.)), %g2; \
+ 102: or %g2,%lo(_GLOBAL_OFFSET_TABLE_-(101b-.)), %g2; \
+ sethi %hi(errno), %o1; \
+ add %g2, %o7, %l7; \
+ or %o1, %lo(errno), %o1; \
+ mov %g3,%o7; \
+ ldx [%l7+%o1], %g2; \
+ st %o0, [%g2]; \
retl; \
- sub %g0,1,%i0
+ sub %g0, 1, %i0
# endif
#else
# ifdef _LIBC_REENTRANT
# define SYSCALL_ERROR_HANDLER \
- save %sp,-160,%sp; \
- call __errno_location; \
+ save %sp, -192, %sp; \
+ call __errno_location; \
nop; \
- st %i0,[%o0]; \
- sub %g0,1,%i0; \
- jmpl %i7+8, %g0; \
+ st %i0, [%o0]; \
+ sub %g0, 1, %i0; \
+ jmpl %i7+8, %g0; \
restore
# else
# define SYSCALL_ERROR_HANDLER \
.global C_SYMBOL_NAME(errno); \
.type C_SYMBOL_NAME(errno),@object; \
- sethi %hi(errno),%g1; \
- or %g1,%lo(errno),%g1; \
- st %i0,[%g1+%g4]; \
+ sethi %hi(errno), %g1; \
+ st %i0, [%g1 + %lo(errno)]; \
retl; \
- sub %g0,1,%i0
+ sub %g0, 1, %i0
# endif
#endif
@@ -96,8 +95,8 @@
.text; \
ENTRY(name); \
LOADSYSCALL(syscall_name); \
- ta 0x11; \
- bcc,pt %xcc,1f; \
+ ta 0x6d; \
+ bcc,pt %xcc, 1f; \
nop; \
SYSCALL_ERROR_HANDLER; \
1: