summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ldso/ldso/i386/elfinterp.c6
-rw-r--r--ldso/ldso/ldso.c3
-rw-r--r--libc/sysdeps/linux/common/__rt_sigwaitinfo.c2
-rw-r--r--libc/sysdeps/linux/common/__syscall_rt_sigaction.c4
-rw-r--r--libc/sysdeps/linux/common/_exit.c10
-rw-r--r--libc/sysdeps/linux/common/bits/kernel_sigaction.h67
-rw-r--r--libc/sysdeps/linux/i386/brk.c41
-rw-r--r--libc/sysdeps/linux/i386/sigaction.c158
8 files changed, 111 insertions, 180 deletions
diff --git a/ldso/ldso/i386/elfinterp.c b/ldso/ldso/i386/elfinterp.c
index 62e854d87..deb10310c 100644
--- a/ldso/ldso/i386/elfinterp.c
+++ b/ldso/ldso/i386/elfinterp.c
@@ -73,7 +73,7 @@ _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
got_addr = (char **)instr_addr;
/* Get the address of the GOT entry. */
- new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
+ new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, NULL);
if (unlikely(!new_addr)) {
_dl_dprintf(2, "%s: can't resolve symbol '%s' in lib '%s'.\n", _dl_progname, symname, tpnt->libname);
_dl_exit(1);
@@ -166,6 +166,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
char *symname;
unsigned long *reloc_addr;
unsigned long symbol_addr;
+ struct elf_resolve *def_mod = 0;
#if defined (__SUPPORT_LD_DEBUG__)
unsigned long old_val;
#endif
@@ -178,7 +179,8 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
if (symtab_index) {
symbol_addr = (unsigned long)_dl_find_hash(symname, scope, tpnt,
- elf_machine_type_class(reloc_type));
+ elf_machine_type_class(reloc_type),
+ &def_mod);
/*
* We want to allow undefined references to weak symbols - this
diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c
index c05db8241..f74fb4aab 100644
--- a/ldso/ldso/ldso.c
+++ b/ldso/ldso/ldso.c
@@ -842,6 +842,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
_dl_protect_relro (tpnt);
}
+#if USE_TLS
if (!was_tls_init_tp_called && _dl_tls_max_dtv_idx > 0)
++_dl_tls_generation;
@@ -863,6 +864,8 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
_dl_exit(30);
}
}
+#endif /* USE_TLS */
+
/* OK, at this point things are pretty much ready to run. Now we need
* to touch up a few items that are required, and then we can let the
* user application have at it. Note that the dynamic linker itself
diff --git a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c
index 5a35a5d49..1adc0fd73 100644
--- a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c
+++ b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c
@@ -77,7 +77,7 @@ int __sigwaitinfo(const sigset_t *set, siginfo_t *info)
# else
# define __need_NULL
# include <stddef.h>
-# define __NR___rt_sigwaitinfo __NR_rt_sigwaitinfo
+# define __NR___rt_sigwaitinfo __NR_rt_sigtimedwait
static _syscall4(int, __rt_sigwaitinfo, const sigset_t *, set,
siginfo_t *, info, const struct timespec *, timeout,
size_t, setsize);
diff --git a/libc/sysdeps/linux/common/__syscall_rt_sigaction.c b/libc/sysdeps/linux/common/__syscall_rt_sigaction.c
index 0f5329cfb..6fb416039 100644
--- a/libc/sysdeps/linux/common/__syscall_rt_sigaction.c
+++ b/libc/sysdeps/linux/common/__syscall_rt_sigaction.c
@@ -13,8 +13,8 @@
#include <signal.h>
#include <bits/kernel_sigaction.h>
-#define __NR___syscall_rt_sigaction __NR_rt_sigaction
-_syscall4(int, __syscall_rt_sigaction, int, signum,
+#define __NR___rt_sigaction __NR_rt_sigaction
+_syscall4(int, __rt_sigaction, int, signum,
const struct kernel_sigaction *, act, struct kernel_sigaction *, oldact,
size_t, size)
#endif
diff --git a/libc/sysdeps/linux/common/_exit.c b/libc/sysdeps/linux/common/_exit.c
index a0b891d25..518a6d2e8 100644
--- a/libc/sysdeps/linux/common/_exit.c
+++ b/libc/sysdeps/linux/common/_exit.c
@@ -12,9 +12,6 @@
#include <unistd.h>
#include <sys/types.h>
#include <sys/syscall.h>
-#ifdef __UCLIBC_HAS_THREADS__
-#include <sysdep.h>
-#endif
/* libc_hidden_proto(_exit) */
@@ -28,13 +25,6 @@ void attribute_noreturn _exit(int status)
{
/* The loop is added only to keep gcc happy. */
while(1)
- {
-#ifdef __UCLIBC_HAS_THREADS_NATIVE__
-# ifdef __NR_exit_group
- INLINE_SYSCALL(exit_group, 1, status);
-# endif
-#endif
INLINE_SYSCALL(exit, 1, status);
- }
}
libc_hidden_def(_exit)
diff --git a/libc/sysdeps/linux/common/bits/kernel_sigaction.h b/libc/sysdeps/linux/common/bits/kernel_sigaction.h
index ec414e1e3..f74e0a28a 100644
--- a/libc/sysdeps/linux/common/bits/kernel_sigaction.h
+++ b/libc/sysdeps/linux/common/bits/kernel_sigaction.h
@@ -4,72 +4,33 @@
/* This file provides whatever this particular arch's kernel thinks
* the sigaction struct should look like... */
-#undef NO_OLD_SIGACTION
-#if defined(__mips__)
-/* We have libc/sysdeps/linux/mips/bits/kernel_sigaction.h,
- * so this should never be used. Lets see whether it is true. */
-struct BUG_is_here { char BUG_is_here[-1]; };
+#if defined(__ia64__)
#undef HAVE_SA_RESTORER
-/* This is the sigaction structure from the Linux 2.1.24 kernel. */
-#include <sgidefs.h>
-struct old_kernel_sigaction {
- __sighandler_t k_sa_handler;
- unsigned int sa_flags;
- unsigned long sa_mask;
-};
-#define _KERNEL_NSIG 128
-#define _KERNEL_NSIG_BPW 32
-#define _KERNEL_NSIG_WORDS (_KERNEL_NSIG / _KERNEL_NSIG_BPW)
-typedef struct {
- unsigned long sig[_KERNEL_NSIG_WORDS];
-} kernel_sigset_t;
-/* This is the sigaction structure from the Linux 2.1.68 kernel. */
-struct kernel_sigaction {
- unsigned int sa_flags;
- __sighandler_t k_sa_handler;
- kernel_sigset_t sa_mask;
- void (*sa_restorer)(void);
- int s_resv[1]; /* reserved */
-};
-
-#elif defined(__ia64__)
-
-#define NO_OLD_SIGACTION
-#undef HAVE_SA_RESTORER
-struct kernel_sigaction {
- __sighandler_t k_sa_handler;
- unsigned long sa_flags;
- sigset_t sa_mask;
-};
#else
#define HAVE_SA_RESTORER
/* This is the sigaction structure from the Linux 2.1.20 kernel. */
struct old_kernel_sigaction {
- __sighandler_t k_sa_handler;
- unsigned long sa_mask;
- unsigned long sa_flags;
- void (*sa_restorer) (void);
-};
-/* This is the sigaction structure from the Linux 2.1.68 kernel. */
-struct kernel_sigaction {
- __sighandler_t k_sa_handler;
- unsigned long sa_flags;
- void (*sa_restorer) (void);
- sigset_t sa_mask;
+ __sighandler_t k_sa_handler;
+ unsigned long sa_mask;
+ unsigned long sa_flags;
+ void (*sa_restorer)(void);
};
+/* In uclibc, userspace struct sigaction is identical to
+ * "new" struct kernel_sigaction (one from the Linux 2.1.68 kernel).
+ * See sigaction.h
+ */
-#endif
+extern int __syscall_sigaction(int, const struct old_kernel_sigaction *,
+ struct old_kernel_sigaction *) attribute_hidden;
-#ifndef NO_OLD_SIGACTION
-extern int __syscall_sigaction (int, const struct old_kernel_sigaction *__unbounded,
- struct old_kernel_sigaction *__unbounded) attribute_hidden;
#endif
-extern int __syscall_rt_sigaction (int, const struct kernel_sigaction *__unbounded,
- struct kernel_sigaction *__unbounded, size_t);
+
+extern int __syscall_rt_sigaction(int, const struct sigaction *,
+ struct sigaction *, size_t) attribute_hidden;
#endif /* _BITS_SIGACTION_STRUCT_H */
diff --git a/libc/sysdeps/linux/i386/brk.c b/libc/sysdeps/linux/i386/brk.c
index 2be9c1802..4b47a3b19 100644
--- a/libc/sysdeps/linux/i386/brk.c
+++ b/libc/sysdeps/linux/i386/brk.c
@@ -25,25 +25,28 @@
void *__curbrk attribute_hidden = 0;
/* libc_hidden_proto(brk) */
-int brk (void *addr)
+int brk(void *addr)
{
- void *__unbounded newbrk, *__unbounded scratch;
-
- __asm__ ("movl %%ebx, %1\n" /* Save %ebx in scratch register. */
- "movl %3, %%ebx\n" /* Put ADDR in %ebx to be syscall arg. */
- "int $0x80 # %2\n" /* Perform the system call. */
- "movl %1, %%ebx\n" /* Restore %ebx from scratch register. */
- : "=a" (newbrk), "=r" (scratch)
- : "0" (__NR_brk), "g" (__ptrvalue (addr)));
-
- __curbrk = newbrk;
-
- if (newbrk < addr)
- {
- __set_errno (ENOMEM);
- return -1;
- }
-
- return 0;
+ void *newbrk;
+
+ /* %ebx is used in PIC code, need to save/restore it manually.
+ * gcc won't do it for us if we will request it in constraints
+ */
+ __asm__("pushl %%ebx\n"
+ "movl %2, %%ebx\n"
+ "int $0x80\n"
+ "popl %%ebx\n"
+ : "=a" (newbrk)
+ : "0" (__NR_brk), "g" (addr)
+ );
+
+ __curbrk = newbrk;
+
+ if (newbrk < addr) {
+ __set_errno(ENOMEM);
+ return -1;
+ }
+
+ return 0;
}
libc_hidden_def(brk)
diff --git a/libc/sysdeps/linux/i386/sigaction.c b/libc/sysdeps/linux/i386/sigaction.c
index e323d0938..602f759a4 100644
--- a/libc/sysdeps/linux/i386/sigaction.c
+++ b/libc/sysdeps/linux/i386/sigaction.c
@@ -29,115 +29,89 @@
extern __typeof(sigaction) __libc_sigaction;
+
#if defined __NR_rt_sigaction
-/* Experimentally off - libc_hidden_proto(memcpy) */
-extern void restore_rt (void) __asm__ ("__restore_rt") attribute_hidden;
-extern void restore (void) __asm__ ("__restore") attribute_hidden;
+extern void restore_rt(void) __asm__ ("__restore_rt") attribute_hidden;
+extern void restore(void) __asm__ ("__restore") attribute_hidden;
/* If ACT is not NULL, change the action for SIG to *ACT.
If OACT is not NULL, put the old action for SIG in *OACT. */
-int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
+int __libc_sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
{
- int result;
- struct kernel_sigaction kact, koact;
- enum {
- SIGSET_MIN_SIZE = sizeof(kact.sa_mask) < sizeof(act->sa_mask)
- ? sizeof(kact.sa_mask) : sizeof(act->sa_mask)
- };
+ struct sigaction kact;
#ifdef SIGCANCEL
if (sig == SIGCANCEL) {
- __set_errno (EINVAL);
+ __set_errno(EINVAL);
return -1;
}
#endif
-
if (act) {
- kact.k_sa_handler = act->sa_handler;
- memcpy (&kact.sa_mask, &act->sa_mask, SIGSET_MIN_SIZE);
- kact.sa_flags = act->sa_flags;
-
- kact.sa_flags = act->sa_flags | SA_RESTORER;
- kact.sa_restorer = ((act->sa_flags & SA_SIGINFO)
- ? &restore_rt : &restore);
+ memcpy(&kact, act, sizeof(kact));
+ kact.sa_flags |= SA_RESTORER;
+ kact.sa_restorer = (act->sa_flags & SA_SIGINFO) ? &restore_rt : &restore;
+ act = &kact;
}
-
/* NB: kernel (as of 2.6.25) will return EINVAL
- * if sizeof(kact.sa_mask) does not match kernel's sizeof(sigset_t) */
- result = __syscall_rt_sigaction(sig,
- act ? __ptrvalue (&kact) : NULL,
- oact ? __ptrvalue (&koact) : NULL,
- sizeof(kact.sa_mask));
-
- if (oact && result >= 0) {
- oact->sa_handler = koact.k_sa_handler;
- memcpy (&oact->sa_mask, &koact.sa_mask, SIGSET_MIN_SIZE);
- oact->sa_flags = koact.sa_flags;
- oact->sa_restorer = koact.sa_restorer;
- }
- return result;
+ * if sizeof(act->sa_mask) does not match kernel's sizeof(sigset_t) */
+ return __syscall_rt_sigaction(sig, act, oact, sizeof(act->sa_mask));
}
-
#else
-extern void restore (void) __asm__ ("__restore") attribute_hidden;
+
+extern void restore(void) __asm__ ("__restore") attribute_hidden;
/* If ACT is not NULL, change the action for SIG to *ACT.
If OACT is not NULL, put the old action for SIG in *OACT. */
-int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
+int __libc_sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
{
- int result;
- struct old_kernel_sigaction kact, koact;
+ int result;
+ struct old_kernel_sigaction kact, koact;
#ifdef SIGCANCEL
- if (sig == SIGCANCEL) {
- __set_errno (EINVAL);
- return -1;
- }
+ if (sig == SIGCANCEL) {
+ __set_errno(EINVAL);
+ return -1;
+ }
#endif
-
- if (act) {
- kact.k_sa_handler = act->sa_handler;
- kact.sa_mask = act->sa_mask.__val[0];
- kact.sa_flags = act->sa_flags | SA_RESTORER;
- kact.sa_restorer = &restore;
- }
-
- __asm__ __volatile__ ("pushl %%ebx\n"
- "movl %3, %%ebx\n"
- "int $0x80\n"
- "popl %%ebx"
- : "=a" (result), "=m" (koact)
- : "0" (__NR_sigaction), "r" (sig), "m" (kact),
- "c" (act ? __ptrvalue (&kact) : 0),
- "d" (oact ? __ptrvalue (&koact) : 0));
-
- if (result < 0) {
- __set_errno(-result);
- return -1;
- }
-
- if (oact) {
- oact->sa_handler = koact.k_sa_handler;
- oact->sa_mask.__val[0] = koact.sa_mask;
- oact->sa_flags = koact.sa_flags;
- oact->sa_restorer = koact.sa_restorer;
- }
- return result;
+ if (act) {
+ kact.k_sa_handler = act->sa_handler;
+ kact.sa_mask = act->sa_mask.__val[0];
+ kact.sa_flags = act->sa_flags | SA_RESTORER;
+ kact.sa_restorer = &restore;
+ }
+ __asm__ __volatile__ (
+ " pushl %%ebx\n"
+ " movl %3, %%ebx\n"
+ " int $0x80\n"
+ " popl %%ebx\n"
+ : "=a" (result), "=m" (koact)
+ : "0" (__NR_sigaction), "r" (sig), "m" (kact),
+ "c" (act ? &kact : NULL),
+ "d" (oact ? &koact : NULL));
+ if (result < 0) {
+ __set_errno(-result);
+ return -1;
+ }
+ if (oact) {
+ oact->sa_handler = koact.k_sa_handler;
+ oact->sa_mask.__val[0] = koact.sa_mask;
+ oact->sa_flags = koact.sa_flags;
+ oact->sa_restorer = koact.sa_restorer;
+ }
+ return result;
}
#endif
+
#ifndef LIBC_SIGACTION
-/* libc_hidden_proto(sigaction) */
weak_alias(__libc_sigaction,sigaction)
libc_hidden_weak(sigaction)
#endif
-
-
/* NOTE: Please think twice before making any changes to the bits of
code below. GDB needs some intimate knowledge about it to
recognize them as signal trampolines, and make backtraces through
@@ -146,33 +120,31 @@ libc_hidden_weak(sigaction)
If you ever feel the need to make any changes, please notify the
appropriate GDB maintainer. */
-#define RESTORE(name, syscall) RESTORE2 (name, syscall)
+#define RESTORE(name, syscall) RESTORE2(name, syscall)
#define RESTORE2(name, syscall) \
-__asm__ \
- ( \
- ".text\n" \
- "__" #name ":\n" \
- " movl $" #syscall ", %eax\n" \
- " int $0x80" \
- );
+__asm__ ( \
+ ".text\n" \
+ "__" #name ":\n" \
+ " movl $" #syscall ", %eax\n" \
+ " int $0x80\n" \
+);
#ifdef __NR_rt_sigaction
/* The return code for realtime-signals. */
-RESTORE (restore_rt, __NR_rt_sigreturn)
+RESTORE(restore_rt, __NR_rt_sigreturn)
#endif
#ifdef __NR_sigreturn
/* For the boring old signals. */
# undef RESTORE2
# define RESTORE2(name, syscall) \
-__asm__ \
- ( \
- ".text\n" \
- "__" #name ":\n" \
- " popl %eax\n" \
- " movl $" #syscall ", %eax\n" \
- " int $0x80" \
- );
-
-RESTORE (restore, __NR_sigreturn)
+__asm__ ( \
+ ".text\n" \
+ "__" #name ":\n" \
+ " popl %eax\n" \
+ " movl $" #syscall ", %eax\n" \
+ " int $0x80\n" \
+);
+
+RESTORE(restore, __NR_sigreturn)
#endif