diff options
Diffstat (limited to 'libpthread/nptl/sysdeps/arm')
-rw-r--r-- | libpthread/nptl/sysdeps/arm/Makefile.arch | 69 | ||||
-rw-r--r-- | libpthread/nptl/sysdeps/arm/aeabi_read_tp.S | 1 | ||||
-rw-r--r-- | libpthread/nptl/sysdeps/arm/aeabi_unwind_cpp_pr1.c | 1 | ||||
-rw-r--r-- | libpthread/nptl/sysdeps/arm/dl-tls.h | 30 | ||||
-rw-r--r-- | libpthread/nptl/sysdeps/arm/jmpbuf-unwind.h | 37 | ||||
-rw-r--r-- | libpthread/nptl/sysdeps/arm/pthread_spin_lock.S | 32 | ||||
-rw-r--r-- | libpthread/nptl/sysdeps/arm/pthread_spin_trylock.S | 35 | ||||
-rw-r--r-- | libpthread/nptl/sysdeps/arm/pthreaddef.h | 40 | ||||
-rw-r--r-- | libpthread/nptl/sysdeps/arm/sysdep.h | 92 | ||||
-rw-r--r-- | libpthread/nptl/sysdeps/arm/tcb-offsets.sym | 12 | ||||
-rw-r--r-- | libpthread/nptl/sysdeps/arm/thumb_atomics.S | 1 | ||||
-rw-r--r-- | libpthread/nptl/sysdeps/arm/tls.h | 141 |
12 files changed, 491 insertions, 0 deletions
diff --git a/libpthread/nptl/sysdeps/arm/Makefile.arch b/libpthread/nptl/sysdeps/arm/Makefile.arch new file mode 100644 index 000000000..6d16ae3fd --- /dev/null +++ b/libpthread/nptl/sysdeps/arm/Makefile.arch @@ -0,0 +1,69 @@ +# Makefile for uClibc NPTL +# +# Copyright (C) 2005 Steven J. Hill <sjhill@uclibc.org> +# Portions Copyright (C) 2006 CodeSourcery +# +# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. +# + +libpthread_SSRC = pthread_spin_lock.S pthread_spin_trylock.S aeabi_read_tp.S \ + thumb_atomics.S +libpthread_CSRC = aeabi_unwind_cpp_pr1.c + +librt_SSRC = aeabi_read_tp.S thumb_atomics.S +librt_CSRC = aeabi_unwind_cpp_pr1.c + +libc_a_CSRC = + +CFLAGS-pt-raise.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 + +ASFLAGS-pthread_spin_lock.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 +ASFLAGS-pthread_spin_trylock.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 +ASFLAGS-aeabi_read_tp.S = -DNOT_IN_libc=1 + +CFLAGS-arm = $(SSP_ALL_CFLAGS) + +PTHREAD_ARCH_DIR := $(top_srcdir)libpthread/nptl/sysdeps/arm +PTHREAD_ARCH_OUT := $(top_builddir)libpthread/nptl/sysdeps/arm +PTHREAD_ARCH_OBJ := $(patsubst %.S,$(PTHREAD_ARCH_OUT)/%.o,$(libpthread_SSRC)) +PTHREAD_ARCH_OBJ += $(patsubst %.c,$(PTHREAD_ARCH_OUT)/%.o,$(libpthread_CSRC)) +LIBRT_ARCH_OBJ := $(patsubst %.S,$(PTHREAD_ARCH_OUT)/%.o,$(librt_SSRC)) +LIBRT_ARCH_OBJ += $(patsubst %.c,$(PTHREAD_ARCH_OUT)/%.o,$(librt_CSRC)) + + +ifeq ($(DOPIC),y) +libpthread-a-y += $(PTHREAD_ARCH_OBJ:.o=.os) +else +libpthread-a-y += $(PTHREAD_ARCH_OBJ) +endif +libpthread-so-y += $(PTHREAD_ARCH_OBJ:.o=.oS) + +librt-a-y += $(LIBRT_ARCH_OBJ) +librt-so-y += $(LIBRT_ARCH_OBJ:.o=.oS) + +libpthread-nomulti-y += $(PTHREAD_ARCH_OBJ) + +objclean-y += nptl_arch_objclean +headers_clean-y += nptl_arch_headers_clean + +# +# Create 'tcb-offsets.h' header file. +# +CFLAGS-tcb-offsets.c = -S + +$(PTHREAD_ARCH_OUT)/tcb-offsets.c: $(PTHREAD_ARCH_DIR)/tcb-offsets.sym + $(do_awk) $(top_srcdir)extra/scripts/gen-as-const.awk $< > $@ + +$(PTHREAD_ARCH_OUT)/tcb-offsets.s: $(PTHREAD_ARCH_OUT)/tcb-offsets.c + $(compile.c) + +nptl_arch_headers: $(PTHREAD_ARCH_OUT)/tcb-offsets.s + $(do_sed) -n "s/^.*@@@name@@@\([^@]*\)@@@value@@@[^0-9Xxa-fA-F-]*\([0-9Xxa-fA-F-][0-9Xxa-fA-F-]*\).*@@@end@@@.*$\/#define \1 \2/p" $< > $(PTHREAD_ARCH_OUT)/tcb-offsets.h + +nptl_arch_headers_clean: + $(RM) $(PTHREAD_ARCH_OUT)/tcb-offsets.c \ + $(PTHREAD_ARCH_OUT)/tcb-offsets.s \ + $(PTHREAD_ARCH_OUT)/tcb-offsets.h + +nptl_arch_objclean: + $(RM) $(PTHREAD_ARCH_OUT)/*.{o,os,oS} diff --git a/libpthread/nptl/sysdeps/arm/aeabi_read_tp.S b/libpthread/nptl/sysdeps/arm/aeabi_read_tp.S new file mode 100644 index 000000000..af640d625 --- /dev/null +++ b/libpthread/nptl/sysdeps/arm/aeabi_read_tp.S @@ -0,0 +1 @@ +#include <../../../../ldso/ldso/arm/aeabi_read_tp.S> diff --git a/libpthread/nptl/sysdeps/arm/aeabi_unwind_cpp_pr1.c b/libpthread/nptl/sysdeps/arm/aeabi_unwind_cpp_pr1.c new file mode 100644 index 000000000..84683627b --- /dev/null +++ b/libpthread/nptl/sysdeps/arm/aeabi_unwind_cpp_pr1.c @@ -0,0 +1 @@ +#include <../../../../libc/sysdeps/linux/arm/aeabi_unwind_cpp_pr1.c> diff --git a/libpthread/nptl/sysdeps/arm/dl-tls.h b/libpthread/nptl/sysdeps/arm/dl-tls.h new file mode 100644 index 000000000..f74f3f8da --- /dev/null +++ b/libpthread/nptl/sysdeps/arm/dl-tls.h @@ -0,0 +1,30 @@ +/* Thread-local storage handling in the ELF dynamic linker. ARM version. + Copyright (C) 2005 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. */ + + +/* Type used for the representation of TLS information in the GOT. */ +typedef struct +{ + unsigned long int ti_module; + unsigned long int ti_offset; +} tls_index; + + +extern void *__tls_get_addr (tls_index *ti); + diff --git a/libpthread/nptl/sysdeps/arm/jmpbuf-unwind.h b/libpthread/nptl/sysdeps/arm/jmpbuf-unwind.h new file mode 100644 index 000000000..97a7760a9 --- /dev/null +++ b/libpthread/nptl/sysdeps/arm/jmpbuf-unwind.h @@ -0,0 +1,37 @@ +/* Copyright (C) 2005,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 + 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 <setjmp.h> +#include <stdint.h> +#include <unwind.h> + +/* Test if longjmp to JMPBUF would unwind the frame + containing a local variable at ADDRESS. */ +#undef _JMPBUF_UNWINDS +#define _JMPBUF_UNWINDS(jmpbuf, address, demangle) \ + ((void *) (address) < (void *) demangle (jmpbuf[__JMP_BUF_SP])) + +#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \ + _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj) + +#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \ + ((uintptr_t) (_address) - (_adj) < (uintptr_t) (_jmpbuf)[__JMP_BUF_SP] - (_adj)) + +/* We use the normal longjmp for unwinding. */ +#define __libc_unwind_longjmp(buf, val) longjmp (buf, val) + diff --git a/libpthread/nptl/sysdeps/arm/pthread_spin_lock.S b/libpthread/nptl/sysdeps/arm/pthread_spin_lock.S new file mode 100644 index 000000000..614711446 --- /dev/null +++ b/libpthread/nptl/sysdeps/arm/pthread_spin_lock.S @@ -0,0 +1,32 @@ +/* Copyright (C) 2005 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 <sysdep.h> + + .text + .align 4 + +ENTRY (pthread_spin_lock) + mov r1, #1 +1: swp r2, r1, [r0] + teq r2, #0 + bne 1b + mov r0, #0 + PSEUDO_RET_NOERRNO +END (pthread_spin_lock) + diff --git a/libpthread/nptl/sysdeps/arm/pthread_spin_trylock.S b/libpthread/nptl/sysdeps/arm/pthread_spin_trylock.S new file mode 100644 index 000000000..0c633f94c --- /dev/null +++ b/libpthread/nptl/sysdeps/arm/pthread_spin_trylock.S @@ -0,0 +1,35 @@ +/* Copyright (C) 2005 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. */ + +#define _ERRNO_H 1 +#include <bits/errno.h> + +#include <sysdep.h> + + .text + .align 4 + +ENTRY (pthread_spin_trylock) + mov r1, #1 + swp r2, r1, [r0] + teq r2, #0 + moveq r0, #0 + movne r0, #EBUSY + PSEUDO_RET_NOERRNO +END (pthread_spin_trylock) + diff --git a/libpthread/nptl/sysdeps/arm/pthreaddef.h b/libpthread/nptl/sysdeps/arm/pthreaddef.h new file mode 100644 index 000000000..72206d18d --- /dev/null +++ b/libpthread/nptl/sysdeps/arm/pthreaddef.h @@ -0,0 +1,40 @@ +/* Copyright (C) 2002, 2003, 2005 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. */ + +/* Default stack size. */ +#define ARCH_STACK_DEFAULT_SIZE (2 * 1024 * 1024) + +/* Required stack pointer alignment at beginning. SSE requires 16 + bytes. */ +#define STACK_ALIGN 16 + +/* Minimal stack size after allocating thread descriptor and guard size. */ +#define MINIMAL_REST_STACK 2048 + +/* Alignment requirement for TCB. */ +#define TCB_ALIGNMENT 16 + + +/* Location of current stack frame. */ +#define CURRENT_STACK_FRAME __builtin_frame_address (0) + + +/* XXX Until we have a better place keep the definitions here. */ +#define __exit_thread_inline(val) \ + INLINE_SYSCALL (exit, 1, (val)) + diff --git a/libpthread/nptl/sysdeps/arm/sysdep.h b/libpthread/nptl/sysdeps/arm/sysdep.h new file mode 100644 index 000000000..5c6fc0804 --- /dev/null +++ b/libpthread/nptl/sysdeps/arm/sysdep.h @@ -0,0 +1,92 @@ +/* Assembler macros for ARM. + Copyright (C) 1997, 1998, 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> + +#ifdef __ASSEMBLER__ + +/* Syntactic details of assembler. */ + +#define ALIGNARG(log2) log2 +/* For ELF we need the `.type' directive to make shared libs work right. */ +#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,%##typearg; +#define ASM_SIZE_DIRECTIVE(name) .size name,.-name + +/* In ELF C symbols are asm symbols. */ +#undef NO_UNDERSCORES +#define NO_UNDERSCORES + +#define PLTJMP(_x) _x##(PLT) + +/* APCS-32 doesn't preserve the condition codes across function call. */ +#ifdef __APCS_32__ +#define LOADREGS(cond, base, reglist...)\ + ldm##cond base,reglist +#ifdef __USE_BX__ +#define RETINSTR(cond, reg) \ + bx##cond reg +#define DO_RET(_reg) \ + bx _reg +#else +#define RETINSTR(cond, reg) \ + mov##cond pc, reg +#define DO_RET(_reg) \ + mov pc, _reg +#endif +#else /* APCS-26 */ +#define LOADREGS(cond, base, reglist...)\ + ldm##cond base,reglist^ +#define RETINSTR(cond, reg) \ + mov##cond##s pc, reg +#define DO_RET(_reg) \ + movs pc, _reg +#endif + +/* Define an entry point visible from C. */ +#define ENTRY(name) \ + ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ + ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),function) \ + .align ALIGNARG(4); \ + name##: \ + CALL_MCOUNT + +#undef END +#define END(name) \ + ASM_SIZE_DIRECTIVE(name) + +/* If compiled for profiling, call `mcount' at the start of each function. */ +#ifdef PROF +#define CALL_MCOUNT \ + str lr,[sp, #-4]! ; \ + bl PLTJMP(mcount) ; \ + ldr lr, [sp], #4 ; +#else +#define CALL_MCOUNT /* Do nothing. */ +#endif + +#ifdef NO_UNDERSCORES +/* Since C identifiers are not normally prefixed with an underscore + on this system, the asm identifier `syscall_error' intrudes on the + C name space. Make sure we use an innocuous name. */ +#define syscall_error __syscall_error +#define mcount _mcount +#endif + +#endif /* __ASSEMBLER__ */ + diff --git a/libpthread/nptl/sysdeps/arm/tcb-offsets.sym b/libpthread/nptl/sysdeps/arm/tcb-offsets.sym new file mode 100644 index 000000000..008ce3aa5 --- /dev/null +++ b/libpthread/nptl/sysdeps/arm/tcb-offsets.sym @@ -0,0 +1,12 @@ +#include <sysdep.h> +#include <tls.h> + +-- + +-- Derive offsets relative to the thread register. +#define thread_offsetof(mem) (long)(offsetof(struct pthread, mem) - sizeof(struct pthread)) + +MULTIPLE_THREADS_OFFSET thread_offsetof (header.multiple_threads) +PID_OFFSET thread_offsetof (pid) +TID_OFFSET thread_offsetof (tid) + diff --git a/libpthread/nptl/sysdeps/arm/thumb_atomics.S b/libpthread/nptl/sysdeps/arm/thumb_atomics.S new file mode 100644 index 000000000..aaa7a3d8f --- /dev/null +++ b/libpthread/nptl/sysdeps/arm/thumb_atomics.S @@ -0,0 +1 @@ +#include <../../../../ldso/ldso/arm/thumb_atomics.S> diff --git a/libpthread/nptl/sysdeps/arm/tls.h b/libpthread/nptl/sysdeps/arm/tls.h new file mode 100644 index 000000000..fa98124ee --- /dev/null +++ b/libpthread/nptl/sysdeps/arm/tls.h @@ -0,0 +1,141 @@ +/* Definition for thread-local data handling. NPTL/ARM version. + Copyright (C) 2005 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. */ + +#ifndef _TLS_H +#define _TLS_H 1 + +#ifndef __ASSEMBLER__ +#include <dl-sysdep.h> + +# include <stdbool.h> +# include <stddef.h> +# include <stdint.h> + +/* Type for the dtv. */ +typedef union dtv +{ + size_t counter; + struct + { + void *val; + bool is_static; + } pointer; +} dtv_t; + +#else /* __ASSEMBLER__ */ +# include <tcb-offsets.h> +#endif /* __ASSEMBLER__ */ + + +/* We require TLS support in the tools. */ +#define HAVE_TLS_SUPPORT 1 +#define HAVE_TLS_MODEL_ATTRIBUTE 1 +#define HAVE___THREAD 1 + +/* Signal that TLS support is available. */ +#define USE_TLS 1 + +/* Like all other modern NPTL ports, ARM uses forced unwinding. */ +#define HAVE_FORCED_UNWIND + +#ifndef __ASSEMBLER__ + +/* Get system call information. */ +# include <sysdep.h> + +/* The TP points to the start of the thread blocks. */ +# define TLS_DTV_AT_TP 1 + +/* Get the thread descriptor definition. */ +# include <../../descr.h> + +typedef struct +{ + dtv_t *dtv; + void *private; +} tcbhead_t; + +/* This is the size of the initial TCB. */ +# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) + +/* Alignment requirements for the initial TCB. */ +# define TLS_INIT_TCB_ALIGN 16 + +/* This is the size of the TCB. */ +# define TLS_TCB_SIZE sizeof (tcbhead_t) + +/* This is the size we need before TCB. */ +# define TLS_PRE_TCB_SIZE sizeof (struct pthread) + +/* Alignment requirements for the TCB. */ +# define TLS_TCB_ALIGN 16 + +/* Install the dtv pointer. The pointer passed is to the element with + index -1 which contain the length. */ +# define INSTALL_DTV(tcbp, dtvp) \ + (((tcbhead_t *) (tcbp))->dtv = (dtvp) + 1) + +/* Install new dtv for current thread. */ +# define INSTALL_NEW_DTV(dtv) \ + (THREAD_DTV() = (dtv)) + +/* Return dtv of given thread descriptor. */ +# define GET_DTV(tcbp) \ + (((tcbhead_t *) (tcbp))->dtv) + +/* Code to initially initialize the thread pointer. This might need + special attention since 'errno' is not yet available and if the + operation can cause a failure 'errno' must not be touched. */ +# define TLS_INIT_TP(tcbp, secondcall) \ + ({ INTERNAL_SYSCALL_DECL (err); \ + long result_var; \ + result_var = INTERNAL_SYSCALL_ARM (set_tls, err, 1, (tcbp)); \ + INTERNAL_SYSCALL_ERROR_P (result_var, err) \ + ? "unknown error" : NULL; }) + +/* Return the address of the dtv for the current thread. */ +# define THREAD_DTV() \ + (((tcbhead_t *) __builtin_thread_pointer ())->dtv) + +/* Return the thread descriptor for the current thread. */ +# define THREAD_SELF \ + ((struct pthread *)__builtin_thread_pointer () - 1) + +/* Magic for libthread_db to know how to do THREAD_SELF. */ +# define DB_THREAD_SELF \ + CONST_THREAD_AREA (32, sizeof (struct pthread)) + +/* Access to data in the thread descriptor is easy. */ +#define THREAD_GETMEM(descr, member) \ + descr->member +#define THREAD_GETMEM_NC(descr, member, idx) \ + descr->member[idx] +#define THREAD_SETMEM(descr, member, value) \ + descr->member = (value) +#define THREAD_SETMEM_NC(descr, member, idx, value) \ + descr->member[idx] = (value) + +/* Initializing the thread pointer will generate a SIGILL if the syscall + is not available. */ +#define TLS_INIT_TP_EXPENSIVE 1 + +#endif /* __ASSEMBLER__ */ + +#endif /* tls.h */ + |