mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-30 22:43:12 +03:00
Add sparc64 TLS and NPTL support.
* elf/tls-macros.h: Add Sparc64 defines. * sysdeps/sparc/sparc64/dl-machine.h (sparc64_fixup_plt): Mark as always_inline. (elf_machine_fixup_plt): Likewise. (elf_machine_rela): Handle TLS relocations. (elf_machine_type_cleaa): Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h (SYSCALL_ERROR_HANDLER_ENTRY): Use sethi/or for GOT reloc. It does not always fit in R_SPARC_GOT13 when building -fPIC. Also, add TLS handling. * sysdeps/unix/sysv/linux/configure.in (arch_minimum_kernel): Increase it to 2.4.21 for sparc64. * sysdeps/unix/sysv/linux/sparc/sparc32/clone.S: NULL terminate backtrace by zero'ing out %fp. Store away flags, func_ptr, and func_arg in global registers not local registers. * sysdeps/unix/sysv/linux/sparc/sparc64/clone.S: Handle PTID, TLS, and CTID arguments properly. Add RESET_PID handling. * sysdeps/unix/sysv/linux/sparc/sparc64/pause.c: Rework so that we do not invoke __sigprocmask(). We can always assume rt signals are present on sparc64, so just do an inline syscall. 2005-04-13 Jakub Jelinek <jakub@redhat.com> * sysdeps/sparc/sparc64/dl-machine.h: Add dl_machine_h multiple inclusion guard for the first half of the header. (elf_machine_type_class, ELF_MACHINE_JMP_SLOT, ELF_MACHINE_NO_REL, ELF_MACHINE_PLTREL_OVERLAP, elf_machine_runtime_setup, elf_machine_relplt, DL_STACK_END, RTLD_START): Move into the #ifndef dl_machine_h guarded part of the header.
This commit is contained in:
@ -40,11 +40,19 @@ __clone:
|
||||
save %sp,-96,%sp
|
||||
|
||||
/* sanity check arguments */
|
||||
tst %i0
|
||||
orcc %i0,%g0,%g2
|
||||
be .Lerror
|
||||
orcc %i1,%g0,%o1
|
||||
be .Lerror
|
||||
mov %i2,%o0
|
||||
|
||||
/* The child_stack is the top of the stack, allocate one
|
||||
whole stack frame from that as this is what the kernel
|
||||
expects. */
|
||||
sub %o1, 96, %o1
|
||||
mov %i3, %g3
|
||||
mov %i2, %g4
|
||||
|
||||
/* ptid */
|
||||
mov %i4,%o2
|
||||
/* tls */
|
||||
@ -76,19 +84,21 @@ __clone:
|
||||
__thread_start:
|
||||
#ifdef RESET_PID
|
||||
sethi %hi(CLONE_THREAD), %l0
|
||||
andcc %i2, %l0, %g0
|
||||
andcc %g4, %l0, %g0
|
||||
bne 1f
|
||||
andcc %i2, CLONE_VM, %g0
|
||||
andcc %g4, CLONE_VM, %g0
|
||||
bne,a 2f
|
||||
mov -1,%o0
|
||||
set __NR_getpid,%g1
|
||||
ta 0x10
|
||||
2: st %o0,[%g7 + PID]
|
||||
2:
|
||||
st %o0,[%g7 + PID]
|
||||
st %o0,[%g7 + TID]
|
||||
1:
|
||||
#endif
|
||||
call %i0
|
||||
mov %i3,%o0
|
||||
mov %g0, %fp /* terminate backtrace */
|
||||
call %g2
|
||||
mov %g3,%o0
|
||||
call _exit,0
|
||||
nop
|
||||
|
||||
|
@ -22,8 +22,16 @@
|
||||
|
||||
#include <asm/errno.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <tcb-offsets.h>
|
||||
|
||||
/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
|
||||
#define CLONE_VM 0x00000100
|
||||
#define CLONE_THREAD 0x00010000
|
||||
|
||||
/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
|
||||
pid_t *ptid, void *tls, pid_t *ctid); */
|
||||
|
||||
.register %g2,#scratch
|
||||
.register %g3,#scratch
|
||||
|
||||
.text
|
||||
.align 4
|
||||
@ -34,22 +42,31 @@ __clone:
|
||||
save %sp, -192, %sp
|
||||
|
||||
/* sanity check arguments */
|
||||
brz,pn %i0, 99f
|
||||
mov %i0, %l0 /* save fn */
|
||||
brz,pn %i1, 99f
|
||||
mov %i3, %l3 /* save arg */
|
||||
brz,pn %i0, 99f /* fn non-NULL? */
|
||||
mov %i0, %g2
|
||||
brz,pn %i1, 99f /* child_stack non-NULL? */
|
||||
mov %i2, %o0 /* clone flags */
|
||||
|
||||
/* The child_stack is the top of the stack, allocate one
|
||||
whole stack frame from that as this is what the kernel
|
||||
expects. Also, subtract STACK_BIAS. */
|
||||
sub %i1, 192 + 0x7ff, %o1
|
||||
mov %i3, %g3
|
||||
mov %i2, %g4
|
||||
|
||||
mov %i4,%o2 /* PTID */
|
||||
mov %i5,%o3 /* TLS */
|
||||
ldx [%fp+0x7ff+176],%o4 /* CTID */
|
||||
|
||||
/* Do the system call */
|
||||
sub %i1, 0x7ff, %o1
|
||||
mov %i2, %o0
|
||||
set __NR_clone, %g1
|
||||
ta 0x6d
|
||||
bcs,pn %xcc, 99f
|
||||
nop
|
||||
brnz,pn %o1, __thread_start
|
||||
mov %o0, %i0
|
||||
nop
|
||||
ret
|
||||
restore
|
||||
restore %o0, %g0, %o0
|
||||
99:
|
||||
#ifndef _LIBC_REENTRANT
|
||||
#ifdef PIC
|
||||
@ -77,10 +94,22 @@ __clone:
|
||||
|
||||
.type __thread_start,@function
|
||||
__thread_start:
|
||||
#ifdef RESET_PID
|
||||
sethi %hi(CLONE_THREAD), %l0
|
||||
andcc %g4, %l0, %g0
|
||||
bne,pt %icc, 1f
|
||||
andcc %g4, CLONE_VM, %g0
|
||||
bne,a,pn %icc, 2f
|
||||
mov -1,%o0
|
||||
set __NR_getpid,%g1
|
||||
ta 0x6d
|
||||
2: st %o0,[%g7 + PID]
|
||||
st %o0,[%g7 + TID]
|
||||
1:
|
||||
#endif
|
||||
mov %g0, %fp /* terminate backtrace */
|
||||
sub %sp, 6*8, %sp /* provide arg storage */
|
||||
call %l0
|
||||
mov %l3,%o0
|
||||
call %g2
|
||||
mov %g3,%o0
|
||||
call _exit,0
|
||||
nop
|
||||
.size __thread_start, .-__thread_start
|
||||
|
@ -1 +1,47 @@
|
||||
#include <sysdeps/posix/pause.c>
|
||||
/* pause -- suspend the process until a signal arrives. POSIX.1 version.
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <sysdep-cancel.h>
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <bp-checks.h>
|
||||
|
||||
/* Suspend the process until a signal arrives.
|
||||
This always returns -1 and sets errno to EINTR. */
|
||||
int
|
||||
__libc_pause (void)
|
||||
{
|
||||
sigset_t set;
|
||||
|
||||
__sigemptyset (&set);
|
||||
INLINE_SYSCALL (rt_sigprocmask, 4, SIG_BLOCK, CHECK_SIGSET (NULL),
|
||||
CHECK_SIGSET_NULL_OK (&set), _NSIG / 8);
|
||||
|
||||
/* pause is a cancellation point, but so is sigsuspend.
|
||||
So no need for anything special here. */
|
||||
|
||||
return __sigsuspend (&set);
|
||||
}
|
||||
weak_alias (__libc_pause, pause)
|
||||
|
||||
LIBC_CANCEL_HANDLED (); /* sigsuspend handles our cancellation. */
|
||||
|
@ -85,11 +85,54 @@ SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler) \
|
||||
sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %l7; \
|
||||
call __sparc64.get_pic.l7; \
|
||||
add %l7, %lo(_GLOBAL_OFFSET_TABLE_+4), %l7; \
|
||||
ldx [%l7 + rtld_errno], %l0; \
|
||||
sethi %hi(rtld_errno), %g1; \
|
||||
or %g1, %lo(rtld_errno), %g1; \
|
||||
ldx [%l7 + %g1], %l0; \
|
||||
st %i0, [%l0]; \
|
||||
jmpl %i7+8, %g0; \
|
||||
restore %g0, -1, %o0; \
|
||||
.previous;
|
||||
#elif USE___THREAD
|
||||
# ifndef NOT_IN_libc
|
||||
# define SYSCALL_ERROR_ERRNO __libc_errno
|
||||
# else
|
||||
# define SYSCALL_ERROR_ERRNO errno
|
||||
# endif
|
||||
# ifdef SHARED
|
||||
# define SYSCALL_ERROR_HANDLER \
|
||||
.section .gnu.linkonce.t.__sparc64.get_pic.l7,"ax",@progbits; \
|
||||
.globl __sparc64.get_pic.l7; \
|
||||
.hidden __sparc64.get_pic.l7; \
|
||||
.type __sparc64.get_pic.l7,@function; \
|
||||
__sparc64.get_pic.l7: \
|
||||
retl; \
|
||||
add %o7, %l7, %l7; \
|
||||
.previous; \
|
||||
SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler) \
|
||||
save %sp,-192,%sp; \
|
||||
sethi %tie_hi22(SYSCALL_ERROR_ERRNO), %l1; \
|
||||
sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %l7; \
|
||||
call __sparc64.get_pic.l7; \
|
||||
add %l7, %lo(_GLOBAL_OFFSET_TABLE_+4), %l7; \
|
||||
add %l1, %tie_lo10(SYSCALL_ERROR_ERRNO), %l1; \
|
||||
ldx [%l7 + %l1], %l1, %tie_ldx(SYSCALL_ERROR_ERRNO); \
|
||||
st %i0, [%g7 + %l1], %tie_add(SYSCALL_ERROR_ERRNO); \
|
||||
jmpl %i7+8, %g0; \
|
||||
restore %g0, -1, %o0; \
|
||||
.previous;
|
||||
# else
|
||||
# define SYSCALL_ERROR_HANDLER \
|
||||
SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler) \
|
||||
sethi %tie_hi22(SYSCALL_ERROR_ERRNO), %g1; \
|
||||
sethi %hi(_GLOBAL_OFFSET_TABLE_), %g2; \
|
||||
add %g1, %tie_lo10(SYSCALL_ERROR_ERRNO), %g1; \
|
||||
add %g2, %lo(_GLOBAL_OFFSET_TABLE_), %g2; \
|
||||
ldx [%g2 + %g1], %g1, %tie_ldx(SYSCALL_ERROR_ERRNO); \
|
||||
st %o0, [%g7 + %g1], %tie_add(SYSCALL_ERROR_ERRNO); \
|
||||
jmpl %o7+8, %g0; \
|
||||
mov -1, %o0; \
|
||||
.previous;
|
||||
# endif
|
||||
#else
|
||||
# define SYSCALL_ERROR_HANDLER \
|
||||
SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler) \
|
||||
|
Reference in New Issue
Block a user