mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-29 11:41:21 +03:00
* elf/dl-runtime.c (fixup, profile_fixup): The final arg to _dl_lookup_*symbol is DL_LOOKUP_NOPLT not ELF_MACHINE_JMP_SLOT. * elf/elf.h (EM_SPARC64): Remove. (EM_SPARC32PLUS, EM_SPARCV9): Add. (HWCAP_SPARC_V9): Add. * elf/ldsodefs.h (_dl_hwcap): Declare. * sysdeps/sparc/sparc32/dl-machine.h (_dl_hwcap, _dl_hwcap_mask): Weaken so dlopen from static progies works. (WEAKADDR): New macro. (elf_machine_matches_host): Accept EM_SPARC32PLUS on a v9 cpu. (LD_SO_PRELOAD): New macro. (elf_machine_fixup_plt): Cope with weak _dl_hwcap. (elf_machine_rela): Weaken _dl_rtld_map. * sysdeps/unix/sysv/linux/sparc/sparc32/clone.S: Rename __libc_clone to __clone, and remove the later's alias. * sysdeps/unix/sysv/linux/sparc/sparc64/clone.S: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c: Copy to/from the kernel's structure.
1998-04-06 Jakub Jelinek <jj@sunsite.ms.mff.cuni.cz> * elf/dl-runtime.c (fixup, profile_fixup): The final arg to _dl_lookup_*symbol is DL_LOOKUP_NOPLT not ELF_MACHINE_JMP_SLOT. * elf/elf.h (EM_SPARC64): Remove. (EM_SPARC32PLUS, EM_SPARCV9): Add. (HWCAP_SPARC_V9): Add. * elf/ldsodefs.h (_dl_hwcap): Declare. * sysdeps/sparc/sparc32/dl-machine.h (_dl_hwcap, _dl_hwcap_mask): Weaken so dlopen from static progies works. (WEAKADDR): New macro. (elf_machine_matches_host): Accept EM_SPARC32PLUS on a v9 cpu. (LD_SO_PRELOAD): New macro. (elf_machine_fixup_plt): Cope with weak _dl_hwcap. (elf_machine_rela): Weaken _dl_rtld_map. * sysdeps/unix/sysv/linux/sparc/sparc32/clone.S: Rename __libc_clone to __clone, and remove the later's alias. * sysdeps/unix/sysv/linux/sparc/sparc64/clone.S: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c: Copy to/from the kernel's structure. * sysdeps/generic/libc-start.c: Allow init and fini to be null.
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
Contributed by Richard Henderson (rth@tamu.edu).
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -26,21 +26,18 @@
|
||||
|
||||
.text
|
||||
.align 4
|
||||
.globl __libc_clone
|
||||
.type __libc_clone,@function
|
||||
.weak clone
|
||||
__clone = __libc_clone
|
||||
clone = __libc_clone
|
||||
.globl __clone
|
||||
.type __clone,@function
|
||||
|
||||
__libc_clone:
|
||||
__clone:
|
||||
save %sp,-96,%sp
|
||||
|
||||
/* sanity check arguments */
|
||||
tst %i0
|
||||
be __clone_syscall_error
|
||||
tst %i1
|
||||
be __clone_syscall_error
|
||||
nop
|
||||
be .Lerror
|
||||
tst %i1
|
||||
be .Lerror
|
||||
nop
|
||||
|
||||
/* Do the system call */
|
||||
mov %i1,%o1
|
||||
@ -48,23 +45,31 @@ __libc_clone:
|
||||
set __NR_clone,%g1
|
||||
ta 0x10
|
||||
bcs __clone_syscall_error
|
||||
tst %o1
|
||||
tst %o1
|
||||
bne __thread_start
|
||||
nop
|
||||
nop
|
||||
mov %o0,%i0
|
||||
ret
|
||||
restore
|
||||
restore
|
||||
|
||||
__clone_syscall_error:
|
||||
.Lerror:
|
||||
call __errno_location
|
||||
set EINVAL,%i0
|
||||
set EINVAL,%i0
|
||||
st %i0,[%o0]
|
||||
mov -1,%i0
|
||||
ret
|
||||
restore
|
||||
restore
|
||||
|
||||
.size __clone, .-__clone
|
||||
|
||||
.type __thread_start,@function
|
||||
|
||||
__thread_start:
|
||||
call %i0
|
||||
mov %i3,%o0
|
||||
mov %i3,%o0
|
||||
call _exit,0
|
||||
nop
|
||||
nop
|
||||
|
||||
.size __thread_start, .-__thread_start
|
||||
|
||||
weak_alias(__clone, clone)
|
||||
|
@ -21,120 +21,65 @@
|
||||
#include <syscall.h>
|
||||
#include <sys/signal.h>
|
||||
#include <errno.h>
|
||||
#include <kernel_sigaction.h>
|
||||
|
||||
/* The variable is shared between all wrappers around signal handling
|
||||
functions which have RT equivalents. */
|
||||
int __libc_missing_rt_sigs;
|
||||
|
||||
/* Commented out while I figure out what the fuck goes on */
|
||||
long ____sig_table [NSIG];
|
||||
#if 0
|
||||
|
||||
/* The kernel will deliver signals in the old way if the signal
|
||||
number is a positive number. The kernel will deliver a signal
|
||||
with the new stack layout if the signal number is a negative number.
|
||||
|
||||
Our sigaction code takes care of selecting the type of kernel we are
|
||||
using at runtime. */
|
||||
|
||||
extern void ____sparc_signal_trampoline (int);
|
||||
|
||||
int
|
||||
__trampoline_sigaction (int sig, struct sigaction *new, struct sigaction *old)
|
||||
{
|
||||
int ret;
|
||||
int need_to_hide_trick = 0;
|
||||
__sighandler_t old_sh;
|
||||
|
||||
if (new)
|
||||
{
|
||||
if (new->sa_handler != SIG_DFL && new->sa_handler != SIG_IGN)
|
||||
{
|
||||
old_sh = ____sig_table[sig];
|
||||
____sig_table[sig] = (long int) new->sa_handler;
|
||||
new->sa_handler = ____sparc_signal_trampoline;
|
||||
need_to_hide_trick = 1;
|
||||
}
|
||||
}
|
||||
__asm__("or %%g0,%0,%%g1\n\t"
|
||||
"or %%g0,%1,%%o0\n\t"
|
||||
"or %%g0,%2,%%o1\n\t"
|
||||
"or %%g0,%3,%%o2\n\t"
|
||||
"t 0x10\n\t"
|
||||
"bcc 1f\n\t"
|
||||
"or %%o0, %%g0, %0\n\t"
|
||||
"sub %%g0, %%o0, %0\n\t"
|
||||
"1:"
|
||||
: "=r" (ret), "=r" ((long int) sig), "=r" ((long int) new),
|
||||
"=r" ((long int) old)
|
||||
: "0" (__NR_sigaction), "1" (sig), "2" (new), "3" (old)
|
||||
: "g1", "o0", "o1", "o2");
|
||||
|
||||
if (ret >= 0)
|
||||
{
|
||||
if (old && old->sa_handler == ____sparc_signal_trampoline)
|
||||
{
|
||||
if (need_to_hide_trick)
|
||||
old->sa_handler = old_sh;
|
||||
else
|
||||
old->sa_handler = ____sig_table[sig];
|
||||
}
|
||||
if (need_to_hide_trick)
|
||||
new->sa_handler = ____sig_table[sig];
|
||||
return 0;
|
||||
}
|
||||
__set_errno (-ret);
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
# define __new_sigaction __sigaction
|
||||
#endif
|
||||
|
||||
int
|
||||
__new_sigaction (int sig, __const struct sigaction *new, struct sigaction *old)
|
||||
__sigaction (int sig, __const struct sigaction *act, struct sigaction *oact)
|
||||
{
|
||||
int ret;
|
||||
struct kernel_sigaction k_sigact, k_osigact;
|
||||
|
||||
/* 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
|
||||
really-new-style rt signals. */
|
||||
sig = -sig;
|
||||
|
||||
__asm__("or %%g0,%0,%%g1\n\t"
|
||||
"or %%g0,%1,%%o0\n\t"
|
||||
"or %%g0,%2,%%o1\n\t"
|
||||
"or %%g0,%3,%%o2\n\t"
|
||||
"t 0x10\n\t"
|
||||
"bcc 1f\n\t"
|
||||
"or %%o0, %%g0, %0\n\t"
|
||||
"sub %%g0,%%o0,%0\n\t"
|
||||
"1:"
|
||||
: "=r" (ret), "=r" ((long int) sig), "=r" ((long int) new),
|
||||
"=r" ((long int) old)
|
||||
: "0" (__NR_sigaction), "1" (sig), "2" (new), "3" (old)
|
||||
: "g1", "o0", "o1", "o2");
|
||||
if (act)
|
||||
{
|
||||
k_sigact.sa_handler = act->sa_handler;
|
||||
k_sigact.sa_mask = act->sa_mask.__val[0];
|
||||
k_sigact.sa_flags = act->sa_flags;
|
||||
}
|
||||
|
||||
{
|
||||
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");
|
||||
|
||||
r_act = act ? &k_sigact : NULL;
|
||||
r_oact = oact ? &k_osigact : NULL;
|
||||
|
||||
__asm__ __volatile__("t 0x10\n\t"
|
||||
"bcc 1f\n\t"
|
||||
" nop\n\t"
|
||||
" sub %%g0,%%o0,%%o0\n"
|
||||
"1:"
|
||||
: "=r"(r_sig)
|
||||
: "r"(r_syscallnr), "r"(r_act), "r"(r_oact),
|
||||
"0"(r_sig));
|
||||
|
||||
ret = r_sig;
|
||||
}
|
||||
|
||||
if (ret >= 0)
|
||||
return 0;
|
||||
{
|
||||
if (oact)
|
||||
{
|
||||
oact->sa_handler = k_osigact.sa_handler;
|
||||
oact->sa_mask.__val[0] = k_osigact.sa_mask;
|
||||
oact->sa_flags = k_osigact.sa_flags;
|
||||
oact->sa_restorer = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
__set_errno (-ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int
|
||||
__sigaction (int sig, __const struct sigaction *new, struct sigaction *old)
|
||||
{
|
||||
static (*sigact_routine) (int, __const struct sigaction *, struct sigaction *);
|
||||
int ret;
|
||||
struct sigaction sa;
|
||||
|
||||
if (sigact_routine)
|
||||
return (*sigact_routine) (sig, new, old);
|
||||
|
||||
ret = __new_sigaction (1, NULL, &sa);
|
||||
if (ret == -1)
|
||||
sigact_routine = __trampoline_sigaction;
|
||||
else
|
||||
sigact_routine = __new_sigaction;
|
||||
|
||||
return __sigaction (sig, new, old);
|
||||
}
|
||||
#endif
|
||||
|
||||
weak_alias (__sigaction, sigaction);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Miguel de Icaza <miguel@gnu.ai.mit.edu>, 1997.
|
||||
|
||||
|
@ -26,13 +26,10 @@
|
||||
|
||||
.text
|
||||
.align 4
|
||||
.globl __libc_clone
|
||||
.type __libc_clone,@function
|
||||
.weak clone
|
||||
__clone = __libc_clone
|
||||
clone = __libc_clone
|
||||
.globl __clone
|
||||
.type __clone,@function
|
||||
|
||||
__libc_clone:
|
||||
__clone:
|
||||
save %sp,-160,%sp
|
||||
|
||||
/* sanity check arguments */
|
||||
@ -77,7 +74,7 @@ __libc_clone:
|
||||
mov -1,%i0
|
||||
ret
|
||||
restore
|
||||
.size __libc_clone, .-__libc_clone
|
||||
.size __clone, .-__clone
|
||||
|
||||
.type __thread_start,@function
|
||||
__thread_start:
|
||||
@ -88,3 +85,5 @@ __thread_start:
|
||||
call _exit,0
|
||||
nop
|
||||
.size __thread_start, .-__thread_start
|
||||
|
||||
weak_alias(__clone, clone)
|
||||
|
Reference in New Issue
Block a user