mirror of
https://sourceware.org/git/glibc.git
synced 2025-01-03 00:10:10 +00: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:
parent
a55400166d
commit
4194bc660f
27
ChangeLog
27
ChangeLog
@ -1,5 +1,32 @@
|
|||||||
|
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.
|
||||||
|
|
||||||
1998-04-06 Richard Henderson <rth@cygnus.com>
|
1998-04-06 Richard Henderson <rth@cygnus.com>
|
||||||
|
|
||||||
|
* sysdeps/generic/libc-start.c: Allow init and fini to be null.
|
||||||
|
|
||||||
* sysdeps/sparc/sparc32/elf.S: Rewrite for __libc_start_main.
|
* sysdeps/sparc/sparc32/elf.S: Rewrite for __libc_start_main.
|
||||||
* sysdeps/sparc/sparc64/elf.S: Likewise.
|
* sysdeps/sparc/sparc64/elf.S: Likewise.
|
||||||
|
|
||||||
|
@ -128,13 +128,13 @@ fixup (
|
|||||||
{
|
{
|
||||||
value = _dl_lookup_versioned_symbol(strtab + sym->st_name,
|
value = _dl_lookup_versioned_symbol(strtab + sym->st_name,
|
||||||
&sym, scope, l->l_name,
|
&sym, scope, l->l_name,
|
||||||
version, ELF_MACHINE_JMP_SLOT);
|
version, DL_LOOKUP_NOPLT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case 0:
|
case 0:
|
||||||
value = _dl_lookup_symbol (strtab + sym->st_name, &sym, scope,
|
value = _dl_lookup_symbol (strtab + sym->st_name, &sym, scope,
|
||||||
l->l_name, ELF_MACHINE_JMP_SLOT);
|
l->l_name, DL_LOOKUP_NOPLT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Currently value contains the base load address of the object
|
/* Currently value contains the base load address of the object
|
||||||
@ -205,13 +205,13 @@ profile_fixup (
|
|||||||
value = _dl_lookup_versioned_symbol(strtab + sym->st_name,
|
value = _dl_lookup_versioned_symbol(strtab + sym->st_name,
|
||||||
&sym, scope, l->l_name,
|
&sym, scope, l->l_name,
|
||||||
version,
|
version,
|
||||||
ELF_MACHINE_JMP_SLOT);
|
DL_LOOKUP_NOPLT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case 0:
|
case 0:
|
||||||
value = _dl_lookup_symbol (strtab + sym->st_name, &sym, scope,
|
value = _dl_lookup_symbol (strtab + sym->st_name, &sym, scope,
|
||||||
l->l_name, ELF_MACHINE_JMP_SLOT);
|
l->l_name, DL_LOOKUP_NOPLT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Currently value contains the base load address of the object
|
/* Currently value contains the base load address of the object
|
||||||
|
@ -162,11 +162,14 @@ typedef struct
|
|||||||
#define EM_S370 9 /* Amdahl */
|
#define EM_S370 9 /* Amdahl */
|
||||||
#define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */
|
#define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */
|
||||||
|
|
||||||
#define EM_SPARC64 11 /* SPARC v9 (not official) 64-bit */
|
|
||||||
|
|
||||||
#define EM_PARISC 15 /* HPPA */
|
#define EM_PARISC 15 /* HPPA */
|
||||||
|
|
||||||
|
#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */
|
||||||
|
|
||||||
#define EM_PPC 20 /* PowerPC */
|
#define EM_PPC 20 /* PowerPC */
|
||||||
|
|
||||||
|
#define EM_SPARCV9 43 /* SPARC v9 64-bit */
|
||||||
|
|
||||||
/* If it is necessary to assign new unofficial EM_* values, please
|
/* If it is necessary to assign new unofficial EM_* values, please
|
||||||
pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
|
pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
|
||||||
chances of collision with official or non-GNU unofficial values. */
|
chances of collision with official or non-GNU unofficial values. */
|
||||||
@ -808,6 +811,7 @@ typedef struct
|
|||||||
#define HWCAP_SPARC_STBAR 2
|
#define HWCAP_SPARC_STBAR 2
|
||||||
#define HWCAP_SPARC_SWAP 4
|
#define HWCAP_SPARC_SWAP 4
|
||||||
#define HWCAP_SPARC_MULDIV 8
|
#define HWCAP_SPARC_MULDIV 8
|
||||||
|
#define HWCAP_SPARC_V9 16 /* The cpu is v9, so v8plus is ok. */
|
||||||
|
|
||||||
/* MIPS R3000 specific definitions. */
|
/* MIPS R3000 specific definitions. */
|
||||||
|
|
||||||
|
@ -140,6 +140,9 @@ extern int _dl_debug_files;
|
|||||||
/* Expect cache ID. */
|
/* Expect cache ID. */
|
||||||
extern int _dl_correct_cache_id;
|
extern int _dl_correct_cache_id;
|
||||||
|
|
||||||
|
/* Mask for hardware capabilities that are available. */
|
||||||
|
extern unsigned long int _dl_hwcap;
|
||||||
|
|
||||||
/* Mask for important hardware capabilities we honour. */
|
/* Mask for important hardware capabilities we honour. */
|
||||||
extern unsigned long int _dl_hwcap_mask;
|
extern unsigned long int _dl_hwcap_mask;
|
||||||
|
|
||||||
|
@ -40,13 +40,13 @@ __libc_start_main (int (*main) (int, char **, char **), int argc,
|
|||||||
__libc_multiple_libcs = dummy_addr && !_dl_starting_up;
|
__libc_multiple_libcs = dummy_addr && !_dl_starting_up;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Set the global _environ variable correctly. */
|
||||||
|
__environ = &argv[argc + 1];
|
||||||
|
|
||||||
/* Register the destructor of the dynamic linker if there is any. */
|
/* Register the destructor of the dynamic linker if there is any. */
|
||||||
if (rtld_fini != NULL)
|
if (rtld_fini != NULL)
|
||||||
atexit (rtld_fini);
|
atexit (rtld_fini);
|
||||||
|
|
||||||
/* Set the global _environ variable correctly. */
|
|
||||||
__environ = &argv[argc + 1];
|
|
||||||
|
|
||||||
/* Call the initializer of the libc. */
|
/* Call the initializer of the libc. */
|
||||||
#ifdef PIC
|
#ifdef PIC
|
||||||
if (_dl_debug_impcalls)
|
if (_dl_debug_impcalls)
|
||||||
@ -54,15 +54,17 @@ __libc_start_main (int (*main) (int, char **, char **), int argc,
|
|||||||
#endif
|
#endif
|
||||||
__libc_init_first (argc, argv, __environ);
|
__libc_init_first (argc, argv, __environ);
|
||||||
|
|
||||||
/* Call the initializer of the program. */
|
/* Register the destructor of the program, if any. */
|
||||||
|
if (fini)
|
||||||
|
atexit (fini);
|
||||||
|
|
||||||
|
/* Call the initializer of the program, if any. */
|
||||||
#ifdef PIC
|
#ifdef PIC
|
||||||
if (_dl_debug_impcalls)
|
if (_dl_debug_impcalls)
|
||||||
_dl_debug_message (1, "\ninitialize program: ", argv[0], "\n\n", NULL);
|
_dl_debug_message (1, "\ninitialize program: ", argv[0], "\n\n", NULL);
|
||||||
#endif
|
#endif
|
||||||
(*init) ();
|
if (init)
|
||||||
|
(*init) ();
|
||||||
/* Register the destructor of the program. */
|
|
||||||
atexit (fini);
|
|
||||||
|
|
||||||
#ifdef PIC
|
#ifdef PIC
|
||||||
if (_dl_debug_impcalls)
|
if (_dl_debug_impcalls)
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <link.h>
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <elf/ldsodefs.h>
|
||||||
|
|
||||||
|
|
||||||
/* Some SPARC opcodes we need to use for self-modifying code. */
|
/* Some SPARC opcodes we need to use for self-modifying code. */
|
||||||
@ -33,11 +33,36 @@
|
|||||||
#define OPCODE_SAVE_SP 0x9de3bfa8 /* save %sp, -(16+6)*4, %sp */
|
#define OPCODE_SAVE_SP 0x9de3bfa8 /* save %sp, -(16+6)*4, %sp */
|
||||||
|
|
||||||
|
|
||||||
|
/* To allow static progies to link properly, define these as weak. */
|
||||||
|
weak_extern(_dl_hwcap);
|
||||||
|
weak_extern(_dl_hwcap_mask);
|
||||||
|
|
||||||
|
|
||||||
|
/* Protect some broken versions of gcc from misinterpreting weak addresses. */
|
||||||
|
#define WEAKADDR(x) ({ __typeof(x) *_px = &x; \
|
||||||
|
__asm ("" : "=r" (_px) : "0" (_px)); \
|
||||||
|
_px })
|
||||||
|
|
||||||
|
|
||||||
|
/* Use a different preload file when running in 32-bit emulation mode
|
||||||
|
on a 64-bit host. */
|
||||||
|
#define LD_SO_PRELOAD ((_dl_hwcap & HWCAP_SPARC_V9) ? "/etc/ld.so.preload32" \
|
||||||
|
: "/etc/ld.so.preload")
|
||||||
|
|
||||||
|
|
||||||
/* Return nonzero iff E_MACHINE is compatible with the running host. */
|
/* Return nonzero iff E_MACHINE is compatible with the running host. */
|
||||||
static inline int
|
static inline int
|
||||||
elf_machine_matches_host (Elf32_Half e_machine)
|
elf_machine_matches_host (Elf32_Half e_machine)
|
||||||
{
|
{
|
||||||
return e_machine == EM_SPARC;
|
if (e_machine == EM_SPARC)
|
||||||
|
return 1;
|
||||||
|
else if (e_machine == EM_SPARC32PLUS)
|
||||||
|
{
|
||||||
|
unsigned long *hwcap = WEAKADDR(_dl_hwcap);
|
||||||
|
return hwcap && (*hwcap & _dl_hwcap_mask & HWCAP_SPARC_V9);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -240,7 +265,14 @@ static inline void
|
|||||||
elf_machine_fixup_plt (struct link_map *map, const Elf32_Rela *reloc,
|
elf_machine_fixup_plt (struct link_map *map, const Elf32_Rela *reloc,
|
||||||
Elf32_Addr *reloc_addr, Elf32_Addr value)
|
Elf32_Addr *reloc_addr, Elf32_Addr value)
|
||||||
{
|
{
|
||||||
extern unsigned long _dl_hwcap;
|
#ifndef RTLD_BOOTSTRAP
|
||||||
|
/* Note that we don't mask the hwcap here, as the flush is essential to
|
||||||
|
functionality on those cpu's that implement it. */
|
||||||
|
unsigned long *hwcap = WEAKADDR(_dl_hwcap);
|
||||||
|
int do_flush = (!hwcap || (*hwcap & HWCAP_SPARC_FLUSH));
|
||||||
|
#else
|
||||||
|
int do_flush = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* For thread safety, write the instructions from the bottom and
|
/* For thread safety, write the instructions from the bottom and
|
||||||
flush before we overwrite the critical "b,a". This of course
|
flush before we overwrite the critical "b,a". This of course
|
||||||
@ -248,16 +280,12 @@ elf_machine_fixup_plt (struct link_map *map, const Elf32_Rela *reloc,
|
|||||||
But we also can't tell if we _can_ use flush, so don't. */
|
But we also can't tell if we _can_ use flush, so don't. */
|
||||||
|
|
||||||
reloc_addr[2] = OPCODE_JMP_G1 | (value & 0x3ff);
|
reloc_addr[2] = OPCODE_JMP_G1 | (value & 0x3ff);
|
||||||
#ifndef RTLD_BOOTSTRAP
|
if (do_flush)
|
||||||
if (_dl_hwcap & HWCAP_SPARC_FLUSH)
|
|
||||||
__asm __volatile ("flush %0+8" : : "r"(reloc_addr));
|
__asm __volatile ("flush %0+8" : : "r"(reloc_addr));
|
||||||
#endif
|
|
||||||
|
|
||||||
reloc_addr[1] = OPCODE_SETHI_G1 | (value >> 10);
|
reloc_addr[1] = OPCODE_SETHI_G1 | (value >> 10);
|
||||||
#ifndef RTLD_BOOTSTRAP
|
if (do_flush)
|
||||||
if (_dl_hwcap & HWCAP_SPARC_FLUSH)
|
|
||||||
__asm __volatile ("flush %0+4" : : "r"(reloc_addr));
|
__asm __volatile ("flush %0+4" : : "r"(reloc_addr));
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the final value of a plt relocation. */
|
/* Return the final value of a plt relocation. */
|
||||||
@ -278,6 +306,15 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
|
|||||||
const Elf32_Sym *sym, const struct r_found_version *version,
|
const Elf32_Sym *sym, const struct r_found_version *version,
|
||||||
Elf32_Addr *const reloc_addr)
|
Elf32_Addr *const reloc_addr)
|
||||||
{
|
{
|
||||||
|
#ifndef RTLD_BOOTSTRAP
|
||||||
|
/* This is defined in rtld.c, but nowhere in the static libc.a; make the
|
||||||
|
reference weak so static programs can still link. This declaration
|
||||||
|
cannot be done when compiling rtld.c (i.e. #ifdef RTLD_BOOTSTRAP)
|
||||||
|
because rtld.c contains the common defn for _dl_rtld_map, which is
|
||||||
|
incompatible with a weak decl in the same file. */
|
||||||
|
weak_extern (_dl_rtld_map);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ELF32_R_TYPE (reloc->r_info) == R_SPARC_RELATIVE)
|
if (ELF32_R_TYPE (reloc->r_info) == R_SPARC_RELATIVE)
|
||||||
{
|
{
|
||||||
#ifndef RTLD_BOOTSTRAP
|
#ifndef RTLD_BOOTSTRAP
|
||||||
|
@ -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).
|
Contributed by Richard Henderson (rth@tamu.edu).
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
@ -26,21 +26,18 @@
|
|||||||
|
|
||||||
.text
|
.text
|
||||||
.align 4
|
.align 4
|
||||||
.globl __libc_clone
|
.globl __clone
|
||||||
.type __libc_clone,@function
|
.type __clone,@function
|
||||||
.weak clone
|
|
||||||
__clone = __libc_clone
|
|
||||||
clone = __libc_clone
|
|
||||||
|
|
||||||
__libc_clone:
|
__clone:
|
||||||
save %sp,-96,%sp
|
save %sp,-96,%sp
|
||||||
|
|
||||||
/* sanity check arguments */
|
/* sanity check arguments */
|
||||||
tst %i0
|
tst %i0
|
||||||
be __clone_syscall_error
|
be .Lerror
|
||||||
tst %i1
|
tst %i1
|
||||||
be __clone_syscall_error
|
be .Lerror
|
||||||
nop
|
nop
|
||||||
|
|
||||||
/* Do the system call */
|
/* Do the system call */
|
||||||
mov %i1,%o1
|
mov %i1,%o1
|
||||||
@ -48,23 +45,31 @@ __libc_clone:
|
|||||||
set __NR_clone,%g1
|
set __NR_clone,%g1
|
||||||
ta 0x10
|
ta 0x10
|
||||||
bcs __clone_syscall_error
|
bcs __clone_syscall_error
|
||||||
tst %o1
|
tst %o1
|
||||||
bne __thread_start
|
bne __thread_start
|
||||||
nop
|
nop
|
||||||
mov %o0,%i0
|
mov %o0,%i0
|
||||||
ret
|
ret
|
||||||
restore
|
restore
|
||||||
|
|
||||||
__clone_syscall_error:
|
.Lerror:
|
||||||
call __errno_location
|
call __errno_location
|
||||||
set EINVAL,%i0
|
set EINVAL,%i0
|
||||||
st %i0,[%o0]
|
st %i0,[%o0]
|
||||||
mov -1,%i0
|
mov -1,%i0
|
||||||
ret
|
ret
|
||||||
restore
|
restore
|
||||||
|
|
||||||
|
.size __clone, .-__clone
|
||||||
|
|
||||||
|
.type __thread_start,@function
|
||||||
|
|
||||||
__thread_start:
|
__thread_start:
|
||||||
call %i0
|
call %i0
|
||||||
mov %i3,%o0
|
mov %i3,%o0
|
||||||
call _exit,0
|
call _exit,0
|
||||||
nop
|
nop
|
||||||
|
|
||||||
|
.size __thread_start, .-__thread_start
|
||||||
|
|
||||||
|
weak_alias(__clone, clone)
|
||||||
|
@ -21,120 +21,65 @@
|
|||||||
#include <syscall.h>
|
#include <syscall.h>
|
||||||
#include <sys/signal.h>
|
#include <sys/signal.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <kernel_sigaction.h>
|
||||||
|
|
||||||
/* The variable is shared between all wrappers around signal handling
|
/* The variable is shared between all wrappers around signal handling
|
||||||
functions which have RT equivalents. */
|
functions which have RT equivalents. */
|
||||||
int __libc_missing_rt_sigs;
|
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
|
int
|
||||||
__trampoline_sigaction (int sig, struct sigaction *new, struct sigaction *old)
|
__sigaction (int sig, __const struct sigaction *act, struct sigaction *oact)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
int ret;
|
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;
|
sig = -sig;
|
||||||
|
|
||||||
__asm__("or %%g0,%0,%%g1\n\t"
|
if (act)
|
||||||
"or %%g0,%1,%%o0\n\t"
|
{
|
||||||
"or %%g0,%2,%%o1\n\t"
|
k_sigact.sa_handler = act->sa_handler;
|
||||||
"or %%g0,%3,%%o2\n\t"
|
k_sigact.sa_mask = act->sa_mask.__val[0];
|
||||||
"t 0x10\n\t"
|
k_sigact.sa_flags = act->sa_flags;
|
||||||
"bcc 1f\n\t"
|
}
|
||||||
"or %%o0, %%g0, %0\n\t"
|
|
||||||
"sub %%g0,%%o0,%0\n\t"
|
{
|
||||||
"1:"
|
register int r_syscallnr __asm__("%g1") = __NR_sigaction;
|
||||||
: "=r" (ret), "=r" ((long int) sig), "=r" ((long int) new),
|
register int r_sig __asm__("%o0") = sig;
|
||||||
"=r" ((long int) old)
|
register struct kernel_sigaction *r_act __asm__("%o1");
|
||||||
: "0" (__NR_sigaction), "1" (sig), "2" (new), "3" (old)
|
register struct kernel_sigaction *r_oact __asm__("%o2");
|
||||||
: "g1", "o0", "o1", "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)
|
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);
|
__set_errno (-ret);
|
||||||
return -1;
|
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);
|
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.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Miguel de Icaza <miguel@gnu.ai.mit.edu>, 1997.
|
Contributed by Miguel de Icaza <miguel@gnu.ai.mit.edu>, 1997.
|
||||||
|
|
||||||
|
@ -26,13 +26,10 @@
|
|||||||
|
|
||||||
.text
|
.text
|
||||||
.align 4
|
.align 4
|
||||||
.globl __libc_clone
|
.globl __clone
|
||||||
.type __libc_clone,@function
|
.type __clone,@function
|
||||||
.weak clone
|
|
||||||
__clone = __libc_clone
|
|
||||||
clone = __libc_clone
|
|
||||||
|
|
||||||
__libc_clone:
|
__clone:
|
||||||
save %sp,-160,%sp
|
save %sp,-160,%sp
|
||||||
|
|
||||||
/* sanity check arguments */
|
/* sanity check arguments */
|
||||||
@ -77,7 +74,7 @@ __libc_clone:
|
|||||||
mov -1,%i0
|
mov -1,%i0
|
||||||
ret
|
ret
|
||||||
restore
|
restore
|
||||||
.size __libc_clone, .-__libc_clone
|
.size __clone, .-__clone
|
||||||
|
|
||||||
.type __thread_start,@function
|
.type __thread_start,@function
|
||||||
__thread_start:
|
__thread_start:
|
||||||
@ -88,3 +85,5 @@ __thread_start:
|
|||||||
call _exit,0
|
call _exit,0
|
||||||
nop
|
nop
|
||||||
.size __thread_start, .-__thread_start
|
.size __thread_start, .-__thread_start
|
||||||
|
|
||||||
|
weak_alias(__clone, clone)
|
||||||
|
Loading…
Reference in New Issue
Block a user