diff options
author | Waldemar Brodkorb <wbx@uclibc-ng.org> | 2016-10-31 18:05:44 +0100 |
---|---|---|
committer | Waldemar Brodkorb <wbx@uclibc-ng.org> | 2016-11-03 20:37:48 +0100 |
commit | 191739597c6d380692885cfdd8dd8aa4f31f029d (patch) | |
tree | b3f05ce72f7a87433905698dd58371048c904812 | |
parent | 7825930078208462655e107677656c45014e91b4 (diff) |
microblaze: add NPTL/TLS support from GNU libc
Not perfect, but a starting point.
Some tests of the test suite are failing.
33 files changed, 1394 insertions, 100 deletions
diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in index b25946461..cb2d4d1a2 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 17a6143b5..cca3d3832 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/microblaze/dl-debug.h b/ldso/ldso/microblaze/dl-debug.h index 6fd7bd59f..30b27bb2a 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 ba15a87c3..720c53aab 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 b293d27cc..43200271e 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 <http://www.gnu.org/licenses/>. */ -/* Use reloca */ #define ELF_USES_RELOCA #include <elf.h> - /* 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 1f6aeffb7..33aef2f3e 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 e23515ed0..b89f7f945 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 := +CSRC-y := __syscall_error.c SSRC-y := setjmp.S __longjmp.S vfork.S clone.S diff --git a/libc/sysdeps/linux/microblaze/__syscall_error.c b/libc/sysdeps/linux/microblaze/__syscall_error.c new file mode 100644 index 000000000..2b642e816 --- /dev/null +++ b/libc/sysdeps/linux/microblaze/__syscall_error.c @@ -0,0 +1,18 @@ +/* Wrapper for setting errno. + * + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#include <errno.h> +#include <features.h> + +/* This routine is jumped to by all the syscall handlers, to stash + * an error number into errno. */ +int __syscall_error(int err_no) attribute_hidden; +int __syscall_error(int err_no) +{ + __set_errno(-err_no); + return -1; +} diff --git a/libc/sysdeps/linux/microblaze/bits/uClibc_arch_features.h b/libc/sysdeps/linux/microblaze/bits/uClibc_arch_features.h index ea767abbf..321d699b0 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 index 46d4fe6b4..69c20453f 100644 --- a/libc/sysdeps/linux/microblaze/clone.S +++ b/libc/sysdeps/linux/microblaze/clone.S @@ -23,6 +23,10 @@ #define _ERRNO_H 1 #include <bits/errno.h> +#if defined __UCLIBC_HAS_THREADS__ && !defined __UCLIBC_HAS_LINUXTHREADS__ +#include <sysdep-cancel.h> +#endif + /* int clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg, pid_t *ptid, struct user_desc *tls, pid_t *ctid); @@ -39,8 +43,8 @@ .text ENTRY (__clone) addik r3,r0,-EINVAL - beqi r5,1f ; // Invalid func - beqi r6,1f ; // Invalid stack + 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 @@ -53,7 +57,7 @@ ENTRY (__clone) addk r0,r0,r0 addik r4,r0,-4095 cmpu r4,r4,r3 - bgei r4,1f + bgei r4,SYSCALL_ERROR_LABEL beqi r3,L(thread_start) rtsd r15,8 nop @@ -67,12 +71,7 @@ L(thread_start): addik r12,r0,SYS_ify(exit) brki r14,8 nop - -1: rsubk r3,r3,r0 - rtsd r15,8 - addik r3,r0,-1 /* delay slot. */ - -END(__clone) +PSEUDO_END(__clone) libc_hidden_def (__clone) weak_alias (__clone,clone) diff --git a/libc/sysdeps/linux/microblaze/jmpbuf-offsets.h b/libc/sysdeps/linux/microblaze/jmpbuf-offsets.h deleted file mode 100644 index c6cccc739..000000000 --- a/libc/sysdeps/linux/microblaze/jmpbuf-offsets.h +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> - * - * 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 2c1c0793c..155792b37 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 <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) \ + ((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 1f01a2a1d..a463d339e 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 + <http://www.gnu.org/licenses/>. */ + #include <common/sysdep.h> #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 cadd1167d..11b9e2758 100644 --- a/libc/sysdeps/linux/microblaze/vfork.S +++ b/libc/sysdeps/linux/microblaze/vfork.S @@ -1,42 +1,44 @@ -/* - * libc/sysdeps/linux/microblaze/vfork.S -- `vfork' syscall for linux/microblaze - * - * Copyright (C) 2003 John Williams <jwilliams@itee.uq.edu.au> - * Copyright (C) 2001 NEC Corporation - * Copyright (C) 2001 Miles Bader <miles@gnu.org> - * - * 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 <miles@gnu.org> - * Microblaze port by John Williams - */ - -#include <sys/syscall.h> +/* 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 + <http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> +#define _ERRNO_H 1 +#include <bits/errno.h> /* 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 */ +ENTRY(__vfork) + + DO_CALL (vfork, 0) + addik r12,r0,-4095 + cmpu r12,r12,r3 + bgei r12,1f + rtsd r15,8 + nop 1: rsubk r3,r3,r0 rtsd r15,8 addik r3,r0,-1 /* delay slot. */ -2: rtsd r15, 8 /* error return */ - nop - .size __vfork, .-__vfork +END(__vfork) weak_alias(__vfork, vfork) libc_hidden_def(vfork) diff --git a/libpthread/nptl/sysdeps/microblaze/Makefile.arch b/libpthread/nptl/sysdeps/microblaze/Makefile.arch new file mode 100644 index 000000000..b69fb48da --- /dev/null +++ b/libpthread/nptl/sysdeps/microblaze/Makefile.arch @@ -0,0 +1,4 @@ +# Makefile for uClibc NPTL +# 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/microblaze/dl-tls.h b/libpthread/nptl/sysdeps/microblaze/dl-tls.h new file mode 100644 index 000000000..5613e21e2 --- /dev/null +++ b/libpthread/nptl/sysdeps/microblaze/dl-tls.h @@ -0,0 +1,26 @@ +/* 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 + <http://www.gnu.org/licenses/>. */ + +/* 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/microblaze/libc-tls.c b/libpthread/nptl/sysdeps/microblaze/libc-tls.c new file mode 100644 index 000000000..7f440fb06 --- /dev/null +++ b/libpthread/nptl/sysdeps/microblaze/libc-tls.c @@ -0,0 +1,36 @@ +/* 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 + <http://www.gnu.org/licenses/>. */ + +#include <sysdeps/generic/libc-tls.c> +#include <dl-tls.h> + +/* 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) +{ + dtv_t *dtv = THREAD_DTV (); + return (char *) dtv[1].pointer.val + ti->ti_offset; +} + +#endif diff --git a/libpthread/nptl/sysdeps/microblaze/pthread_spin_lock.c b/libpthread/nptl/sysdeps/microblaze/pthread_spin_lock.c new file mode 100644 index 000000000..e393a73ac --- /dev/null +++ b/libpthread/nptl/sysdeps/microblaze/pthread_spin_lock.c @@ -0,0 +1,62 @@ +/* pthread_spin_lock -- lock a spin lock. Generic version. + Copyright (C) 2012-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 |