From patchwork Thu Nov 3 22:27:49 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: wbx X-Patchwork-Id: 691060 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from helium.openadk.org (helium.openadk.org [IPv6:2a00:1828:2000:679::23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3t903Z08ZLz9snk for ; Fri, 4 Nov 2016 09:28:08 +1100 (AEDT) Received: from helium.openadk.org (localhost [IPv6:::1]) by helium.openadk.org (Postfix) with ESMTP id 17D7D10151; Thu, 3 Nov 2016 23:28:03 +0100 (CET) X-Original-To: devel@uclibc-ng.org Delivered-To: devel@helium.openadk.org Received: by helium.openadk.org (Postfix, from userid 1000) id CEE0410151; Thu, 3 Nov 2016 23:27:49 +0100 (CET) MIME-Version: 1.0 To: devel@uclibc-ng.org X-Git-Refname: refs/heads/master X-Git-Reftype: branch X-Git-Oldrev: 99ef2719fb3d703fe38c4113cd7f5adec516dd3a X-Git-Newrev: 191739597c6d380692885cfdd8dd8aa4f31f029d Auto-Submitted: auto-generated Message-Id: <20161103222749.CEE0410151@helium.openadk.org> Date: Thu, 3 Nov 2016 23:27:49 +0100 (CET) From: wbx@helium.openadk.org (wbx) Subject: [uclibc-ng-devel] uClibc-ng - small C library for embedded systems branch master updated. v1.0.19-5-g1917395 X-BeenThere: devel@uclibc-ng.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: uClibc-ng Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: devel-bounces@uclibc-ng.org Sender: "devel" This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "uClibc-ng - small C library for embedded systems". The branch, master has been updated via 191739597c6d380692885cfdd8dd8aa4f31f029d (commit) via 7825930078208462655e107677656c45014e91b4 (commit) via a7f8986f6e81b912b35b46dcad4b8258f75c8b29 (commit) from 99ef2719fb3d703fe38c4113cd7f5adec516dd3a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 191739597c6d380692885cfdd8dd8aa4f31f029d Author: Waldemar Brodkorb Date: Mon Oct 31 18:05:44 2016 +0100 microblaze: add NPTL/TLS support from GNU libc Not perfect, but a starting point. Some tests of the test suite are failing. commit 7825930078208462655e107677656c45014e91b4 Author: Waldemar Brodkorb Date: Wed Jul 20 23:41:10 2016 +0200 microblaze: use assembly version of clone, fix vfork Signed-off-by: Waldemar Brodkorb commit a7f8986f6e81b912b35b46dcad4b8258f75c8b29 Author: Waldemar Brodkorb Date: Sun Jul 24 19:15:09 2016 +0200 ldso: remove useless debug output, too much noise ----------------------------------------------------------------------- Summary of changes: extra/Configs/Config.in | 1 - include/elf.h | 55 +++---- ldso/ldso/dl-startup.c | 2 - ldso/ldso/microblaze/dl-debug.h | 8 ++ ldso/ldso/microblaze/dl-startup.h | 3 - ldso/ldso/microblaze/dl-sysdep.h | 28 ++-- ldso/ldso/microblaze/elfinterp.c | 22 +-- libc/sysdeps/linux/microblaze/Makefile.arch | 4 +- .../linux/{xtensa => microblaze}/__syscall_error.c | 0 .../linux/microblaze/bits/uClibc_arch_features.h | 3 +- libc/sysdeps/linux/microblaze/clone.S | 77 ++++++++++ libc/sysdeps/linux/microblaze/clone.c | 47 ------ libc/sysdeps/linux/microblaze/jmpbuf-offsets.h | 6 - libc/sysdeps/linux/microblaze/jmpbuf-unwind.h | 25 ++++ libc/sysdeps/linux/microblaze/sysdep.h | 83 ++++++++++- libc/sysdeps/linux/microblaze/vfork.S | 73 +++++----- .../nptl/sysdeps/{arc => microblaze}/Makefile.arch | 4 - .../nptl/sysdeps/{sh => microblaze}/dl-tls.h | 12 +- .../nptl/sysdeps/{arm => microblaze}/libc-tls.c | 16 +-- .../{arm => microblaze}/pthread_spin_lock.c | 4 - .../{arm => microblaze}/pthread_spin_trylock.c | 0 .../nptl/sysdeps/{mips => microblaze}/pthreaddef.h | 26 ++-- .../sysdeps/{mips => microblaze}/tcb-offsets.sym | 4 +- libpthread/nptl/sysdeps/microblaze/tls.h | 159 +++++++++++++++++++++ .../unix/sysv/linux/{metag => microblaze}/Makefile | 0 .../sysv/linux/{arc => microblaze}/Makefile.arch | 6 - .../{xtensa => microblaze}/bits/pthreadtypes.h | 75 +++++----- .../linux/{arm => microblaze}/bits/semaphore.h | 8 +- .../sysdeps/unix/sysv/linux/microblaze/clone.S | 4 + .../sysv/linux/{arm => microblaze}/createthread.c | 0 .../unix/sysv/linux/{xtensa => microblaze}/fork.c | 0 .../sysv/linux/{arc => microblaze}/lowlevellock.h | 24 ++-- .../linux/{xtensa => microblaze}/pthread_once.c | 0 .../unix/sysv/linux/microblaze/sysdep-cancel.h | 139 ++++++++++++++++++ .../sysdeps/unix/sysv/linux/microblaze/vfork.S | 5 + 35 files changed, 673 insertions(+), 250 deletions(-) copy libc/sysdeps/linux/{xtensa => microblaze}/__syscall_error.c (100%) create mode 100644 libc/sysdeps/linux/microblaze/clone.S delete mode 100644 libc/sysdeps/linux/microblaze/clone.c delete mode 100644 libc/sysdeps/linux/microblaze/jmpbuf-offsets.h copy libpthread/nptl/sysdeps/{arc => microblaze}/Makefile.arch (69%) copy libpthread/nptl/sysdeps/{sh => microblaze}/dl-tls.h (69%) copy libpthread/nptl/sysdeps/{arm => microblaze}/libc-tls.c (70%) copy libpthread/nptl/sysdeps/{arm => microblaze}/pthread_spin_lock.c (88%) copy libpthread/nptl/sysdeps/{arm => microblaze}/pthread_spin_trylock.c (100%) copy libpthread/nptl/sysdeps/{mips => microblaze}/pthreaddef.h (62%) copy libpthread/nptl/sysdeps/{mips => microblaze}/tcb-offsets.sym (52%) create mode 100644 libpthread/nptl/sysdeps/microblaze/tls.h copy libpthread/nptl/sysdeps/unix/sysv/linux/{metag => microblaze}/Makefile (100%) copy libpthread/nptl/sysdeps/unix/sysv/linux/{arc => microblaze}/Makefile.arch (71%) copy libpthread/nptl/sysdeps/unix/sysv/linux/{xtensa => microblaze}/bits/pthreadtypes.h (77%) copy libpthread/nptl/sysdeps/unix/sysv/linux/{arm => microblaze}/bits/semaphore.h (90%) create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/clone.S copy libpthread/nptl/sysdeps/unix/sysv/linux/{arm => microblaze}/createthread.c (100%) copy libpthread/nptl/sysdeps/unix/sysv/linux/{xtensa => microblaze}/fork.c (100%) copy libpthread/nptl/sysdeps/unix/sysv/linux/{arc => microblaze}/lowlevellock.h (93%) copy libpthread/nptl/sysdeps/unix/sysv/linux/{xtensa => microblaze}/pthread_once.c (100%) create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/sysdep-cancel.h create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/vfork.S hooks/post-receive diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in index b259464..cb2d4d1 100644 --- a/extra/Configs/Config.in +++ b/extra/Configs/Config.in @@ -521,7 +521,6 @@ config UCLIBC_HAS_THREADS_NATIVE !TARGET_hppa && \ !TARGET_ia64 && \ !TARGET_m68k && \ - !TARGET_microblaze && \ !TARGET_nds32 && \ !TARGET_nios2 && \ !TARGET_or1k && \ diff --git a/include/elf.h b/include/elf.h index 17a6143..cca3d38 100644 --- a/include/elf.h +++ b/include/elf.h @@ -3234,30 +3234,37 @@ typedef Elf32_Addr Elf32_Conflict; #define DT_C6000_NUM 4 -/* microblaze specific relocs */ -#define R_MICROBLAZE_NONE 0 -#define R_MICROBLAZE_32 1 -#define R_MICROBLAZE_32_PCREL 2 -#define R_MICROBLAZE_64_PCREL 3 -#define R_MICROBLAZE_32_PCREL_LO 4 -#define R_MICROBLAZE_64 5 -#define R_MICROBLAZE_32_LO 6 -#define R_MICROBLAZE_SRO32 7 -#define R_MICROBLAZE_SRW32 8 -#define R_MICROBLAZE_64_NONE 9 -#define R_MICROBLAZE_32_SYM_OP_SYM 10 -#define R_MICROBLAZE_GNU_VTINHERIT 11 -#define R_MICROBLAZE_GNU_VTENTRY 12 -#define R_MICROBLAZE_GOTPC_64 13 /* PC-relative GOT offset */ -#define R_MICROBLAZE_GOT_64 14 /* GOT entry offset */ -#define R_MICROBLAZE_PLT_64 15 /* PLT offset (PC-relative */ -#define R_MICROBLAZE_REL 16 /* adjust by program base */ -#define R_MICROBLAZE_JUMP_SLOT 17 /* create PLT entry */ -#define R_MICROBLAZE_GLOB_DAT 18 /* create GOT entry */ -#define R_MICROBLAZE_GOTOFF_64 19 /* offset relative to GOT */ -#define R_MICROBLAZE_GOTOFF_32 20 /* offset relative to GOT */ -#define R_MICROBLAZE_COPY 21 /* runtime copy */ -#define R_MICROBLAZE_NUM 22 +/* MicroBlaze relocations */ +#define R_MICROBLAZE_NONE 0 /* No reloc. */ +#define R_MICROBLAZE_32 1 /* Direct 32 bit. */ +#define R_MICROBLAZE_32_PCREL 2 /* PC relative 32 bit. */ +#define R_MICROBLAZE_64_PCREL 3 /* PC relative 64 bit. */ +#define R_MICROBLAZE_32_PCREL_LO 4 /* Low 16 bits of PCREL32. */ +#define R_MICROBLAZE_64 5 /* Direct 64 bit. */ +#define R_MICROBLAZE_32_LO 6 /* Low 16 bit. */ +#define R_MICROBLAZE_SRO32 7 /* Read-only small data area. */ +#define R_MICROBLAZE_SRW32 8 /* Read-write small data area. */ +#define R_MICROBLAZE_64_NONE 9 /* No reloc. */ +#define R_MICROBLAZE_32_SYM_OP_SYM 10 /* Symbol Op Symbol relocation. */ +#define R_MICROBLAZE_GNU_VTINHERIT 11 /* GNU C++ vtable hierarchy. */ +#define R_MICROBLAZE_GNU_VTENTRY 12 /* GNU C++ vtable member usage. */ +#define R_MICROBLAZE_GOTPC_64 13 /* PC-relative GOT offset. */ +#define R_MICROBLAZE_GOT_64 14 /* GOT entry offset. */ +#define R_MICROBLAZE_PLT_64 15 /* PLT offset (PC-relative). */ +#define R_MICROBLAZE_REL 16 /* Adjust by program base. */ +#define R_MICROBLAZE_JUMP_SLOT 17 /* Create PLT entry. */ +#define R_MICROBLAZE_GLOB_DAT 18 /* Create GOT entry. */ +#define R_MICROBLAZE_GOTOFF_64 19 /* 64 bit offset to GOT. */ +#define R_MICROBLAZE_GOTOFF_32 20 /* 32 bit offset to GOT. */ +#define R_MICROBLAZE_COPY 21 /* Runtime copy. */ +#define R_MICROBLAZE_TLS 22 /* TLS Reloc. */ +#define R_MICROBLAZE_TLSGD 23 /* TLS General Dynamic. */ +#define R_MICROBLAZE_TLSLD 24 /* TLS Local Dynamic. */ +#define R_MICROBLAZE_TLSDTPMOD32 25 /* TLS Module ID. */ +#define R_MICROBLAZE_TLSDTPREL32 26 /* TLS Offset Within TLS Block. */ +#define R_MICROBLAZE_TLSDTPREL64 27 /* TLS Offset Within TLS Block. */ +#define R_MICROBLAZE_TLSGOTTPREL32 28 /* TLS Offset From Thread Pointer. */ +#define R_MICROBLAZE_TLSTPREL32 29 /* TLS Offset From Thread Pointer. */ /* Meta relocations */ #define R_METAG_HIADDR16 0 diff --git a/ldso/ldso/dl-startup.c b/ldso/ldso/dl-startup.c index 18a39ce..87f564f 100644 --- a/ldso/ldso/dl-startup.c +++ b/ldso/ldso/dl-startup.c @@ -319,8 +319,6 @@ DL_START(unsigned long args) SEND_STDERR_DEBUG(strtab + sym->st_name); SEND_STDERR_DEBUG("\n"); #endif - } else { - SEND_STDERR_DEBUG("relocating unknown symbol\n"); } /* Use this machine-specific macro to perform the actual relocation. */ PERFORM_BOOTSTRAP_RELOC(rpnt, reloc_addr, symbol_addr, load_addr, sym); diff --git a/ldso/ldso/microblaze/dl-debug.h b/ldso/ldso/microblaze/dl-debug.h index 6fd7bd5..30b27bb 100644 --- a/ldso/ldso/microblaze/dl-debug.h +++ b/ldso/ldso/microblaze/dl-debug.h @@ -51,4 +51,12 @@ static const char * const _dl_reltypes_tab[] = "R_MICROBLAZE_GOTOFF_64", "R_MICROBLAZE_GOTOFF_32", "R_MICROBLAZE_COPY", + "R_MICROBLAZE_TLS", + "R_MICROBLAZE_TLSGD", + "R_MICROBLAZE_TLSLD", + "R_MICROBLAZE_TLSDTPMOD32", + "R_MICROBLAZE_TLSDTPREL32", + "R_MICROBLAZE_TLSDTPREL64", + "R_MICROBLAZE_TLSGOTTPREL32", + "R_MICROBLAZE_TLSTPREL32", }; diff --git a/ldso/ldso/microblaze/dl-startup.h b/ldso/ldso/microblaze/dl-startup.h index ba15a87..720c53a 100644 --- a/ldso/ldso/microblaze/dl-startup.h +++ b/ldso/ldso/microblaze/dl-startup.h @@ -78,9 +78,6 @@ _dl_start_user:\n\ */ #define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*) ARGS)+1) -/* The ld.so library requires relocations */ -#define ARCH_NEEDS_BOOTSTRAP_RELOCS - static __always_inline void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr, unsigned long symbol_addr, unsigned long load_addr, attribute_unused Elf32_Sym *symtab) diff --git a/ldso/ldso/microblaze/dl-sysdep.h b/ldso/ldso/microblaze/dl-sysdep.h index b293d27..4320027 100644 --- a/ldso/ldso/microblaze/dl-sysdep.h +++ b/ldso/ldso/microblaze/dl-sysdep.h @@ -1,5 +1,3 @@ -/* elf reloc code for the microblaze platform, based on glibc 2.3.6, dl-machine.h */ - /* The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -15,37 +13,41 @@ License along with the GNU C Library; if not, see . */ -/* Use reloca */ #define ELF_USES_RELOCA #include - /* Initialise the GOT */ -#define INIT_GOT(GOT_BASE,MODULE) \ -do { \ - GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \ - GOT_BASE[1] = (unsigned long) MODULE; \ +#define INIT_GOT(GOT_BASE,MODULE) \ +do { \ + GOT_BASE[1] = (unsigned long) MODULE; \ + GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \ } while(0) /* Here we define the magic numbers that this dynamic loader should accept */ - #define MAGIC1 EM_MICROBLAZE #undef MAGIC2 /* Used for error messages */ #define ELF_TARGET "microblaze" +/* Need bootstrap relocations */ +#define ARCH_NEEDS_BOOTSTRAP_RELOCS + struct elf_resolve; unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); #define elf_machine_type_class(type) \ - (((type) == R_MICROBLAZE_JUMP_SLOT) * ELF_RTYPE_CLASS_PLT \ + (((type) == R_MICROBLAZE_JUMP_SLOT || \ + (type) == R_MICROBLAZE_TLSDTPREL32 || \ + (type) == R_MICROBLAZE_TLSDTPMOD32 || \ + (type) == R_MICROBLAZE_TLSTPREL32) \ + * ELF_RTYPE_CLASS_PLT \ | ((type) == R_MICROBLAZE_COPY) * ELF_RTYPE_CLASS_COPY) /* Return the link-time address of _DYNAMIC. Conveniently, this is the first element of the GOT. This must be inlined in a function which uses global data. */ -static inline Elf32_Addr +static __always_inline Elf32_Addr __attribute__ ((unused)) elf_machine_dynamic (void) { Elf32_Addr got_entry_0; @@ -56,7 +58,6 @@ elf_machine_dynamic (void) return got_entry_0; } - /* Return the run-time load address of the shared object. */ static inline Elf32_Addr elf_machine_load_address (void) @@ -64,6 +65,7 @@ elf_machine_load_address (void) /* Compute the difference between the runtime address of _DYNAMIC as seen by a GOTOFF reference, and the link-time address found in the special unrelocated first GOT entry. */ + Elf32_Addr dyn; __asm__ __volatile__ ( "addik %0,r20,_DYNAMIC@GOTOFF" @@ -72,8 +74,6 @@ elf_machine_load_address (void) return dyn - elf_machine_dynamic (); } - - static __always_inline void elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, Elf32_Word relative_count) diff --git a/ldso/ldso/microblaze/elfinterp.c b/ldso/ldso/microblaze/elfinterp.c index 1f6aeff..33aef2f 100644 --- a/ldso/ldso/microblaze/elfinterp.c +++ b/ldso/ldso/microblaze/elfinterp.c @@ -214,16 +214,13 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, case R_MICROBLAZE_NONE: case R_MICROBLAZE_64_NONE: break; - case R_MICROBLAZE_64: *reloc_addr = symbol_addr + rpnt->r_addend; break; - case R_MICROBLAZE_32: case R_MICROBLAZE_32_LO: *reloc_addr = symbol_addr + rpnt->r_addend; break; - case R_MICROBLAZE_32_PCREL: case R_MICROBLAZE_32_PCREL_LO: case R_MICROBLAZE_64_PCREL: @@ -231,16 +228,25 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, case R_MICROBLAZE_SRW32: *reloc_addr = symbol_addr + rpnt->r_addend; break; - case R_MICROBLAZE_GLOB_DAT: case R_MICROBLAZE_JUMP_SLOT: *reloc_addr = symbol_addr + rpnt->r_addend; break; -/* Handled by elf_machine_relative */ case R_MICROBLAZE_REL: *reloc_addr = (unsigned long)tpnt->loadaddr + rpnt->r_addend; break; - +#if defined USE_TLS && USE_TLS + case R_MICROBLAZE_TLSDTPMOD32: + *reloc_addr = tls_tpnt->l_tls_modid; + break; + case R_MICROBLAZE_TLSDTPREL32: + *reloc_addr = symbol_addr; + break; + case R_MICROBLAZE_TLSTPREL32: + CHECK_STATIC_TLS ((struct link_map *) tls_tpnt); + *reloc_addr = tls_tpnt->l_tls_offset + symbol_addr + rpnt->r_addend; + break; +#endif case R_MICROBLAZE_COPY: if (symbol_addr) { #if defined (__SUPPORT_LD_DEBUG__) @@ -250,7 +256,6 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, symname, sym_ref.sym->st_size, symbol_addr, reloc_addr); #endif - _dl_memcpy((char *)reloc_addr, (char *)symbol_addr, sym_ref.sym->st_size); @@ -260,7 +265,6 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, _dl_dprintf(_dl_debug_file, "no symbol_addr to copy !?\n"); #endif break; - default: return -1; /* Calls _dl_exit(1). */ } @@ -279,14 +283,12 @@ _dl_do_lazy_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab) { int reloc_type; - int symtab_index; ElfW(Addr) *reloc_addr; #if defined (__SUPPORT_LD_DEBUG__) ElfW(Addr) old_val; #endif (void)scope; - symtab_index = ELF_R_SYM(rpnt->r_info); (void)strtab; reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + rpnt->r_offset); diff --git a/libc/sysdeps/linux/microblaze/Makefile.arch b/libc/sysdeps/linux/microblaze/Makefile.arch index 6f1e9fb..b89f7f9 100644 --- a/libc/sysdeps/linux/microblaze/Makefile.arch +++ b/libc/sysdeps/linux/microblaze/Makefile.arch @@ -5,5 +5,5 @@ # # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. -CSRC-y := clone.c -SSRC-y := setjmp.S __longjmp.S vfork.S +CSRC-y := __syscall_error.c +SSRC-y := setjmp.S __longjmp.S vfork.S clone.S diff --git a/libc/sysdeps/linux/xtensa/__syscall_error.c b/libc/sysdeps/linux/microblaze/__syscall_error.c similarity index 100% copy from libc/sysdeps/linux/xtensa/__syscall_error.c copy to libc/sysdeps/linux/microblaze/__syscall_error.c diff --git a/libc/sysdeps/linux/microblaze/bits/uClibc_arch_features.h b/libc/sysdeps/linux/microblaze/bits/uClibc_arch_features.h index ea767ab..321d699 100644 --- a/libc/sysdeps/linux/microblaze/bits/uClibc_arch_features.h +++ b/libc/sysdeps/linux/microblaze/bits/uClibc_arch_features.h @@ -6,8 +6,7 @@ #define _BITS_UCLIBC_ARCH_FEATURES_H /* instruction used when calling abort() to kill yourself */ -/*#define __UCLIBC_ABORT_INSTRUCTION__ "asm instruction"*/ -#undef __UCLIBC_ABORT_INSTRUCTION__ +#define __UCLIBC_ABORT_INSTRUCTION__ "brki r0, -1" /* can your target use syscall6() for mmap ? */ #define __UCLIBC_MMAP_HAS_6_ARGS__ diff --git a/libc/sysdeps/linux/microblaze/clone.S b/libc/sysdeps/linux/microblaze/clone.S new file mode 100644 index 0000000..69c2045 --- /dev/null +++ b/libc/sysdeps/linux/microblaze/clone.S @@ -0,0 +1,77 @@ +/* Copyright (C) 1996-2016 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, see + . */ + +/* clone() is even more special than fork() as it mucks with stacks + and invokes a function in the right context after its all over. */ + +#include +#define _ERRNO_H 1 +#include + +#if defined __UCLIBC_HAS_THREADS__ && !defined __UCLIBC_HAS_LINUXTHREADS__ +#include +#endif + +/* int clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg, + pid_t *ptid, struct user_desc *tls, pid_t *ctid); + + INCOMING: r5 (fn), r6 (child_stack), r7 (flags), r8 (arg), r9 (ptid) + r10 (tls), 28 (r1) ctid + + OUTGOING: + + linux: arch/microblaze/entry.S: sys_clone expects + r5 (flags) r6 (child stack) r7 (stack_size) r8 (ptid)r9 (ctid) + r10 (tls) +*/ + + .text +ENTRY (__clone) + addik r3,r0,-EINVAL + beqi r5,SYSCALL_ERROR_LABEL ; // Invalid func + beqi r6,SYSCALL_ERROR_LABEL ; // Invalid stack + addik r6,r6,-8 + swi r5,r6,0 ; // Push fn onto child's stack + swi r8,r6,4 ; // Push arg for child + addk r5,r0,r7 ; // flags for clone() syscall + addk r7,r0,r0 + addk r8,r0,r9 ; // parent tid ptr + lwi r9,r1,28 ; // child tid ptr + addik r12,r0,SYS_ify(clone) + brki r14,8 + addk r0,r0,r0 + addik r4,r0,-4095 + cmpu r4,r4,r3 + bgei r4,SYSCALL_ERROR_LABEL + beqi r3,L(thread_start) + rtsd r15,8 + nop + +L(thread_start): + lwi r12,r1,0 ; // fn + lwi r5,r1,4 ; // arg + brald r15,r12 + nop + addk r5,r0,r3 + addik r12,r0,SYS_ify(exit) + brki r14,8 + nop +PSEUDO_END(__clone) + +libc_hidden_def (__clone) +weak_alias (__clone,clone) diff --git a/libc/sysdeps/linux/microblaze/clone.c b/libc/sysdeps/linux/microblaze/clone.c deleted file mode 100644 index d921008..0000000 --- a/libc/sysdeps/linux/microblaze/clone.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2004 Atmel Corporation - * - * This file is subject to the terms and conditions of the GNU Lesser General - * Public License. See the file "COPYING.LIB" in the main directory of this - * archive for more details. - */ -#include -#include -#include -#include - -int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, ...) -{ - int rval = -EINVAL; - if (fn && child_stack) - rval = INTERNAL_SYSCALL(clone, 0, 2, flags, child_stack); - - if (rval == 0) - { - int exitCode = fn(arg); - rval = INTERNAL_SYSCALL(exit, 0, 1, exitCode); - } - - return rval; -} - -#ifdef __NR_clone2 -int -__clone2(int (*fn)(void *arg), void *child_stack, size_t stack_size, - int flags, void *arg, ...) -{ - int rval = -EINVAL; - if (fn && child_stack) - { - rval = INTERNAL_SYSCALL(clone2, 0, 3, flags, child_stack, stack_size); - } - - if (rval == 0) - { - int exitCode = fn(arg); - rval = INTERNAL_SYSCALL(exit, 0, 1, exitCode); - } - - return rval; -} -#endif diff --git a/libc/sysdeps/linux/microblaze/jmpbuf-offsets.h b/libc/sysdeps/linux/microblaze/jmpbuf-offsets.h deleted file mode 100644 index c6cccc7..0000000 --- a/libc/sysdeps/linux/microblaze/jmpbuf-offsets.h +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (C) 2000-2006 Erik Andersen - * - * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. - */ -#define JB_SIZE (4 * 18) diff --git a/libc/sysdeps/linux/microblaze/jmpbuf-unwind.h b/libc/sysdeps/linux/microblaze/jmpbuf-unwind.h index 2c1c079..155792b 100644 --- a/libc/sysdeps/linux/microblaze/jmpbuf-unwind.h +++ b/libc/sysdeps/linux/microblaze/jmpbuf-unwind.h @@ -10,3 +10,28 @@ containing a local variable at ADDRESS. */ #define _JMPBUF_UNWINDS(jmpbuf, address) \ ((void *) (address) < (void *) (jmpbuf)[0].__sp) + +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ +#include +#include + +/* Test if longjmp to JMPBUF would unwind the frame + containing a local variable at ADDRESS. */ +#undef _JMPBUF_UNWINDS +#define _JMPBUF_UNWINDS(jmpbuf, address) \ + ((void *) (address) < (void *) (jmpbuf)[0].__sp) + +#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \ + _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj) + +static inline uintptr_t __attribute__ ((unused)) +_jmpbuf_sp (__jmp_buf regs) +{ + void *sp = (void *) regs[0].__sp; + return (uintptr_t) sp; +} + +#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \ + ((uintptr_t) (_address) - (_adj) < _jmpbuf_sp (_jmpbuf) - (_adj)) + +#endif diff --git a/libc/sysdeps/linux/microblaze/sysdep.h b/libc/sysdeps/linux/microblaze/sysdep.h index 1f01a2a..a463d33 100644 --- a/libc/sysdeps/linux/microblaze/sysdep.h +++ b/libc/sysdeps/linux/microblaze/sysdep.h @@ -1,9 +1,25 @@ +/* Copyright (C) 2000-2016 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, see + . */ + #include #ifdef __ASSEMBLER__ -/* Syntactic details of assembler. */ - # define ALIGNARG(log2) log2 # define ASM_SIZE_DIRECTIVE(name) .size name,.-name @@ -22,4 +38,67 @@ # define L(name) $L##name # endif +/* We don't want the label for the error handler to be visible in the symbol + table when we define it here. */ +# ifdef __PIC__ +# define SYSCALL_ERROR_LABEL 0f +# else +# define SYSCALL_ERROR_LABEL __syscall_error +# endif + +# define DO_CALL(syscall_name, args) \ + addik r12,r0,SYS_ify (syscall_name); \ + brki r14,8; \ + addk r0,r0,r0; + +# undef PSEUDO +# define PSEUDO(name, syscall_name, args) \ + .text; \ + ENTRY (name) \ + DO_CALL (syscall_name, args); \ + addik r12,r0,-4095; \ + cmpu r12,r12,r3; \ + bgei r12,SYSCALL_ERROR_LABEL; + +# undef PSEUDO_END +# define PSEUDO_END(name) \ + SYSCALL_ERROR_HANDLER; \ + END (name) + +#ifdef __PIC__ +# define SYSCALL_ERROR_LABEL_DCL 0 +# if defined _LIBC_REENTRANT +# define SYSCALL_ERROR_HANDLER \ +SYSCALL_ERROR_LABEL_DCL: \ + addik r1,r1,-16; \ + swi r15,r1,0; \ + swi r20,r1,8; \ + rsubk r3,r3,r0; \ + swi r3,r1,12; \ + mfs r20,rpc; \ + addik r20,r20,_GLOBAL_OFFSET_TABLE_+8; \ + brlid r15,__errno_location@PLT; \ + nop; \ + lwi r4,r1,12; \ + swi r4,r3,0; \ + lwi r20,r1,8; \ + lwi r15,r1,0; \ + addik r1,r1,16; \ + rtsd r15,8; \ + addik r3,r0,-1; +# else /* !_LIBC_REENTRANT. */ +# define SYSCALL_ERROR_HANDLER \ +SYSCALL_ERROR_LABEL_DCL: \ + mfs r12,rpc; \ + addik r12,r12,_GLOBAL_OFFSET_TABLE_+8; \ + lwi r12,r12,errno@GOT; \ + rsubk r3,r3,r0; \ + swi r3,r12,0; \ + rtsd r15,8; \ + addik r3,r0,-1; +# endif /* _LIBC_REENTRANT. */ +#else +# define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */ +#endif /* PIC. */ + #endif diff --git a/libc/sysdeps/linux/microblaze/vfork.S b/libc/sysdeps/linux/microblaze/vfork.S index cd60128..11b9e27 100644 --- a/libc/sysdeps/linux/microblaze/vfork.S +++ b/libc/sysdeps/linux/microblaze/vfork.S @@ -1,47 +1,44 @@ -/* - * libc/sysdeps/linux/microblaze/vfork.S -- `vfork' syscall for linux/microblaze - * - * Copyright (C) 2003 John Williams - * Copyright (C) 2001 NEC Corporation - * Copyright (C) 2001 Miles Bader - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License. See the file COPYING.LIB in the main - * directory of this archive for more details. - * - * Written by Miles Bader - * Microblaze port by John Williams - */ - -#include +/* Copyright (C) 2005-2016 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, see + . */ + +#include +#define _ERRNO_H 1 +#include /* Clone the calling process, but without copying the whole address space. The calling process is suspended until the new process exits or is replaced by a call to `execve'. Return -1 for errors, 0 to the new process, and the process ID of the new process to the old process. */ - .globl __vfork - .hidden __vfork - .align 4 -__vfork: - addi r12, r0, SYS_vfork - brki r14, 0x08; - addi r4, r3, 125 /* minimum err value */ - blti r4, 1f /* is r3 < -125? */ - bri 2f /* normal return */ -1: sub r3, r3, r0 /* r3 = -r3 */ -#ifdef __PIC__ - mfs r3,rpc - addik r3,r3,_GLOBAL_OFFSET_TABLE_+8 - lwi r3,r3,C_SYMBOL_NAME(errno)@GOT - sw r3, r0, r3 -#else - swi r3, r0, C_SYMBOL_NAME(errno); -#endif - /* state restore etc */ -2: rtsd r15, 8 /* error return */ +ENTRY(__vfork) + + DO_CALL (vfork, 0) + addik r12,r0,-4095 + cmpu r12,r12,r3 + bgei r12,1f + rtsd r15,8 nop - .size __vfork, .-__vfork -weak_alias(__vfork,vfork) +1: rsubk r3,r3,r0 + rtsd r15,8 + addik r3,r0,-1 /* delay slot. */ + +END(__vfork) + +weak_alias(__vfork, vfork) libc_hidden_def(vfork) diff --git a/libpthread/nptl/sysdeps/arc/Makefile.arch b/libpthread/nptl/sysdeps/microblaze/Makefile.arch similarity index 69% copy from libpthread/nptl/sysdeps/arc/Makefile.arch copy to libpthread/nptl/sysdeps/microblaze/Makefile.arch index 08ec7e7..b69fb48 100644 --- a/libpthread/nptl/sysdeps/arc/Makefile.arch +++ b/libpthread/nptl/sysdeps/microblaze/Makefile.arch @@ -1,8 +1,4 @@ # Makefile for uClibc NPTL -# -# Copyright (C) 2005 Steven J. Hill -# # Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball. -# libc_arch_a_CSRC = libc-tls.c diff --git a/libpthread/nptl/sysdeps/sh/dl-tls.h b/libpthread/nptl/sysdeps/microblaze/dl-tls.h similarity index 69% copy from libpthread/nptl/sysdeps/sh/dl-tls.h copy to libpthread/nptl/sysdeps/microblaze/dl-tls.h index f5f90be..5613e21 100644 --- a/libpthread/nptl/sysdeps/sh/dl-tls.h +++ b/libpthread/nptl/sysdeps/microblaze/dl-tls.h @@ -1,11 +1,11 @@ -/* Thread-local storage handling in the ELF dynamic linker. SH version. - Copyright (C) 2002 Free Software Foundation, Inc. +/* Copyright (C) 2005-2016 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. + 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 @@ -16,7 +16,6 @@ License along with the GNU C Library; if not, see . */ - /* Type used for the representation of TLS information in the GOT. */ typedef struct { @@ -24,5 +23,4 @@ typedef struct unsigned long int ti_offset; } tls_index; - extern void *__tls_get_addr (tls_index *ti); diff --git a/libpthread/nptl/sysdeps/arm/libc-tls.c b/libpthread/nptl/sysdeps/microblaze/libc-tls.c similarity index 70% copy from libpthread/nptl/sysdeps/arm/libc-tls.c copy to libpthread/nptl/sysdeps/microblaze/libc-tls.c index 6576072..7f440fb 100644 --- a/libpthread/nptl/sysdeps/arm/libc-tls.c +++ b/libpthread/nptl/sysdeps/microblaze/libc-tls.c @@ -1,11 +1,11 @@ -/* Thread-local storage handling in the ELF dynamic linker. ARM version. - Copyright (C) 2005 Free Software Foundation, Inc. +/* Copyright (C) 2005-2016 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. + 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 @@ -19,13 +19,13 @@ #include #include -#if defined(USE_TLS) && USE_TLS - -/* On ARM, linker optimizations are not required, so __tls_get_addr +/* On Microblaze, 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. */ +#if defined(USE_TLS) && USE_TLS + void * __tls_get_addr (tls_index *ti) { diff --git a/libpthread/nptl/sysdeps/arm/pthread_spin_lock.c b/libpthread/nptl/sysdeps/microblaze/pthread_spin_lock.c similarity index 88% copy from libpthread/nptl/sysdeps/arm/pthread_spin_lock.c copy to libpthread/nptl/sysdeps/microblaze/pthread_spin_lock.c index 77f5f50..e393a73 100644 --- a/libpthread/nptl/sysdeps/arm/pthread_spin_lock.c +++ b/libpthread/nptl/sysdeps/microblaze/pthread_spin_lock.c @@ -19,10 +19,6 @@ #include #include "pthreadP.h" -/* A machine-specific version can define SPIN_LOCK_READS_BETWEEN_CMPXCHG - to the number of plain reads that it's optimal to spin on between uses - of atomic_compare_and_exchange_val_acq. If spinning forever is optimal - then use -1. If no plain reads here would ever be optimal, use 0. */ #define SPIN_LOCK_READS_BETWEEN_CMPXCHG 1000 int diff --git a/libpthread/nptl/sysdeps/arm/pthread_spin_trylock.c b/libpthread/nptl/sysdeps/microblaze/pthread_spin_trylock.c similarity index 100% copy from libpthread/nptl/sysdeps/arm/pthread_spin_trylock.c copy to libpthread/nptl/sysdeps/microblaze/pthread_spin_trylock.c diff --git a/libpthread/nptl/sysdeps/mips/pthreaddef.h b/libpthread/nptl/sysdeps/microblaze/pthreaddef.h similarity index 62% copy from libpthread/nptl/sysdeps/mips/pthreaddef.h copy to libpthread/nptl/sysdeps/microblaze/pthreaddef.h index 6929882..47e87dd 100644 --- a/libpthread/nptl/sysdeps/mips/pthreaddef.h +++ b/libpthread/nptl/sysdeps/microblaze/pthreaddef.h @@ -1,10 +1,11 @@ -/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. +/* Copyright (C) 2002-2016 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. + 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 @@ -15,24 +16,25 @@ License along with the GNU C Library; if not, see . */ +#include +#include + /* Default stack size. */ -#define ARCH_STACK_DEFAULT_SIZE (2 * 1024 * 1024) +#define ARCH_STACK_DEFAULT_SIZE (2 * 1024 * 1024) /* Required stack pointer alignment at beginning. */ -#define STACK_ALIGN 16 +#define STACK_ALIGN 16 /* Minimal stack size after allocating thread descriptor and guard size. */ -#define MINIMAL_REST_STACK 2048 +#define MINIMAL_REST_STACK 2048 /* Alignment requirement for TCB. */ -#define TCB_ALIGNMENT 16 - +#define TCB_ALIGNMENT 16 /* Location of current stack frame. */ -#define CURRENT_STACK_FRAME __builtin_frame_address (0) - +#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)) +INLINE_SYSCALL (exit, 1, (val)) diff --git a/libpthread/nptl/sysdeps/mips/tcb-offsets.sym b/libpthread/nptl/sysdeps/microblaze/tcb-offsets.sym similarity index 52% copy from libpthread/nptl/sysdeps/mips/tcb-offsets.sym copy to libpthread/nptl/sysdeps/microblaze/tcb-offsets.sym index e0e71dc..18afbee 100644 --- a/libpthread/nptl/sysdeps/mips/tcb-offsets.sym +++ b/libpthread/nptl/sysdeps/microblaze/tcb-offsets.sym @@ -4,8 +4,8 @@ -- -- Abuse tls.h macros to derive offsets relative to the thread register. -#define thread_offsetof(mem) (long)(offsetof(struct pthread, mem) - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE) +#define thread_offsetof(mem) (long)(offsetof (struct pthread, mem) - sizeof (struct pthread)) -MULTIPLE_THREADS_OFFSET thread_offsetof (header.multiple_threads) +MULTIPLE_THREADS_OFFSET thread_offsetof (header.multiple_threads) PID_OFFSET thread_offsetof (pid) TID_OFFSET thread_offsetof (tid) diff --git a/libpthread/nptl/sysdeps/microblaze/tls.h b/libpthread/nptl/sysdeps/microblaze/tls.h new file mode 100644 index 0000000..b5bcde9 --- /dev/null +++ b/libpthread/nptl/sysdeps/microblaze/tls.h @@ -0,0 +1,159 @@ +/* Copyright (C) 2005-2016 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, see + . */ + +#ifndef _TLS_H +# define _TLS_H 1 + +#ifndef __ASSEMBLER__ + +# include +# include +# include + +/* Type for the dtv. */ +typedef union dtv +{ + size_t counter; + struct + { + void *val; + bool is_static; + } pointer; +} dtv_t; + +#else /* __ASSEMBLER__ */ +# include +#endif /* __ASSEMBLER__ */ + +/* We require TLS support in the tools. */ +#define HAVE_TLS_SUPPORT 1 +#define HAVE___THREAD 1 +#define HAVE_TLS_MODEL_ATTRIBUTE 1 + +/* Signal that TLS support is available. */ +#define USE_TLS 1 + +#ifndef __ASSEMBLER__ + +/* Get system call information. */ +# include + +/* 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; + +#define READ_THREAD_POINTER() \ + ({ register void *__microblaze_thread_area __asm__ ("r21"); \ + __microblaze_thread_area; }) + +/* 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. + r21 is reserved for thread pointer. */ +# define TLS_INIT_TP(tcbp, secondcall) \ + ({ __asm__ __volatile__ ("or r21,r0,%0" : : "r" ((void *)tcbp)); NULL; }) + +# define TLS_DEFINE_INIT_TP(tp, pd) void *tp = (pd) + 1 + +/* Return the address of the dtv for the current thread. */ +# define THREAD_DTV() \ + (((tcbhead_t *) READ_THREAD_POINTER())->dtv) + +/* Return the thread descriptor for the current thread. */ +# define THREAD_SELF \ + (((struct pthread *) READ_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)) + +/* Read member of the thread descriptor directly. */ +# define THREAD_GETMEM(descr, member) (descr->member) + +/* Same as THREAD_GETMEM, but the member offset can be non-constant. */ +# define THREAD_GETMEM_NC(descr, member, idx) \ + (descr->member[idx]) + +/* Set member of the thread descriptor directly. */ +# define THREAD_SETMEM(descr, member, value) \ + (descr->member = (value)) + +/* Same as THREAD_SETMEM, but the member offset can be non-constant. */ +# define THREAD_SETMEM_NC(descr, member, idx, value) \ + (descr->member[idx] = (value)) + +/* Get and set the global scope generation counter in struct pthread. */ +# define THREAD_GSCOPE_FLAG_UNUSED 0 +# define THREAD_GSCOPE_FLAG_USED 1 +# define THREAD_GSCOPE_FLAG_WAIT 2 +# define THREAD_GSCOPE_RESET_FLAG() \ + do \ + { int __res \ + = atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \ + THREAD_GSCOPE_FLAG_UNUSED); \ + if (__res == THREAD_GSCOPE_FLAG_WAIT) \ + lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE); \ + } \ + while (0) +# define THREAD_GSCOPE_SET_FLAG() \ + do \ + { \ + THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED; \ + atomic_write_barrier (); \ + } \ + while (0) +# define THREAD_GSCOPE_WAIT() \ + GL (dl_wait_lookup_done) () + +#endif /* __ASSEMBLER__ */ + +#endif /* tls.h. */ diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/metag/Makefile b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/Makefile similarity index 100% copy from libpthread/nptl/sysdeps/unix/sysv/linux/metag/Makefile copy to libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/Makefile diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arc/Makefile.arch b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/Makefile.arch similarity index 71% copy from libpthread/nptl/sysdeps/unix/sysv/linux/arc/Makefile.arch copy to libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/Makefile.arch index fa5d530..77707a0 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/arc/Makefile.arch +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/Makefile.arch @@ -1,14 +1,8 @@ # Makefile for uClibc NPTL -# -# Copyright (C) 2006 Steven J. Hill -# # Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball. -# libpthread_linux_arch_SSRC = libpthread_linux_arch_CSRC = pthread_once.c libc_linux_arch_CSRC = fork.c libc_linux_arch_SSRC = clone.S vfork.S -libc_linux_arch_SSRC-OMIT = waitpid.S - diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/bits/pthreadtypes.h b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/bits/pthreadtypes.h similarity index 77% copy from libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/bits/pthreadtypes.h copy to libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/bits/pthreadtypes.h index 5e44020..9e9e307 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/bits/pthreadtypes.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/bits/pthreadtypes.h @@ -1,4 +1,5 @@ -/* Copyright (C) 2002-2012 Free Software Foundation, Inc. +/* Copyright (C) 2002-2016 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 @@ -12,48 +13,46 @@ 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, see + License along with the GNU C Library; if not, see . */ #ifndef _BITS_PTHREADTYPES_H -#define _BITS_PTHREADTYPES_H 1 +# define _BITS_PTHREADTYPES_H 1 -#include +# include -#define __SIZEOF_PTHREAD_ATTR_T 36 -#define __SIZEOF_PTHREAD_MUTEX_T 24 -#define __SIZEOF_PTHREAD_MUTEXATTR_T 4 -#define __SIZEOF_PTHREAD_COND_T 48 -#define __SIZEOF_PTHREAD_COND_COMPAT_T 12 -#define __SIZEOF_PTHREAD_CONDATTR_T 4 -#define __SIZEOF_PTHREAD_RWLOCK_T 32 -#define __SIZEOF_PTHREAD_RWLOCKATTR_T 8 -#define __SIZEOF_PTHREAD_BARRIER_T 20 -#define __SIZEOF_PTHREAD_BARRIERATTR_T 4 +# define __SIZEOF_PTHREAD_ATTR_T 36 +# define __SIZEOF_PTHREAD_MUTEX_T 24 +# define __SIZEOF_PTHREAD_MUTEXATTR_T 4 +# define __SIZEOF_PTHREAD_COND_T 48 +# define __SIZEOF_PTHREAD_COND_COMPAT_T 12 +# define __SIZEOF_PTHREAD_CONDATTR_T 4 +# define __SIZEOF_PTHREAD_RWLOCK_T 32 +# define __SIZEOF_PTHREAD_RWLOCKATTR_T 8 +# define __SIZEOF_PTHREAD_BARRIER_T 20 +# define __SIZEOF_PTHREAD_BARRIERATTR_T 4 /* Thread identifiers. The structure of the attribute type is not exposed on purpose. */ typedef unsigned long int pthread_t; - union pthread_attr_t { char __size[__SIZEOF_PTHREAD_ATTR_T]; long int __align; }; -#ifndef __have_pthread_attr_t -typedef union pthread_attr_t pthread_attr_t; -# define __have_pthread_attr_t 1 -#endif +# ifndef __have_pthread_attr_t +typedef union pthread_attr_t pthread_attr_t; +# define __have_pthread_attr_t 1 +# endif typedef struct __pthread_internal_slist { struct __pthread_internal_slist *__next; } __pthread_slist_t; - /* Data structures for mutex handling. The structure of the attribute type is not exposed on purpose. */ typedef union @@ -77,13 +76,15 @@ typedef union long int __align; } pthread_mutex_t; +/* Mutex __spins initializer used by PTHREAD_MUTEX_INITIALIZER. */ +#define __PTHREAD_SPINS 0 + typedef union { char __size[__SIZEOF_PTHREAD_MUTEXATTR_T]; - long int __align; + int __align; } pthread_mutexattr_t; - /* Data structure for conditional variable handling. The structure of the attribute type is not exposed on purpose. */ typedef union @@ -106,19 +107,16 @@ typedef union typedef union { char __size[__SIZEOF_PTHREAD_CONDATTR_T]; - long int __align; + int __align; } pthread_condattr_t; - -/* Keys for thread-specific data */ +/* Keys for thread-specific data. */ typedef unsigned int pthread_key_t; - -/* Once-only execution */ +/* Once-only execution. */ typedef int pthread_once_t; - -#if defined __USE_UNIX98 || defined __USE_XOPEN2K +# if defined __USE_UNIX98 || defined __USE_XOPEN2K /* Data structure for read-write lock variable handling. The structure of the attribute type is not exposed on purpose. */ typedef union @@ -131,40 +129,40 @@ typedef union unsigned int __writer_wakeup; unsigned int __nr_readers_queued; unsigned int __nr_writers_queued; -#if __BYTE_ORDER == __BIG_ENDIAN +# if __BYTE_ORDER == __BIG_ENDIAN unsigned char __pad1; unsigned char __pad2; unsigned char __shared; /* FLAGS must stay at this position in the structure to maintain binary compatibility. */ unsigned char __flags; -#else +# else /* FLAGS must stay at this position in the structure to maintain binary compatibility. */ unsigned char __flags; unsigned char __shared; unsigned char __pad1; unsigned char __pad2; -#endif +# endif int __writer; } __data; char __size[__SIZEOF_PTHREAD_RWLOCK_T]; long int __align; } pthread_rwlock_t; +#define __PTHREAD_RWLOCK_ELISION_EXTRA 0 + typedef union { char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T]; long int __align; } pthread_rwlockattr_t; -#endif - +# endif -#ifdef __USE_XOPEN2K +# ifdef __USE_XOPEN2K /* POSIX spinlock data type. */ typedef volatile int pthread_spinlock_t; - /* POSIX barriers data type. The structure of the type is deliberately not exposed. */ typedef union @@ -178,7 +176,6 @@ typedef union char __size[__SIZEOF_PTHREAD_BARRIERATTR_T]; int __align; } pthread_barrierattr_t; -#endif - +# endif -#endif /* bits/pthreadtypes.h */ +#endif /* bits/pthreadtypes.h. */ diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/semaphore.h b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/bits/semaphore.h similarity index 90% copy from libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/semaphore.h copy to libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/bits/semaphore.h index e68fbcc..ea05026 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/semaphore.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/bits/semaphore.h @@ -1,4 +1,5 @@ -/* Copyright (C) 2002, 2005, 2007 Free Software Foundation, Inc. +/* Copyright (C) 2002-2016 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 @@ -19,13 +20,10 @@ # error "Never use directly; include instead." #endif - #define __SIZEOF_SEM_T 16 - /* Value returned if `sem_open' failed. */ -#define SEM_FAILED ((sem_t *) 0) - +#define SEM_FAILED ((sem_t *) 0) typedef union { diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/clone.S b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/clone.S new file mode 100644 index 0000000..faa78d9 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/clone.S @@ -0,0 +1,4 @@ +#define RESET_PID +#include +#include +#include "../../../../../../../libc/sysdeps/linux/microblaze/clone.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/createthread.c b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/createthread.c similarity index 100% copy from libpthread/nptl/sysdeps/unix/sysv/linux/arm/createthread.c copy to libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/createthread.c diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/fork.c b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/fork.c similarity index 100% copy from libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/fork.c copy to libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/fork.c diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arc/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/lowlevellock.h similarity index 93% copy from libpthread/nptl/sysdeps/unix/sysv/linux/arc/lowlevellock.h copy to libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/lowlevellock.h index 44a1ac0..e8dce9d 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/arc/lowlevellock.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/lowlevellock.h @@ -79,21 +79,21 @@ #define lll_futex_timed_wait(futexp, val, timespec, private) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ - long int __ret; \ - __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \ + long int __sysret; \ + __sysret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \ __lll_private_flag (FUTEX_WAIT, private), \ (val), (timespec)); \ - __ret; \ + __sysret; \ }) #define lll_futex_wake(futexp, nr, private) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ - long int __ret; \ - __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \ + long int __sysret; \ + __sysret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \ __lll_private_flag (FUTEX_WAKE, private), \ (nr), 0); \ - __ret; \ + __sysret; \ }) #define lll_robust_dead(futexv, private) \ @@ -109,11 +109,11 @@ #define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ - long int __ret; \ - __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \ + long int __sysret; \ + __sysret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \ __lll_private_flag (FUTEX_CMP_REQUEUE, private),\ (nr_wake), (nr_move), (mutex), (val)); \ - INTERNAL_SYSCALL_ERROR_P (__ret, __err); \ + INTERNAL_SYSCALL_ERROR_P (__sysret, __err); \ }) @@ -121,12 +121,12 @@ #define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ - long int __ret; \ - __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \ + long int __sysret; \ + __sysret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \ __lll_private_flag (FUTEX_WAKE_OP, private), \ (nr_wake), (nr_wake2), (futexp2), \ FUTEX_OP_CLEAR_WAKE_IF_GT_ONE); \ - INTERNAL_SYSCALL_ERROR_P (__ret, __err); \ + INTERNAL_SYSCALL_ERROR_P (__sysret, __err); \ }) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/pthread_once.c b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/pthread_once.c similarity index 100% copy from libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/pthread_once.c copy to libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/pthread_once.c diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/sysdep-cancel.h new file mode 100644 index 0000000..2af79ca --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/sysdep-cancel.h @@ -0,0 +1,139 @@ +/* Copyright (C) 2014-2016 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, see + . */ + +#include +#include +#ifndef __ASSEMBLER__ +# include +#endif + +#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt + +#ifdef __ASSEMBLER__ + +#undef ret +#define ret + +# if !IS_IN_librt || !defined(PIC) +# define AC_STACK_SIZE 16 /* space for r15, async_cancel arg and 2 temp words */ +# define AC_SET_GOT /* empty */ +# define AC_RESTORE_GOT /* empty */ +# else +# define AC_STACK_SIZE 20 /* extra 4 bytes for r20 */ +# define AC_SET_GOT \ + swi r20, r1, AC_STACK_SIZE-4; \ + mfs r20, rpc; \ + addik r20, r20, _GLOBAL_OFFSET_TABLE_+8; +# define AC_RESTORE_GOT \ + lwi r20, r1, AC_STACK_SIZE-4; +# endif + +# undef PSEUDO +# define PSEUDO(name, syscall_name, args) \ + .text; \ + ENTRY (name) \ + SINGLE_THREAD_P(r12); \ + bnei r12, L(pseudo_cancel); \ + .globl __##syscall_name##_nocancel; \ + .type __##syscall_name##_nocancel,@function; \ +__##syscall_name##_nocancel: \ + DO_CALL (syscall_name, args); \ + addik r4, r0, -4095; \ + cmpu r4, r4, r3; \ + rsubk r3,r3,r0; \ + rtsd r15,8; \ + addik r3,r0,-1; \ + rtsd r15, 8; \ + nop; \ + .size __##syscall_name##_nocancel, .-__##syscall_name##_nocancel; \ +L(pseudo_cancel): \ + addik r1, r1, -AC_STACK_SIZE; \ + swi r15, r1, 0; \ + AC_SET_GOT \ + DOCARGS_##args \ + CENABLE; \ + swi r3, r1, 8; \ + UNDOCARGS_##args \ + DO_CALL (syscall_name, args); \ + swi r3, r1, 12; \ + lwi r5, r1, 8; \ + CDISABLE; \ + lwi r3, r1, 12; \ + lwi r15, r1, 0; \ + AC_RESTORE_GOT \ + addik r1, r1, AC_STACK_SIZE; \ + addik r4, r0, -4095; \ + cmpu r4, r4, r3; \ + rsubk r3,r3,r0; \ + rtsd r15,8; \ + addik r3,r0,-1; \ + rtsd r15, 8; \ + nop; + +/* + * Macros to save/restore syscall arguments across CENABLE + * The arguments are saved into the caller's stack (original r1 + 4) + */ + +# define DOCARGS_0 +# define DOCARGS_1 swi r5, r1, AC_STACK_SIZE + 4; +# define DOCARGS_2 swi r6, r1, AC_STACK_SIZE + 8; DOCARGS_1 +# define DOCARGS_3 swi r7, r1, AC_STACK_SIZE + 12; DOCARGS_2 +# define DOCARGS_4 swi r8, r1, AC_STACK_SIZE + 16; DOCARGS_3 +# define DOCARGS_5 swi r9, r1, AC_STACK_SIZE + 20; DOCARGS_4 +# define DOCARGS_6 swi r10, r1, AC_STACK_SIZE + 24; DOCARGS_5 + +# define UNDOCARGS_0 +# define UNDOCARGS_1 lwi r5, r1, AC_STACK_SIZE + 4; +# define UNDOCARGS_2 UNDOCARGS_1 lwi r6, r1, AC_STACK_SIZE + 8; +# define UNDOCARGS_3 UNDOCARGS_2 lwi r7, r1, AC_STACK_SIZE + 12; +# define UNDOCARGS_4 UNDOCARGS_3 lwi r8, r1, AC_STACK_SIZE + 16; +# define UNDOCARGS_5 UNDOCARGS_4 lwi r9, r1, AC_STACK_SIZE + 20; +# define UNDOCARGS_6 UNDOCARGS_5 lwi r10, r1, AC_STACK_SIZE + 24; + +# ifdef PIC +# define PSEUDO_JMP(sym) brlid r15, sym##@PLTPC; addk r0, r0, r0 +# else +# define PSEUDO_JMP(sym) brlid r15, sym; addk r0, r0, r0 +# endif + +# if defined IS_IN_libpthread +# define CENABLE PSEUDO_JMP (__pthread_enable_asynccancel) +# define CDISABLE PSEUDO_JMP (__pthread_disable_asynccancel) +# define __local_multiple_threads __pthread_multiple_threads +# elif !defined NOT_IN_libc +# define CENABLE PSEUDO_JMP (__libc_enable_asynccancel) +# define CDISABLE PSEUDO_JMP (__libc_disable_asynccancel) +# define __local_multiple_threads __libc_multiple_threads +# elif defined IS_IN_librt +# define CENABLE PSEUDO_JMP (__librt_enable_asynccancel) +# define CDISABLE PSEUDO_JMP (__librt_disable_asynccancel) +# else +# error Unsupported library +# endif + +#define SINGLE_THREAD_P(reg) \ + lwi reg, r0, MULTIPLE_THREADS_OFFSET(reg) + +#else /* !__ASSEMBLER__ */ +# define SINGLE_THREAD_P \ + __builtin_expect (THREAD_GETMEM (THREAD_SELF, \ + header.multiple_threads) == 0, 1) + +#endif /* __ASSEMBLER__ */ + +#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/vfork.S new file mode 100644 index 0000000..4336717 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/microblaze/vfork.S @@ -0,0 +1,5 @@ +#define SAVE_PID +#define RESTORE_PID +#include +#include +#include