summaryrefslogtreecommitdiff
path: root/libpthread/nptl/sysdeps/alpha
diff options
context:
space:
mode:
authorAustin Foxley <austinf@cetoncorp.com>2009-10-17 12:26:24 -0700
committerAustin Foxley <austinf@cetoncorp.com>2009-10-17 12:26:24 -0700
commitc68d0fa2d88fc2134a38d99e7e944828384a7671 (patch)
tree6596943bd1c77f18d6e49d4153ddd3f3d67b49f5 /libpthread/nptl/sysdeps/alpha
parent9a03e98a3b418f33c347a6023e9320f3a42cb9e4 (diff)
libpthread/nptl: core of the "Native Posix Threading Library" for uClibc
targetting arm,sh,i386,mips,sparc for now Signed-off-by: Austin Foxley <austinf@cetoncorp.com>
Diffstat (limited to 'libpthread/nptl/sysdeps/alpha')
-rw-r--r--libpthread/nptl/sysdeps/alpha/Makefile21
-rw-r--r--libpthread/nptl/sysdeps/alpha/dl-tls.h29
-rw-r--r--libpthread/nptl/sysdeps/alpha/elf/pt-initfini.c89
-rw-r--r--libpthread/nptl/sysdeps/alpha/jmpbuf-unwind.h31
-rw-r--r--libpthread/nptl/sysdeps/alpha/libc-tls.c37
-rw-r--r--libpthread/nptl/sysdeps/alpha/pthread_spin_lock.S45
-rw-r--r--libpthread/nptl/sysdeps/alpha/pthread_spin_trylock.S46
-rw-r--r--libpthread/nptl/sysdeps/alpha/pthreaddef.h38
-rw-r--r--libpthread/nptl/sysdeps/alpha/tcb-offsets.sym14
-rw-r--r--libpthread/nptl/sysdeps/alpha/tls.h127
10 files changed, 477 insertions, 0 deletions
diff --git a/libpthread/nptl/sysdeps/alpha/Makefile b/libpthread/nptl/sysdeps/alpha/Makefile
new file mode 100644
index 000000000..88c106bbb
--- /dev/null
+++ b/libpthread/nptl/sysdeps/alpha/Makefile
@@ -0,0 +1,21 @@
+# Copyright (C) 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.
+
+ifeq ($(subdir),csu)
+gen-as-const-headers += tcb-offsets.sym
+endif
diff --git a/libpthread/nptl/sysdeps/alpha/dl-tls.h b/libpthread/nptl/sysdeps/alpha/dl-tls.h
new file mode 100644
index 000000000..f81f95d75
--- /dev/null
+++ b/libpthread/nptl/sysdeps/alpha/dl-tls.h
@@ -0,0 +1,29 @@
+/* Thread-local storage handling in the ELF dynamic linker. Alpha version.
+ Copyright (C) 2002 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/alpha/elf/pt-initfini.c b/libpthread/nptl/sysdeps/alpha/elf/pt-initfini.c
new file mode 100644
index 000000000..ba2e419d6
--- /dev/null
+++ b/libpthread/nptl/sysdeps/alpha/elf/pt-initfini.c
@@ -0,0 +1,89 @@
+/* Special .init and .fini section support for Alpha. NPTL version.
+ Copyright (C) 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. */
+
+/* This file is compiled into assembly code which is then munged by a sed
+ script into two files: crti.s and crtn.s.
+
+ * crti.s puts a function prologue at the beginning of the .init and .fini
+ sections and defines global symbols for those addresses, so they can be
+ called as functions.
+
+ * crtn.s puts the corresponding function epilogues in the .init and .fini
+ sections.
+
+ This differs from what would be generated by the generic code in that
+ we save and restore the GP within the function. In order for linker
+ relaxation to work, the value in the GP register on exit from a function
+ must be valid for the function entry point. Normally, a function is
+ contained within one object file and this is not an issue, provided
+ that the function reloads the gp after making any function calls.
+ However, _init and _fini are constructed from pieces of many object
+ files, all of which may have different GP values. So we must reload
+ the GP value from crti.o in crtn.o. */
+
+__asm__ (" \n\
+#include \"defs.h\" \n\
+ \n\
+/*@HEADER_ENDS*/ \n\
+ \n\
+/*@_init_PROLOG_BEGINS*/ \n\
+ .section .init, \"ax\", @progbits \n\
+ .globl _init \n\
+ .type _init,@function \n\
+ .usepv _init,std \n\
+_init: \n\
+ ldgp $29, 0($27) \n\
+ subq $30, 16, $30 \n\
+ stq $26, 0($30) \n\
+ stq $29, 8($30) \n\
+ bsr $26, __pthread_initialize_minimal_internal !samegp \n\
+ .align 3 \n\
+/*@_init_PROLOG_ENDS*/ \n\
+ \n\
+/*@_init_EPILOG_BEGINS*/ \n\
+ .section .init, \"ax\", @progbits \n\
+ ldq $26, 0($30) \n\
+ ldq $29, 8($30) \n\
+ addq $30, 16, $30 \n\
+ ret \n\
+/*@_init_EPILOG_ENDS*/ \n\
+ \n\
+/*@_fini_PROLOG_BEGINS*/ \n\
+ .section .fini, \"ax\", @progbits \n\
+ .globl _fini \n\
+ .type _fini,@function \n\
+ .usepv _fini,std \n\
+_fini: \n\
+ ldgp $29, 0($27) \n\
+ subq $30, 16, $30 \n\
+ stq $26, 0($30) \n\
+ stq $29, 8($30) \n\
+ .align 3 \n\
+/*@_fini_PROLOG_ENDS*/ \n\
+ \n\
+/*@_fini_EPILOG_BEGINS*/ \n\
+ .section .fini, \"ax\", @progbits \n\
+ ldq $26, 0($30) \n\
+ ldq $29, 8($30) \n\
+ addq $30, 16, $30 \n\
+ ret \n\
+/*@_fini_EPILOG_ENDS*/ \n\
+ \n\
+/*@TRAILER_BEGINS*/ \n\
+");
diff --git a/libpthread/nptl/sysdeps/alpha/jmpbuf-unwind.h b/libpthread/nptl/sysdeps/alpha/jmpbuf-unwind.h
new file mode 100644
index 000000000..5cef8b1cf
--- /dev/null
+++ b/libpthread/nptl/sysdeps/alpha/jmpbuf-unwind.h
@@ -0,0 +1,31 @@
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+ 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>
+
+#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)[JB_SP] - (_adj))
+
+/* We use the normal lobngjmp for unwinding. */
+#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
diff --git a/libpthread/nptl/sysdeps/alpha/libc-tls.c b/libpthread/nptl/sysdeps/alpha/libc-tls.c
new file mode 100644
index 000000000..a3b68e928
--- /dev/null
+++ b/libpthread/nptl/sysdeps/alpha/libc-tls.c
@@ -0,0 +1,37 @@
+/* Thread-local storage handling in the ELF dynamic linker. Alpha version.
+ Copyright (C) 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/libc-tls.c>
+#include <dl-tls.h>
+
+#if USE_TLS
+
+/* On Alpha, linker optimizations are not required, so __tls_get_addr
+ can be called even in statically linked binaries. In this case module
+ must be always 1 and PT_TLS segment exist in the binary, otherwise it
+ would not link. */
+
+void *
+__tls_get_addr (tls_index *ti)
+{
+ dtv_t *dtv = THREAD_DTV ();
+ return (char *) dtv[1].pointer.val + ti->ti_offset;
+}
+
+#endif
diff --git a/libpthread/nptl/sysdeps/alpha/pthread_spin_lock.S b/libpthread/nptl/sysdeps/alpha/pthread_spin_lock.S
new file mode 100644
index 000000000..ce6cd41a4
--- /dev/null
+++ b/libpthread/nptl/sysdeps/alpha/pthread_spin_lock.S
@@ -0,0 +1,45 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <rth@twiddle.net>, 2003.
+
+ 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. */
+
+
+ .text
+ .align 4
+
+ .globl pthread_spin_lock
+ .ent pthread_spin_lock
+pthread_spin_lock:
+ .frame $sp, 0, $26, 0
+ .prologue 0
+
+0: ldl_l $1, 0($16)
+ lda $2, 1
+ lda $0, 0
+ bne $1, 1f
+
+ stl_c $2, 0($16)
+ beq $2, 1f
+ mb
+ ret
+
+1: ldl $1, 0($16)
+ bne $1, 1b
+ unop
+ br 0b
+
+ .end pthread_spin_lock
diff --git a/libpthread/nptl/sysdeps/alpha/pthread_spin_trylock.S b/libpthread/nptl/sysdeps/alpha/pthread_spin_trylock.S
new file mode 100644
index 000000000..0948da698
--- /dev/null
+++ b/libpthread/nptl/sysdeps/alpha/pthread_spin_trylock.S
@@ -0,0 +1,46 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <rth@twiddle.net>, 2003.
+
+ 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>
+
+ .text
+ .align 4
+
+ .globl pthread_spin_trylock
+ .ent pthread_spin_trylock
+pthread_spin_trylock:
+ .frame $sp, 0, $26, 0
+ .prologue 0
+
+0: ldl_l $1, 0($16)
+ lda $2, 1
+ lda $0, EBUSY
+ bne $1, 1f
+
+ stl_c $2, 0($16)
+ beq $2, 2f
+ mb
+ lda $0, 0
+
+1: ret
+2: br 0b
+
+ .end pthread_spin_trylock
diff --git a/libpthread/nptl/sysdeps/alpha/pthreaddef.h b/libpthread/nptl/sysdeps/alpha/pthreaddef.h
new file mode 100644
index 000000000..26c4daf7b
--- /dev/null
+++ b/libpthread/nptl/sysdeps/alpha/pthreaddef.h
@@ -0,0 +1,38 @@
+/* Copyright (C) 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. */
+
+/* Default stack size. */
+#define ARCH_STACK_DEFAULT_SIZE (4 * 1024 * 1024)
+
+/* Required stack pointer alignment at beginning. The ABI requires 16. */
+#define STACK_ALIGN 16
+
+/* Minimal stack size after allocating thread descriptor and guard size. */
+#define MINIMAL_REST_STACK 4096
+
+/* 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. */
+
+/* While there is no such syscall. */
+#define __exit_thread_inline(val) \
+ INLINE_SYSCALL (exit, 1, (val))
diff --git a/libpthread/nptl/sysdeps/alpha/tcb-offsets.sym b/libpthread/nptl/sysdeps/alpha/tcb-offsets.sym
new file mode 100644
index 000000000..c21a79104
--- /dev/null
+++ b/libpthread/nptl/sysdeps/alpha/tcb-offsets.sym
@@ -0,0 +1,14 @@
+#include <sysdep.h>
+#include <tls.h>
+
+--
+
+-- Abuse tls.h macros to derive offsets relative to the thread register.
+-- # define __builtin_thread_pointer() ((void *) 0)
+-- # define thread_offsetof(mem) ((void *) &THREAD_SELF->mem - (void *) 0)
+-- Ho hum, this doesn't work in gcc4, so Know Things about THREAD_SELF
+#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/alpha/tls.h b/libpthread/nptl/sysdeps/alpha/tls.h
new file mode 100644
index 000000000..99cd27a03
--- /dev/null
+++ b/libpthread/nptl/sysdeps/alpha/tls.h
@@ -0,0 +1,127 @@
+/* Definition for thread-local data handling. NPTL/Alpha version.
+ Copyright (C) 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. */
+
+#ifndef _TLS_H
+#define _TLS_H 1
+
+#ifndef __ASSEMBLER__
+# 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. */
+#ifndef HAVE_TLS_SUPPORT
+# error "TLS support is required."
+#endif
+
+/* Signal that TLS support is available. */
+# define USE_TLS 1
+
+#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 <nptl/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) \
+ (__builtin_set_thread_pointer ((void *)(tcbp)), 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 \
+ REGISTER (64, 64, 32 * 8, -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)
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* tls.h */