summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libpthread/nptl/Makefile.in12
-rw-r--r--libpthread/nptl/cancellation.c2
-rw-r--r--libpthread/nptl/descr.h19
-rw-r--r--libpthread/nptl/forward.c8
-rw-r--r--libpthread/nptl/init.c44
-rw-r--r--libpthread/nptl/pt-system.c3
-rw-r--r--libpthread/nptl/pthread_cancel.c10
-rw-r--r--libpthread/nptl/res.c3
-rw-r--r--libpthread/nptl/sysdeps/generic/dl-support.c15
-rw-r--r--libpthread/nptl/sysdeps/generic/dl-tls.c82
-rw-r--r--libpthread/nptl/sysdeps/generic/libc-tls.c5
-rw-r--r--libpthread/nptl/sysdeps/generic/sysdep.h21
-rw-r--r--libpthread/nptl/sysdeps/pthread/Makefile.in20
-rw-r--r--libpthread/nptl/sysdeps/pthread/bits/libc-lock.h7
-rw-r--r--libpthread/nptl/sysdeps/pthread/bits/stdio-lock.h1
-rw-r--r--libpthread/nptl/sysdeps/pthread/pthread.h5
-rw-r--r--libpthread/nptl/sysdeps/pthread/sigaction.c7
-rw-r--r--libpthread/nptl/sysdeps/pthread/unwind-resume.c5
-rw-r--r--libpthread/nptl/sysdeps/unix/sysdep.h61
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in75
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/close.S14
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/fork.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/open.S14
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/read.S12
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sigwait.c2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/waitpid.S19
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/write.S12
-rw-r--r--libpthread/nptl_db/structs.def4
-rw-r--r--libpthread/nptl_db/td_thr_tlsbase.c13
29 files changed, 383 insertions, 113 deletions
diff --git a/libpthread/nptl/Makefile.in b/libpthread/nptl/Makefile.in
index 9761f9670..4e1db3dcc 100644
--- a/libpthread/nptl/Makefile.in
+++ b/libpthread/nptl/Makefile.in
@@ -150,7 +150,7 @@ CFLAGS-msgrcv.c = -fexceptions -fasynchronous-unwind-tables
CFLAGS-msgsnd.c = -fexceptions -fasynchronous-unwind-tables
CFLAGS-tcdrain.c = -fexceptions -fasynchronous-unwind-tables
-CFLAGS-pt-system.c = -fexceptions
+CFLAGS-pt-system.c = -fexceptions -I./libc/stdlib
#
# The rest of this file is uClibc specific.
@@ -235,7 +235,7 @@ libpthread_so_SRC = $(patsubst %, $(PTHREAD_DIR)/%.c, \
$(libpthread-misc-routines), $(libpthread-routines)))
libc-static-y += $(patsubst %.c, $(PTHREAD_OUT)/%.o, alloca_cutoff.c \
- forward.c libc-cancellation.c)
+ libc-cancellation.c)
libc-shared-y += $(patsubst %.c, $(PTHREAD_OUT)/%.oS, forward.c \
libc-cancellation.c)
libpthread-nonshared-y += $(patsubst %,$(PTHREAD_OUT)/%.oS,$(libpthread_static_SRC))
@@ -272,7 +272,7 @@ endif
$(do_ar)
ifeq ($(DOPIC),y)
-$(top_builddir)lib/libpthread.a: $(libpthread-a-y:.o=.oS)
+$(top_builddir)lib/libpthread.a: $(libpthread-a-y:.o=.os)
else
$(top_builddir)lib/libpthread.a: $(libpthread-a-y)
endif
@@ -295,7 +295,7 @@ $(PTHREAD_OUT)/pthread-errnos.s: $(PTHREAD_OUT)/pthread-errnos.c
$(PTHREAD_OUT)/pthread-errnos.h: $(PTHREAD_OUT)/pthread-errnos.s
@sed -n "s/^.*@@@name@@@\([^@]*\)@@@value@@@[^0-9Xxa-fA-F-]*\([0-9Xxa-fA-F-][0-9Xxa-fA-F-]*\).*@@@end@@@.*$\/#define \1 \2/p" $< > $(PTHREAD_OUT)/pthread-errnos.h
-nptl_headers:
+nptl_headers_bootstrap:
@sed 's/\(.*\)/"\1\\n"/' $(PTDIR)/Banner > $(PTDIR)/banner.h
@echo "#define VERSION \""$(VERSION)"\"" > $(PTDIR)/version.h
$(LN) -sf ../$(PTDIR)/sysdeps/pthread/pthread.h $(top_builddir)include/
@@ -305,6 +305,8 @@ nptl_headers:
$(LN) -sf ../../$(PTDIR)/sysdeps/unix/sysv/linux/$(TARGET_ARCH)/bits/pthreadtypes.h $(top_builddir)include/bits/
$(LN) -sf ../../$(PTDIR)/sysdeps/pthread/bits/libc-lock.h $(top_builddir)include/bits/
$(LN) -sf ../../$(PTDIR)/sysdeps/pthread/bits/stdio-lock.h $(top_builddir)include/bits/
+
+nptl_headers:
ifeq ($(shell $(CC) --help >& /dev/null && echo yes),yes)
$(MAKE) $(PTHREAD_OUT)/pthread-errnos.h
endif
@@ -315,4 +317,4 @@ nptl_headers_clean:
$(PTHREAD_OUT)/pthread-errnos.{c,h,s}
libpthread_clean:
- $(RM) $(PTHREAD_OUT)/*.{o,os,oS}
+ $(RM) $(PTHREAD_OUT)/*.{o,os,oS,a}
diff --git a/libpthread/nptl/cancellation.c b/libpthread/nptl/cancellation.c
index 59e16b9e1..1d28d383f 100644
--- a/libpthread/nptl/cancellation.c
+++ b/libpthread/nptl/cancellation.c
@@ -32,7 +32,6 @@ __pthread_enable_asynccancel (void)
struct pthread *self = THREAD_SELF;
int oldval = THREAD_GETMEM (self, cancelhandling);
-//printf("%s\n", __FUNCTION__);
while (1)
{
int newval = oldval | CANCELTYPE_BITMASK;
@@ -65,7 +64,6 @@ void
internal_function attribute_hidden
__pthread_disable_asynccancel (int oldtype)
{
-//printf("%s\n", __FUNCTION__);
/* If asynchronous cancellation was enabled before we do not have
anything to do. */
if (oldtype & CANCELTYPE_BITMASK)
diff --git a/libpthread/nptl/descr.h b/libpthread/nptl/descr.h
index 474fa9caa..12e48a83c 100644
--- a/libpthread/nptl/descr.h
+++ b/libpthread/nptl/descr.h
@@ -96,7 +96,7 @@ struct pthread_unwind_buf
struct xid_command
{
int syscall_no;
- long id[3];
+ long int id[3];
volatile int cntr;
};
@@ -160,8 +160,11 @@ struct pthread
/* Bit set if thread terminated and TCB is freed. */
#define TERMINATED_BIT 5
#define TERMINATED_BITMASK 0x20
+ /* Bit set if thread is supposed to change XID. */
+#define SETXID_BIT 6
+#define SETXID_BITMASK 0x40
/* Mask for the rest. Helps the compiler to optimize. */
-#define CANCEL_RESTMASK 0xffffffc0
+#define CANCEL_RESTMASK 0xffffff80
#define CANCEL_ENABLED_AND_CANCELED(value) \
(((value) & (CANCELSTATE_BITMASK | CANCELED_BITMASK | EXITING_BITMASK \
@@ -202,6 +205,9 @@ struct pthread
/* Lock to synchronize access to the descriptor. */
lll_lock_t lock;
+ /* Lock for synchronizing setxid calls. */
+ lll_lock_t setxid_futex;
+
#if HP_TIMING_AVAIL
/* Offset of the CPU clock at start thread start time. */
hp_timing_t cpuclock_offset;
@@ -254,12 +260,11 @@ struct pthread
/* Resolver state. */
struct __res_state res;
- /* If you add fields after the res field above, please adjust
- the following macro. */
-#define PTHREAD_STRUCT_END_PADDING \
- (sizeof (struct pthread) - offsetof (struct pthread, res) \
- - sizeof (((struct pthread *) 0)->res))
+ /* This member must be last. */
+ char end_padding[];
+#define PTHREAD_STRUCT_END_PADDING \
+ (sizeof (struct pthread) - offsetof (struct pthread, end_padding))
} __attribute ((aligned (TCB_ALIGNMENT)));
diff --git a/libpthread/nptl/forward.c b/libpthread/nptl/forward.c
index 843096841..5b71f8e67 100644
--- a/libpthread/nptl/forward.c
+++ b/libpthread/nptl/forward.c
@@ -123,25 +123,25 @@ FORWARD (pthread_setschedparam,
FORWARD (pthread_mutex_destroy, (pthread_mutex_t *mutex), (mutex), 0)
+libc_hidden_proto(pthread_mutex_init)
FORWARD (pthread_mutex_init,
(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr),
(mutex, mutexattr), 0)
-libc_hidden_proto(pthread_mutex_init)
strong_alias(pthread_mutex_init, __pthread_mutex_init)
libc_hidden_def(pthread_mutex_init)
-FORWARD (pthread_mutex_trylock, (pthread_mutex_t *mutex), (mutex), 0)
libc_hidden_proto(pthread_mutex_trylock)
+FORWARD (pthread_mutex_trylock, (pthread_mutex_t *mutex), (mutex), 0)
strong_alias(pthread_mutex_trylock, __pthread_mutex_trylock)
libc_hidden_def(pthread_mutex_trylock)
-FORWARD (pthread_mutex_lock, (pthread_mutex_t *mutex), (mutex), 0)
libc_hidden_proto(pthread_mutex_lock)
+FORWARD (pthread_mutex_lock, (pthread_mutex_t *mutex), (mutex), 0)
strong_alias(pthread_mutex_lock, __pthread_mutex_lock)
libc_hidden_def(pthread_mutex_lock)
-FORWARD (pthread_mutex_unlock, (pthread_mutex_t *mutex), (mutex), 0)
libc_hidden_proto(pthread_mutex_unlock)
+FORWARD (pthread_mutex_unlock, (pthread_mutex_t *mutex), (mutex), 0)
strong_alias(pthread_mutex_unlock, __pthread_mutex_unlock)
libc_hidden_def(pthread_mutex_unlock)
diff --git a/libpthread/nptl/init.c b/libpthread/nptl/init.c
index ead1a3fba..cd5d39314 100644
--- a/libpthread/nptl/init.c
+++ b/libpthread/nptl/init.c
@@ -271,6 +271,17 @@ __pthread_initialize_minimal_internal (void)
(void) INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_UNBLOCK, &sa.sa_mask,
NULL, _NSIG / 8);
+ /* Get the size of the static and alignment requirements for the TLS
+ block. */
+ size_t static_tls_align;
+ _dl_get_tls_static_info (&__static_tls_size, &static_tls_align);
+
+ /* Make sure the size takes all the alignments into account. */
+ if (STACK_ALIGN > static_tls_align)
+ static_tls_align = STACK_ALIGN;
+ __static_tls_align_m1 = static_tls_align - 1;
+
+ __static_tls_size = roundup (__static_tls_size, static_tls_align);
/* Determine the default allowed stack size. This is the size used
in case the user does not specify one. */
@@ -279,29 +290,28 @@ __pthread_initialize_minimal_internal (void)
|| limit.rlim_cur == RLIM_INFINITY)
/* The system limit is not usable. Use an architecture-specific
default. */
- __default_stacksize = ARCH_STACK_DEFAULT_SIZE;
+ limit.rlim_cur = ARCH_STACK_DEFAULT_SIZE;
else if (limit.rlim_cur < PTHREAD_STACK_MIN)
/* The system limit is unusably small.
Use the minimal size acceptable. */
- __default_stacksize = PTHREAD_STACK_MIN;
- else
- {
- /* Round the resource limit up to page size. */
- const uintptr_t pagesz = sysconf (_SC_PAGESIZE);
- __default_stacksize = (limit.rlim_cur + pagesz - 1) & -pagesz;
- }
+ limit.rlim_cur = PTHREAD_STACK_MIN;
- /* Get the size of the static and alignment requirements for the TLS
- block. */
- size_t static_tls_align;
- _dl_get_tls_static_info (&__static_tls_size, &static_tls_align);
+ /* Make sure it meets the minimum size that allocate_stack
+ (allocatestack.c) will demand, which depends on the page size. */
+ const uintptr_t pagesz = sysconf (_SC_PAGESIZE);
+ const size_t minstack = pagesz + __static_tls_size + MINIMAL_REST_STACK;
+ if (limit.rlim_cur < minstack)
+ limit.rlim_cur = minstack;
- /* Make sure the size takes all the alignments into account. */
- if (STACK_ALIGN > static_tls_align)
- static_tls_align = STACK_ALIGN;
- __static_tls_align_m1 = static_tls_align - 1;
+ /* Round the resource limit up to page size. */
+ limit.rlim_cur = (limit.rlim_cur + pagesz - 1) & -pagesz;
+ __default_stacksize = limit.rlim_cur;
- __static_tls_size = roundup (__static_tls_size, static_tls_align);
+#ifdef SHARED
+ /* Transfer the old value from the dynamic linker's internal location. */
+ *__libc_dl_error_tsd () = *(*GL(dl_error_catch_tsd)) ();
+ GL(dl_error_catch_tsd) = &__libc_dl_error_tsd;
+#endif
GL(dl_init_static_tls) = &__pthread_init_static_tls;
diff --git a/libpthread/nptl/pt-system.c b/libpthread/nptl/pt-system.c
index b3b45ab93..09a08ec24 100644
--- a/libpthread/nptl/pt-system.c
+++ b/libpthread/nptl/pt-system.c
@@ -23,6 +23,9 @@
#include "pthreadP.h"
+extern __typeof(system) __libc_system;
+#include <system.c>
+
int
system (const char *line)
{
diff --git a/libpthread/nptl/pthread_cancel.c b/libpthread/nptl/pthread_cancel.c
index 41543fd78..a13af56b3 100644
--- a/libpthread/nptl/pthread_cancel.c
+++ b/libpthread/nptl/pthread_cancel.c
@@ -31,13 +31,11 @@ pthread_cancel (th)
{
volatile struct pthread *pd = (volatile struct pthread *) th;
-//printf("%s:%d\n", __FUNCTION__, __LINE__);
/* Make sure the descriptor is valid. */
if (INVALID_TD_P (pd))
/* Not a valid thread handle. */
return ESRCH;
-//printf("%s:%d\n", __FUNCTION__, __LINE__);
#ifdef SHARED
pthread_cancel_init ();
#endif
@@ -49,20 +47,17 @@ pthread_cancel (th)
oldval = pd->cancelhandling;
newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK;
-//printf("%s:%d\n", __FUNCTION__, __LINE__);
/* Avoid doing unnecessary work. The atomic operation can
potentially be expensive if the bug has to be locked and
remote cache lines have to be invalidated. */
if (oldval == newval)
break;
-//printf("%s:%d newval = %x\n", __FUNCTION__, __LINE__, newval);
/* If the cancellation is handled asynchronously just send a
signal. We avoid this if possible since it's more
expensive. */
if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
{
-//printf("%s:%d\n", __FUNCTION__, __LINE__);
/* Mark the cancellation as "in progress". */
atomic_bit_set (&pd->cancelhandling, CANCELING_BIT);
@@ -81,23 +76,19 @@ pthread_cancel (th)
val = INTERNAL_SYSCALL (tgkill, err, 3,
THREAD_GETMEM (THREAD_SELF, pid), pd->tid,
SIGCANCEL);
-//printf("%s:%d\n", __FUNCTION__, __LINE__);
#else
# ifdef __NR_tgkill
val = INTERNAL_SYSCALL (tgkill, err, 3,
THREAD_GETMEM (THREAD_SELF, pid), pd->tid,
SIGCANCEL);
-//printf("%s:%d\n", __FUNCTION__, __LINE__);
if (INTERNAL_SYSCALL_ERROR_P (val, err)
&& INTERNAL_SYSCALL_ERRNO (val, err) == ENOSYS)
# endif
val = INTERNAL_SYSCALL (tkill, err, 2, pd->tid, SIGCANCEL);
-//printf("%s:%d\n", __FUNCTION__, __LINE__);
#endif
if (INTERNAL_SYSCALL_ERROR_P (val, err))
result = INTERNAL_SYSCALL_ERRNO (val, err);
-//printf("%s:%d\n", __FUNCTION__, __LINE__);
break;
}
@@ -106,7 +97,6 @@ pthread_cancel (th)
atomically since other bits could be modified as well. */
while (atomic_compare_and_exchange_bool_acq (&pd->cancelhandling, newval,
oldval));
-//printf("%s:%d\n", __FUNCTION__, __LINE__);
return result;
}
diff --git a/libpthread/nptl/res.c b/libpthread/nptl/res.c
index ba4f81d06..37529899e 100644
--- a/libpthread/nptl/res.c
+++ b/libpthread/nptl/res.c
@@ -17,8 +17,9 @@
02111-1307 USA. */
#include <features.h>
-#include <resolv.h>
+
#include <tls.h>
+#include <resolv.h>
struct __res_state *
__res_state (void)
diff --git a/libpthread/nptl/sysdeps/generic/dl-support.c b/libpthread/nptl/sysdeps/generic/dl-support.c
index 496694ca4..b8f0c07a6 100644
--- a/libpthread/nptl/sysdeps/generic/dl-support.c
+++ b/libpthread/nptl/sysdeps/generic/dl-support.c
@@ -35,16 +35,11 @@ void
internal_function
_dl_aux_init (ElfW(auxv_t) *av)
{
- for (; av->a_type != AT_NULL; ++av)
- switch (av->a_type)
- {
- case AT_PHDR:
- GL(dl_phdr) = (void *) av->a_un.a_val;
- break;
- case AT_PHNUM:
- GL(dl_phnum) = av->a_un.a_val;
- break;
- }
+ /* Get the program headers base address from the aux vect */
+ GL(dl_phdr) = (ElfW(Phdr) *) av[AT_PHDR].a_un.a_val;
+
+ /* Get the number of program headers from the aux vect */
+ GL(dl_phnum) = (size_t) av[AT_PHNUM].a_un.a_val;
}
/* Initialize static TLS area and DTV for current (only) thread.
diff --git a/libpthread/nptl/sysdeps/generic/dl-tls.c b/libpthread/nptl/sysdeps/generic/dl-tls.c
index 1a045ba5b..ad2e84ea3 100644
--- a/libpthread/nptl/sysdeps/generic/dl-tls.c
+++ b/libpthread/nptl/sysdeps/generic/dl-tls.c
@@ -24,6 +24,8 @@
#include <tls.h>
#include <dl-tls.h>
#include <ldsodefs.h>
+#include <dl-elf.h>
+#include <dl-hash.h>
#include <assert.h>
#include <link.h>
@@ -66,6 +68,86 @@ void *_dl_memalign(size_t alignment, size_t bytes)
return _dl_malloc(bytes);
}
+
+/*
+ * We are trying to perform a static TLS relocation in MAP, but it was
+ * dynamically loaded. This can only work if there is enough surplus in
+ * the static TLS area already allocated for each running thread. If this
+ * object's TLS segment is too big to fit, we fail. If it fits,
+ * we set MAP->l_tls_offset and return.
+ * This function intentionally does not return any value but signals error
+ * directly, as static TLS should be rare and code handling it should
+ * not be inlined as much as possible.
+ */
+
+
+void
+internal_function __attribute_noinline__
+_dl_allocate_static_tls (struct link_map *map)
+{
+ /* If the alignment requirements are too high fail. */
+ if (map->l_tls_align > _dl_tls_static_align)
+ {
+fail:
+ _dl_dprintf(_dl_debug_file, "cannot allocate memory in static TLS block");
+ _dl_exit(30);
+ }
+
+# if TLS_TCB_AT_TP
+ size_t freebytes;
+ size_t n;
+ size_t blsize;
+
+ freebytes = _dl_tls_static_size - _dl_tls_static_used - TLS_TCB_SIZE;
+
+ blsize = map->l_tls_blocksize + map->l_tls_firstbyte_offset;
+ if (freebytes < blsize)
+ goto fail;
+
+ n = (freebytes - blsize) / map->l_tls_align;
+
+ size_t offset = _dl_tls_static_used + (freebytes - n * map->l_tls_align
+ - map->l_tls_firstbyte_offset);
+
+ map->l_tls_offset = _dl_tls_static_used = offset;
+# elif TLS_DTV_AT_TP
+ size_t used;
+ size_t check;
+
+ size_t offset = roundup (_dl_tls_static_used, map->l_tls_align);
+ used = offset + map->l_tls_blocksize;
+ check = used;
+
+ /* dl_tls_static_used includes the TCB at the beginning. */
+ if (check > _dl_tls_static_size)
+ goto fail;
+
+ map->l_tls_offset = offset;
+ _dl_tls_static_used = used;
+# else
+# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
+# endif
+
+ /*
+ * If the object is not yet relocated we cannot initialize the
+ * static TLS region. Delay it.
+ */
+ if (((struct elf_resolve *) map)->init_flag & RELOCS_DONE)
+ {
+#ifdef SHARED
+ /*
+ * Update the slot information data for at least the generation of
+ * the DSO we are allocating data for.
+ */
+ if (__builtin_expect (THREAD_DTV()[0].counter != _dl_tls_generation, 0))
+ (void) _dl_update_slotinfo (map->l_tls_modid);
+#endif
+ _dl_init_static_tls (map);
+ }
+ else
+ map->l_need_tls_init = 1;
+}
+
size_t
internal_function
_dl_next_tls_modid (void)
diff --git a/libpthread/nptl/sysdeps/generic/libc-tls.c b/libpthread/nptl/sysdeps/generic/libc-tls.c
index 3b58ce21f..d302d31c9 100644
--- a/libpthread/nptl/sysdeps/generic/libc-tls.c
+++ b/libpthread/nptl/sysdeps/generic/libc-tls.c
@@ -26,13 +26,14 @@
#include <elf.h>
#include <link.h>
#include <string.h>
+#include <stdlib.h>
#ifdef SHARED
#error makefile bug, this file is for static only
#endif
-#ifdef USE_TLS
+#if USE_TLS
extern ElfW(Phdr) *_dl_phdr;
extern size_t _dl_phnum;
@@ -191,7 +192,7 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign)
const char *lossage = TLS_INIT_TP ((char *) tlsblock + tcb_offset, 0);
# elif TLS_DTV_AT_TP
INSTALL_DTV (tlsblock, static_dtv);
- const char *lossage = TLS_INIT_TP (tlsblock, 0);
+ const char *lossage = (char *)TLS_INIT_TP (tlsblock, 0);
# else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
# endif
diff --git a/libpthread/nptl/sysdeps/generic/sysdep.h b/libpthread/nptl/sysdeps/generic/sysdep.h
index 7c2d76b92..0bbcf9a69 100644
--- a/libpthread/nptl/sysdeps/generic/sysdep.h
+++ b/libpthread/nptl/sysdeps/generic/sysdep.h
@@ -17,6 +17,25 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
+#ifndef C_LABEL
+
+/* Define a macro we can use to construct the asm name for a C symbol. */
+#ifdef NO_UNDERSCORES
+#ifdef __STDC__
+#define C_LABEL(name) name##:
+#else
+#define C_LABEL(name) name/**/:
+#endif
+#else
+#ifdef __STDC__
+#define C_LABEL(name) _##name##:
+#else
+#define C_LABEL(name) _/**/name/**/:
+#endif
+#endif
+
+#endif
+
#ifdef __ASSEMBLER__
/* Mark the end of function named SYM. This is used on some platforms
to generate correct debugging information. */
@@ -41,6 +60,7 @@
# define cfi_register(r1, r2) .cfi_register r1, r2
# define cfi_return_column(reg) .cfi_return_column reg
# define cfi_restore(reg) .cfi_restore reg
+# define cfi_same_value(reg) .cfi_same_value reg
# define cfi_undefined(reg) .cfi_undefined reg
# define cfi_remember_state .cfi_remember_state
# define cfi_restore_state .cfi_restore_state
@@ -57,6 +77,7 @@
# define cfi_register(r1, r2)
# define cfi_return_column(reg)
# define cfi_restore(reg)
+# define cfi_same_value(reg)
# define cfi_undefined(reg)
# define cfi_remember_state
# define cfi_restore_state
diff --git a/libpthread/nptl/sysdeps/pthread/Makefile.in b/libpthread/nptl/sysdeps/pthread/Makefile.in
index a0ed8c00c..db3cebd4d 100644
--- a/libpthread/nptl/sysdeps/pthread/Makefile.in
+++ b/libpthread/nptl/sysdeps/pthread/Makefile.in
@@ -17,15 +17,25 @@ libpthread_CSRC = pthread_barrier_wait.c pthread_cond_broadcast.c \
pthread_rwlock_timedwrlock.c pthread_rwlock_unlock.c \
pthread_rwlock_wrlock.c pthread_sigmask.c \
pthread_spin_destroy.c pthread_spin_init.c \
- pthread_spin_unlock.c pt-sigaction.c pt-sigfillset.c \
- pt-sigprocmask.c unwind-forcedunwind.c pt-longjmp.c
+ pthread_spin_unlock.c pt-sigfillset.c \
+ unwind-forcedunwind.c pt-longjmp.c
ifeq ($(TARGET_ARCH),i386)
libpthread_CSRC += pthread_once.c
endif
+
ifeq ($(TARGET_ARCH),sh)
-libpthread_CSRC += pthread_once.c
+SH_PTHREAD_EXCLUDE_LIST = pthread_spin_unlock.c pthread_spin_init.c \
+ pthread_rwlock_wrlock.c pthread_rwlock_rdlock.c \
+ pthread_rwlock_unlock.c pt-longjmp.c \
+ pthread_barrier_wait.c pthread_cond_broadcast.c \
+ pthread_cond_signal.c \
+ pthread_rwlock_timedrdlock.c \
+ pthread_rwlock_timedwrlock.c
+
+libpthread_CSRC := $(filter-out $(SH_PTHREAD_EXCLUDE_LIST),$(libpthread_CSRC))
endif
+
ifeq ($(TARGET_ARCH),x86_64)
libpthread_CSRC += pthread_once.c
endif
@@ -74,6 +84,10 @@ pthread_OBJ = $(patsubst %.c, $(pthread_OUT)/%.o, $(libpthread_CSRC))
libpthread-a-y += $(pthread_OBJ)
libpthread-so-y += $(pthread_OBJ:.o=.oS)
+libpthread-so-y += $(pthread_OUT)/pt-sigaction.oS $(pthread_OUT)/pt-sigprocmask.oS
+
+CFLAGS-sigaction.c = -I$(top_srcdir)libc/signal
+libc-y += $(pthread_OUT)/sigaction.o
librt-a-y += $(pthread_OUT)/librt-cancellation.o
librt-so-y += $(pthread_OUT)/librt-cancellation.oS \
diff --git a/libpthread/nptl/sysdeps/pthread/bits/libc-lock.h b/libpthread/nptl/sysdeps/pthread/bits/libc-lock.h
index d043a0d2e..fb085f5be 100644
--- a/libpthread/nptl/sysdeps/pthread/bits/libc-lock.h
+++ b/libpthread/nptl/sysdeps/pthread/bits/libc-lock.h
@@ -409,6 +409,9 @@ extern void _pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer
/* Normal cleanup handling, based on C cleanup attribute. */
extern __inline void
+__libc_cleanup_routine (struct __pthread_cleanup_frame *f);
+
+extern __inline void
__libc_cleanup_routine (struct __pthread_cleanup_frame *f)
{
if (f->__do_it)
@@ -528,10 +531,11 @@ weak_extern (__pthread_key_create)
weak_extern (__pthread_setspecific)
weak_extern (__pthread_getspecific)
weak_extern (__pthread_once)
-weak_extern (__pthread_initialize)
weak_extern (__pthread_atfork)
+#ifdef SHARED
weak_extern (_pthread_cleanup_push_defer)
weak_extern (_pthread_cleanup_pop_restore)
+#endif
weak_extern (pthread_setcancelstate)
# else
# pragma weak __pthread_mutex_init
@@ -552,7 +556,6 @@ weak_extern (pthread_setcancelstate)
# pragma weak __pthread_setspecific
# pragma weak __pthread_getspecific
# pragma weak __pthread_once
-# pragma weak __pthread_initialize
# pragma weak __pthread_atfork
# pragma weak _pthread_cleanup_push_defer
# pragma weak _pthread_cleanup_pop_restore
diff --git a/libpthread/nptl/sysdeps/pthread/bits/stdio-lock.h b/libpthread/nptl/sysdeps/pthread/bits/stdio-lock.h
index 0caf40d7b..cd64bc37e 100644
--- a/libpthread/nptl/sysdeps/pthread/bits/stdio-lock.h
+++ b/libpthread/nptl/sysdeps/pthread/bits/stdio-lock.h
@@ -20,6 +20,7 @@
#ifndef _BITS_STDIO_LOCK_H
#define _BITS_STDIO_LOCK_H 1
+#include <bits/libc-lock.h>
#include <lowlevellock.h>
diff --git a/libpthread/nptl/sysdeps/pthread/pthread.h b/libpthread/nptl/sysdeps/pthread/pthread.h
index 9090b30d9..bb322af8f 100644
--- a/libpthread/nptl/sysdeps/pthread/pthread.h
+++ b/libpthread/nptl/sysdeps/pthread/pthread.h
@@ -26,7 +26,7 @@
#define __need_sigset_t
#include <signal.h>
#include <bits/pthreadtypes.h>
-#include <setjmp.h>
+#include <bits/setjmp.h>
#include <bits/wordsize.h>
#if defined _LIBC && ( defined IS_IN_libc || defined NOT_IN_libc )
#include <bits/uClibc_pthread.h>
@@ -536,6 +536,9 @@ class __pthread_cleanup_class
needed or fall back on the copy which must exist somewhere
else. */
extern __inline void
+__pthread_cleanup_routine (struct __pthread_cleanup_frame *__frame);
+
+extern __inline void
__pthread_cleanup_routine (struct __pthread_cleanup_frame *__frame)
{
if (__frame->__do_it)
diff --git a/libpthread/nptl/sysdeps/pthread/sigaction.c b/libpthread/nptl/sysdeps/pthread/sigaction.c
index 17443654d..54b5d2de4 100644
--- a/libpthread/nptl/sysdeps/pthread/sigaction.c
+++ b/libpthread/nptl/sysdeps/pthread/sigaction.c
@@ -31,6 +31,9 @@
# include <sigaction.c>
int
+sigaction (int sig, const struct sigaction *act, struct sigaction *oact);
+
+int
__sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
{
if (__builtin_expect (sig == SIGCANCEL || sig == SIGSETXID, 0))
@@ -41,9 +44,9 @@ __sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
return __libc_sigaction (sig, act, oact);
}
-libc_hidden_weak (__sigaction)
+libc_hidden_proto(sigaction)
weak_alias (__sigaction, sigaction)
-
+libc_hidden_weak(sigaction)
#else
# include_next <sigaction.c>
diff --git a/libpthread/nptl/sysdeps/pthread/unwind-resume.c b/libpthread/nptl/sysdeps/pthread/unwind-resume.c
index 594296723..018d2fd2f 100644
--- a/libpthread/nptl/sysdeps/pthread/unwind-resume.c
+++ b/libpthread/nptl/sysdeps/pthread/unwind-resume.c
@@ -27,13 +27,16 @@ static _Unwind_Reason_Code (*libgcc_s_personality)
(int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
struct _Unwind_Context *);
+extern
+void abort(void);
+
static void
init (void)
{
void *resume = NULL;
void *personality = NULL;
void *handle;
-
+ resume = personality = NULL; /* make gcc silent */
handle = dlopen ("libgcc_s.so.1", (RTLD_LOCAL | RTLD_LAZY));
if (handle == NULL
diff --git a/libpthread/nptl/sysdeps/unix/sysdep.h b/libpthread/nptl/sysdeps/unix/sysdep.h
new file mode 100644
index 000000000..3f5d1721c
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysdep.h
@@ -0,0 +1,61 @@
+/* Copyright (C) 1991, 92, 93, 96, 98, 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 <sysdeps/generic/sysdep.h>
+
+#include <sys/syscall.h>
+#define HAVE_SYSCALLS
+
+/* Note that using a `PASTE' macro loses. */
+#ifdef __STDC__
+#define SYSCALL__(name, args) PSEUDO (__##name, name, args)
+#else
+#define SYSCALL__(name, args) PSEUDO (__/**/name, name, args)
+#endif
+#define SYSCALL(name, args) PSEUDO (name, name, args)
+
+/* Machine-dependent sysdep.h files are expected to define the macro
+ PSEUDO (function_name, syscall_name) to emit assembly code to define the
+ C-callable function FUNCTION_NAME to do system call SYSCALL_NAME.
+ r0 and r1 are the system call outputs. MOVE(x, y) should be defined as
+ an instruction such that "MOVE(r1, r0)" works. ret should be defined
+ as the return instruction. */
+
+#ifndef SYS_ify
+#ifdef __STDC__
+#define SYS_ify(syscall_name) SYS_##syscall_name
+#else
+#define SYS_ify(syscall_name) SYS_/**/syscall_name
+#endif
+#endif
+
+/* Terminate a system call named SYM. This is used on some platforms
+ to generate correct debugging information. */
+#ifndef PSEUDO_END
+#define PSEUDO_END(sym)
+#endif
+#ifndef PSEUDO_END_NOERRNO
+#define PSEUDO_END_NOERRNO(sym) PSEUDO_END(sym)
+#endif
+#ifndef PSEUDO_END_ERRVAL
+#define PSEUDO_END_ERRVAL(sym) PSEUDO_END(sym)
+#endif
+
+/* Wrappers around system calls should normally inline the system call code.
+ But sometimes it is not possible or implemented and we use this code. */
+#define INLINE_SYSCALL(name, nr, args...) __syscall_##name (args)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in b/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in
index 0c73e61c2..9826a3de4 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in
@@ -5,34 +5,28 @@
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
-libpthread_CSRC := pt-raise.c pthread_attr_getaffinity.c \
- pthread_attr_setaffinity.c pthread_getaffinity.c \
- pthread_getcpuclockid.c pthread_kill.c \
- pthread_mutex_cond_lock.c pthread_setaffinity.c \
- pthread_yield.c sem_post.c sem_timedwait.c \
- sem_trywait.c sem_wait.c pt-fork.c \
- sigtimedwait.c sigwaitinfo.c pt-sigwait.c pt-sleep.c \
- pt-msgsnd.c pt-msgrcv.c pt-waitpid.c pt-wait.c \
- pt-open64.c pt-tcdrain.c pt-fcntl.c pt-pread_pwrite.c \
- pt-llseek.c pt-fsync.c
-
-libpthread_SSRC := pt-close.S pt-open.S pt-read.S pt-write.S \
- pt-nanosleep.S pt-pause.S pt-lseek.S pt-accept.S \
- pt-connect.S pt-recv.S pt-recvfrom.S pt-recvmsg.S \
- pt-send.S pt-sendmsg.S pt-sendto.S
-
-libc_CSRC := libc_pthread_init.c libc_multiple_threads.c \
- register-atfork.c unregister-atfork.c getpid.c \
- raise.c sleep.c
-
-libc_SSRC := exit-thread.S close.S open.S read.S write.S nanosleep.S \
- creat.S pause.S msync.S lseek.S accept.S connect.S recv.S \
- recvfrom.S recvmsg.S send.S sendmsg.S sendto.S
+libpthread_CSRC = pthread_attr_getaffinity.c \
+ pthread_attr_setaffinity.c pthread_getaffinity.c \
+ pthread_getcpuclockid.c pthread_kill.c \
+ pthread_mutex_cond_lock.c pthread_setaffinity.c \
+ pthread_yield.c sem_post.c sem_timedwait.c \
+ sem_trywait.c sem_wait.c pt-fork.c \
+ sigtimedwait.c sigwaitinfo.c sigwait.c pt-sleep.c
+
+libpthread_SSRC = #ptw-close.S ptw-open.S ptw-waitid.S ptw-waidpid.S ptw-write.S
+
+libc_CSRC = libc_pthread_init.c libc_multiple_threads.c \
+ register-atfork.c unregister-atfork.c getpid.c \
+ raise.c sleep.c jmp-unwind.c
+
+# These provide both a cancellable and a not cancellable implementation
+libc_SSRC = close.S open.S waitpid.S write.S read.S
librt_CSRC := mq_notify.c timer_create.c timer_delete.c \
timer_getoverr.c timer_gettime.c timer_routines.c \
timer_settime.c
+
ifeq ($(TARGET_ARCH),alpha)
libpthread_CSRC += lowlevellock.c
libc_CSRC += libc-lowlevellock.c
@@ -56,6 +50,12 @@ libc_CSRC += libc-lowlevellock.c
librt_CSRC := mq_notify.c
endif
+ifeq ($(TARGET_ARCH),sh)
+SH_PTHREAD_SPECIFIC := sem_post.c sem_wait.c sem_timedwait.c sem_trywait.c
+libpthread_CSRC := $(filter-out $(SH_PTHREAD_SPECIFIC),$(libpthread_CSRC))
+endif
+
+
ifeq ($(TARGET_ARCH),x86_64)
librt_CSRC := mq_notify.c
endif
@@ -82,24 +82,13 @@ CFLAGS-OMIT-getpid.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
CFLAGS-OMIT-raise.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
CFLAGS-OMIT-sleep.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
CFLAGS-OMIT-libc-lowlevellock.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
-CFLAGS-OMIT-exit-thread.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+
CFLAGS-OMIT-close.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
CFLAGS-OMIT-open.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
CFLAGS-OMIT-read.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
CFLAGS-OMIT-write.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
-CFLAGS-OMIT-nanosleep.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
-CFLAGS-OMIT-creat.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
-CFLAGS-OMIT-pause.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
-CFLAGS-OMIT-accept.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
-CFLAGS-OMIT-connect.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
-CFLAGS-OMIT-recv.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
-CFLAGS-OMIT-recvfrom.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
-CFLAGS-OMIT-recvmsg.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
-CFLAGS-OMIT-send.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
-CFLAGS-OMIT-sendmsg.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
-CFLAGS-OMIT-sendto.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
-CFLAGS-OMIT-lseek.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
-CFLAGS-OMIT-msync.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+CFLAGS-OMIT-waitpid.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+
CFLAGS-OMIT-mq_notify.c = -DIS_IN_libpthread=1
CFLAGS-OMIT-timer_create.c = -DIS_IN_libpthread=1
CFLAGS-OMIT-timer_delete.c = -DIS_IN_libpthread=1
@@ -116,8 +105,15 @@ PTHREAD_LINUX_OBJ += $(patsubst %.S,$(PTHREAD_LINUX_OUT)/%.o,$(libpthread_SSRC))
libpthread-a-y += $(PTHREAD_LINUX_OBJ)
libpthread-so-y += $(PTHREAD_LINUX_OBJ:.o=.oS)
+libpthread-so-y += $(PTHREAD_LINUX_OUT)/pt-raise.oS
libpthread-nomulti-y += $(PTHREAD_LINUX_OBJ)
+ASFLAGS-open.S = -D_LIBC_REENTRANT
+ASFLAGS-close.S = -D_LIBC_REENTRANT
+ASFLAGS-read.S = -D_LIBC_REENTRANT
+ASFLAGS-write.S = -D_LIBC_REENTRANT
+ASFLAGS-waitpid.S = -D_LIBC_REENTRANT
+
LIBC_LINUX_OBJ := $(patsubst %.c,$(PTHREAD_LINUX_OUT)/%.o,$(libc_CSRC))
LIBC_LINUX_OBJ += $(patsubst %.S,$(PTHREAD_LINUX_OUT)/%.o,$(libc_SSRC))
@@ -177,11 +173,16 @@ $(PTHREAD_LINUX_OUT)/lowlevelrwlock.h: $(PTHREAD_LINUX_OUT)/lowlevelrwlock.s
$(PTHREAD_LINUX_OUT)/unwindbuf.h: $(PTHREAD_LINUX_OUT)/unwindbuf.s
@sed -n "s/^.*@@@name@@@\([^@]*\)@@@value@@@[^0-9Xxa-fA-F-]*\([0-9Xxa-fA-F-][0-9Xxa-fA-F-]*\).*@@@end@@@.*$\/#define \1 \2/p" $< > $@
+$(PTHREAD_LINUX_DIR)/pt-sleep.c:
+ $(LN) -s sleep.c $@
+
nptl_linux_headers:
$(MAKE) $(PTHREAD_LINUX_OUT)/lowlevelbarrier.h
$(MAKE) $(PTHREAD_LINUX_OUT)/lowlevelcond.h
$(MAKE) $(PTHREAD_LINUX_OUT)/lowlevelrwlock.h
$(MAKE) $(PTHREAD_LINUX_OUT)/unwindbuf.h
+
+nptl_linux_headers_bootstrap:
$(LN) -sf ../../$(PTHREAD_LINUX_DIR)/bits/local_lim.h $(top_builddir)include/bits
nptl_linux_headers_clean:
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/close.S b/libpthread/nptl/sysdeps/unix/sysv/linux/close.S
index b1cd59469..cf50a1eae 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/close.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/close.S
@@ -1,9 +1,21 @@
#include <sysdep-cancel.h>
+
+/*
+extern int __close_nocancel (int) attribute_hidden;
+*/
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+
PSEUDO (__libc_close, close, 1)
ret
-PSEUDO_END (__libc_close)
+PSEUDO_END(__libc_close)
+
+libc_hidden_def (__close_nocancel)
libc_hidden_def (__libc_close)
weak_alias (__libc_close, __close)
libc_hidden_weak (__close)
weak_alias (__libc_close, close)
libc_hidden_weak (close)
+
+
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/fork.c b/libpthread/nptl/sysdeps/unix/sysv/linux/fork.c
index 5d894225a..f8a64c0cb 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/fork.c
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/fork.c
@@ -227,6 +227,7 @@ pid_t __libc_fork (void)
return pid;
}
+weak_alias(__libc_fork,__fork)
libc_hidden_proto(fork)
weak_alias(__libc_fork,fork)
libc_hidden_weak(fork)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/open.S b/libpthread/nptl/sysdeps/unix/sysv/linux/open.S
index 50e4bcef0..486686a22 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/open.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/open.S
@@ -1,9 +1,21 @@
#include <sysdep-cancel.h>
+
+/*
+extern int __open_nocancel (const char *, int, ...) attribute_hidden;
+*/
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
PSEUDO (__libc_open, open, 3)
ret
-PSEUDO_END (__libc_open)
+PSEUDO_END(__libc_open)
+
+libc_hidden_def (__open_nocancel)
libc_hidden_def (__libc_open)
weak_alias (__libc_open, __open)
libc_hidden_weak (__open)
weak_alias (__libc_open, open)
libc_hidden_weak (open)
+
+
+
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/read.S b/libpthread/nptl/sysdeps/unix/sysv/linux/read.S
index dc63d1763..d3adfa84c 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/read.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/read.S
@@ -1,9 +1,19 @@
#include <sysdep-cancel.h>
+
+/*
+extern int __read_nocancel (int, void *, size_t) attribute_hidden;
+*/
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
PSEUDO (__libc_read, read, 3)
ret
-PSEUDO_END (__libc_read)
+PSEUDO_END(__libc_read)
+
+libc_hidden_def (__read_nocancel)
libc_hidden_def (__libc_read)
weak_alias (__libc_read, __read)
libc_hidden_weak (__read)
weak_alias (__libc_read, read)
libc_hidden_weak (read)
+
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sigwait.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sigwait.c
new file mode 100644
index 000000000..bde0a9292
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sigwait.c
@@ -0,0 +1,2 @@
+#include <pthreadP.h>
+#include "../../../../../../libc/signal/sigwait.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/waitpid.S b/libpthread/nptl/sysdeps/unix/sysv/linux/waitpid.S
new file mode 100644
index 000000000..f55d34629
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/waitpid.S
@@ -0,0 +1,19 @@
+#include <sysdep-cancel.h>
+
+/*
+extern pid_t __waitpid_nocancel (pid_t, int *, int) attribute_hidden;
+*/
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+
+PSEUDO (__waitpid, waitpid, 3)
+ret
+PSEUDO_END(__waitpid)
+
+libc_hidden_def (__waitpid)
+weak_alias (__waitpid, waitpid)
+libc_hidden_weak (waitpid)
+weak_alias (__waitpid, __libc_waitpid)
+libc_hidden_weak (__libc_waitpid)
+
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/write.S b/libpthread/nptl/sysdeps/unix/sysv/linux/write.S
index 168eab95c..43de3320d 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/write.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/write.S
@@ -1,9 +1,19 @@
#include <sysdep-cancel.h>
+
+/*
+extern int __write_nocancel (int, const void *, size_t) attribute_hidden;
+*/
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
PSEUDO (__libc_write, write, 3)
ret
-PSEUDO_END (__libc_write)
+PSEUDO_END(__libc_write)
+
+libc_hidden_def (__write_nocancel)
libc_hidden_def (__libc_write)
weak_alias (__libc_write, __write)
libc_hidden_weak (__write)
weak_alias (__libc_write, write)
libc_hidden_weak (write)
+
+#endif
diff --git a/libpthread/nptl_db/structs.def b/libpthread/nptl_db/structs.def
index b17a628e0..823af5cba 100644
--- a/libpthread/nptl_db/structs.def
+++ b/libpthread/nptl_db/structs.def
@@ -1,5 +1,5 @@
/* List of types and symbols in libpthread examined by libthread_db.
- Copyright (C) 2003 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2006 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
@@ -74,6 +74,8 @@ DB_STRUCT_FIELD (link_map, l_tls_modid)
#if !defined IS_IN_libpthread || USE_TLS
DB_STRUCT_ARRAY_FIELD (dtv, dtv)
+# define pointer_val pointer.val /* Field of anonymous struct in dtv_t. */
+DB_STRUCT_FIELD (dtv_t, pointer_val)
#endif
#if !defined IS_IN_libpthread || TLS_TCB_AT_TP
DB_STRUCT_FIELD (pthread, dtvp)
diff --git a/libpthread/nptl_db/td_thr_tlsbase.c b/libpthread/nptl_db/td_thr_tlsbase.c
index c57009a73..aaeda6f3c 100644
--- a/libpthread/nptl_db/td_thr_tlsbase.c
+++ b/libpthread/nptl_db/td_thr_tlsbase.c
@@ -1,5 +1,5 @@
/* Locate TLS data for a thread.
- Copyright (C) 2003 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2006 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
@@ -25,7 +25,7 @@ td_thr_tlsbase (const td_thrhandle_t *th,
psaddr_t *base)
{
td_err_e err;
- psaddr_t dtv, dtvptr;
+ psaddr_t dtv, dtvslot, dtvptr;
if (modid < 1)
return TD_NOTLS;
@@ -35,8 +35,13 @@ td_thr_tlsbase (const td_thrhandle_t *th,
if (err != TD_OK)
return err;
- /* Get the corresponding entry in the DTV. */
- err = DB_GET_FIELD (dtvptr, th->th_ta_p, dtv, dtv, dtv, modid);
+ /* Find the corresponding entry in the DTV. */
+ err = DB_GET_FIELD_ADDRESS (dtvslot, th->th_ta_p, dtv, dtv, dtv, modid);
+ if (err != TD_OK)
+ return err;
+
+ /* Extract the TLS block address from that DTV slot. */
+ err = DB_GET_FIELD (dtvptr, th->th_ta_p, dtvslot, dtv_t, pointer_val, 0);
if (err != TD_OK)
return err;