From patchwork Fri Apr 18 10:24:03 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chung-Lin Tang X-Patchwork-Id: 617 Return-Path: X-Original-To: siddhesh@wilcox.dreamhost.com Delivered-To: siddhesh@wilcox.dreamhost.com Received: from homiemail-mx22.g.dreamhost.com (mx2.sub5.homie.mail.dreamhost.com [208.113.200.128]) by wilcox.dreamhost.com (Postfix) with ESMTP id 8B85936007D for ; Fri, 18 Apr 2014 03:24:35 -0700 (PDT) Received: by homiemail-mx22.g.dreamhost.com (Postfix, from userid 14307373) id 484BD4FF51DB; Fri, 18 Apr 2014 03:24:35 -0700 (PDT) X-Original-To: glibc@patchwork.siddhesh.in Delivered-To: x14307373@homiemail-mx22.g.dreamhost.com Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by homiemail-mx22.g.dreamhost.com (Postfix) with ESMTPS id 033C84FF5134 for ; Fri, 18 Apr 2014 03:24:34 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:message-id:date:from:mime-version:to:cc :subject:content-type; q=dns; s=default; b=sLVVTa2dlvWfC6U1zCORp 3b28hPlIs0pxNH6jN9RIUL7/7Xi5uPOYpUek7UPj4z9fS4RrOI+Q4SJD4doH9QvD a+5Tyc5OOcOp2qB70TSnVZ0hmq98gcuoGDjyZxwwwoXLxiOZWhAG0CkBSs7hKRs1 Yi+sm/PmL7SN7XtWrpoY8Q= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:message-id:date:from:mime-version:to:cc :subject:content-type; s=default; bh=h66BnydPnS9dzrZA69lSpEJmxFc =; b=ledsruxRB+wzyQP2qxvi9GAWhdXKspi0IZ7WLsi/5sGypLuvaiC5SHnz12j Q7dxIEgCVm0RAxxL9zINZPv+C6isfWTvJJMqiitD3UvdU1jXQXbJgtctZMU/J0q7 505M2fcEBlrqbD3QDHc2dHx+EXquZ7LZhm/Dn7s0scu4nhkI= Received: (qmail 27114 invoked by alias); 18 Apr 2014 10:24:32 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 27095 invoked by uid 89); 18 Apr 2014 10:24:29 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.1 required=5.0 tests=AWL, BAYES_50 autolearn=ham version=3.3.2 X-HELO: relay1.mentorg.com Message-ID: <5350FD43.8000103@mentor.com> Date: Fri, 18 Apr 2014 18:24:03 +0800 From: Chung-Lin Tang User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:24.0) Gecko/20100101 Thunderbird/24.4.0 MIME-Version: 1.0 To: CC: "Joseph S. Myers" , Sandra Loosemore Subject: [PATCH v2 3/4] Nios II port submission, Linux specific parts X-DH-Original-To: glibc@patchwork.siddhesh.in Linux specific parts, updated after Joseph's review. Notes: (1) The pthread_once file is removed, to use the current generic one. (2) bits/atomic.h was first re-written to use __atomic_* builtins instead of legacy __sync_* builtins, but after some examination, found that best way (at least in terms of code size) is to simply use inline asm implementation. * sysdeps/unix/sysv/linux/nios2/Implies: New file. * sysdeps/unix/sysv/linux/nios2/Makefile: New file. * sysdeps/unix/sysv/linux/nios2/Versions: New file. * sysdeps/unix/sysv/linux/nios2/cacheflush.c: New file. * sysdeps/unix/sysv/linux/nios2/clone.S: New file. * sysdeps/unix/sysv/linux/nios2/configure: New file. * sysdeps/unix/sysv/linux/nios2/configure.in: New file. * sysdeps/unix/sysv/linux/nios2/getcontext.S: New file. * sysdeps/unix/sysv/linux/nios2/makecontext.c: New file. * sysdeps/unix/sysv/linux/nios2/setcontext.S: New file. * sysdeps/unix/sysv/linux/nios2/swapcontext.S: New file. * sysdeps/unix/sysv/linux/nios2/profil-counter.h: New file. * sysdeps/unix/sysv/linux/nios2/sigcontextinfo.h: New file. * sysdeps/unix/sysv/linux/nios2/kernel-features.h: New file. * sysdeps/unix/sysv/linux/nios2/kernel_rt_sigframe.h: New file. * sysdeps/unix/sysv/linux/nios2/syscall.S: New file. * sysdeps/unix/sysv/linux/nios2/sysdep.S: New file. * sysdeps/unix/sysv/linux/nios2/sysdep.h: New file. * sysdeps/unix/sysv/linux/nios2/ucontext_i.sym: New file. * sysdeps/unix/sysv/linux/nios2/bits/atomic.h: New file. * sysdeps/unix/sysv/linux/nios2/bits/mman.h: New file. * sysdeps/unix/sysv/linux/nios2/nptl/bits/pthreadtypes.h: New file. * sysdeps/unix/sysv/linux/nios2/nptl/bits/semaphore.h: New file. * sysdeps/unix/sysv/linux/nios2/nptl/clone.S: New file. * sysdeps/unix/sysv/linux/nios2/nptl/createthread.c: New file. * sysdeps/unix/sysv/linux/nios2/nptl/fork.c: New file. * sysdeps/unix/sysv/linux/nios2/nptl/lowlevellock.h: New file. * sysdeps/unix/sysv/linux/nios2/nptl/pt-vfork.S: New file. * sysdeps/unix/sysv/linux/nios2/nptl/sysdep-cancel.h: New file. * sysdeps/unix/sysv/linux/nios2/nptl/vfork.S: New file. * sysdeps/unix/sysv/linux/nios2/sys/cachectl.h: New file. * sysdeps/unix/sysv/linux/nios2/sys/procfs.h: New file. * sysdeps/unix/sysv/linux/nios2/sys/ucontext.h: New file. * sysdeps/unix/sysv/linux/nios2/sys/user.h: New file. diff --git a/sysdeps/unix/sysv/linux/nios2/Implies b/sysdeps/unix/sysv/linux/nios2/Implies new file mode 100644 index 0000000..e0fdaeb --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/Implies @@ -0,0 +1,2 @@ +unix/sysv/linux/generic/wordsize-32 +unix/sysv/linux/generic diff --git a/sysdeps/unix/sysv/linux/nios2/Makefile b/sysdeps/unix/sysv/linux/nios2/Makefile new file mode 100644 index 0000000..c22425f --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/Makefile @@ -0,0 +1,9 @@ +ifeq ($(subdir),stdlib) +gen-as-const-headers += ucontext_i.sym +endif + +ifeq ($(subdir),misc) +# MIPS/Tile-style cacheflush routine +sysdep_headers += sys/cachectl.h +sysdep_routines += cacheflush +endif diff --git a/sysdeps/unix/sysv/linux/nios2/Versions b/sysdeps/unix/sysv/linux/nios2/Versions new file mode 100644 index 0000000..54bd224 --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/Versions @@ -0,0 +1,6 @@ +libc { + GLIBC_2.20 { + _flush_cache; + cacheflush; + } +} diff --git a/sysdeps/unix/sysv/linux/nios2/bits/atomic.h b/sysdeps/unix/sysv/linux/nios2/bits/atomic.h new file mode 100644 index 0000000..61b5c77 --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/bits/atomic.h @@ -0,0 +1,89 @@ +/* Low-level functions for atomic operations. Nios II version. + Copyright (C) 2012-2014 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 _NIOS2_BITS_ATOMIC_H +#define _NIOS2_BITS_ATOMIC_H 1 + +#include + +typedef int32_t atomic32_t; +typedef uint32_t uatomic32_t; +typedef int_fast32_t atomic_fast32_t; +typedef uint_fast32_t uatomic_fast32_t; + +typedef intptr_t atomicptr_t; +typedef uintptr_t uatomicptr_t; +typedef intmax_t atomic_max_t; +typedef uintmax_t uatomic_max_t; + + +#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \ + (abort (), (__typeof (*mem)) 0) +#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \ + (abort (), (__typeof (*mem)) 0) +#define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \ + (abort (), (__typeof (*mem)) 0) + +#define __arch_compare_and_exchange_bool_8_acq(mem, newval, oldval) \ + (abort (), 0) +#define __arch_compare_and_exchange_bool_16_acq(mem, newval, oldval) \ + (abort (), 0) +#define __arch_compare_and_exchange_bool_64_acq(mem, newval, oldval) \ + (abort (), 0) + +#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \ + ({ \ + register int r2 asm ("r2"); \ + register int *r4 asm ("r4") = (mem); \ + register int r5 asm ("r5"); \ + register int r6 asm ("r6") = (newval); \ + long retval, orig_oldval = (oldval), kernel_cmpxchg = 0x1004; \ + while (1) \ + { \ + r5 = *r4; \ + if (r5 != orig_oldval) \ + { \ + retval = r5; \ + break; \ + } \ + asm volatile ("callr %1\n" \ + : "=r" (r2) \ + : "r" (kernel_cmpxchg), "r" (r4), "r" (r5), "r" (r6) \ + : "ra", "memory"); \ + if (!r2) { retval = orig_oldval; break; } \ + } \ + retval; \ + }) + +#define __arch_compare_and_exchange_bool_32_acq(mem, newval, oldval) \ + ({ \ + register int r2 asm ("r2"); \ + register int *r4 asm ("r4") = (mem); \ + register int r5 asm ("r5") = (oldval); \ + register int r6 asm ("r6") = (newval); \ + long kernel_cmpxchg = 0x1004; \ + asm volatile ("callr %1\n" \ + : "=r" (r2) \ + : "r" (kernel_cmpxchg), "r" (r4), "r" (r5), "r" (r6) \ + : "ra", "memory"); \ + r2; \ + }) + +#define atomic_full_barrier() ({ asm volatile ("sync"); }) + +#endif /* _NIOS2_BITS_ATOMIC_H */ diff --git a/sysdeps/unix/sysv/linux/nios2/bits/mman.h b/sysdeps/unix/sysv/linux/nios2/bits/mman.h new file mode 100644 index 0000000..562e34e --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/bits/mman.h @@ -0,0 +1,42 @@ +/* Definitions for POSIX memory map interface. Linux/Nios II version. + + Copyright (C) 1997-2014 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 _SYS_MMAN_H +# error "Never use directly; include instead." +#endif + +/* The following definitions basically come from the kernel headers. + But the kernel header is not namespace clean. */ + +/* These are Linux-specific. */ +#ifdef __USE_MISC +# define MAP_GROWSDOWN 0x00100 /* Stack-like segment. */ +# define MAP_DENYWRITE 0x00800 /* ETXTBSY */ +# define MAP_EXECUTABLE 0x01000 /* Mark it as an executable. */ +# define MAP_LOCKED 0x02000 /* Lock the mapping. */ +# define MAP_NORESERVE 0x04000 /* Don't check for reservations. */ +# define MAP_POPULATE 0x08000 /* Populate (prefault) pagetables. */ +# define MAP_NONBLOCK 0x10000 /* Do not block on IO. */ +# define MAP_STACK 0x20000 /* Allocation is for a stack. */ +# define MAP_HUGETLB 0x40000 /* Create huge page mapping. */ +#endif + +/* Include generic Linux declarations. */ +#include diff --git a/sysdeps/unix/sysv/linux/nios2/cacheflush.c b/sysdeps/unix/sysv/linux/nios2/cacheflush.c new file mode 100644 index 0000000..b92a507 --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/cacheflush.c @@ -0,0 +1,28 @@ +/* Copyright (C) 2014 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 +#include + +/* Flush cache(s). */ +int +_flush_cache (char *addr, const int nbytes, const int op) +{ + return INLINE_SYSCALL (cacheflush, 3, addr, nbytes, op); +} +weak_alias (_flush_cache, cacheflush) diff --git a/sysdeps/unix/sysv/linux/nios2/clone.S b/sysdeps/unix/sysv/linux/nios2/clone.S new file mode 100644 index 0000000..16d4438 --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/clone.S @@ -0,0 +1,107 @@ +/* Copyright (C) 2008-2014 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andrew Jenner , 2008. + + 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 +#include + +#define CLONE_VM 0x00000100 +#define CLONE_THREAD 0x00010000 + +/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, + void *parent_tidptr, void *tls, void *child_tidptr) */ + + .text +ENTRY(__clone) + /* Sanity check arguments. */ + movi r2, EINVAL + /* No NULL function pointers. */ + beq r4, zero, SYSCALL_ERROR_LABEL + /* No NULL stack pointers. */ + beq r5, zero, SYSCALL_ERROR_LABEL + + subi r5, r5, 8 /* Reserve argument save space. */ + stw r4, 4(r5) /* Save function pointer. */ + stw r7, 0(r5) /* Save argument pointer. */ + + /* Load arguments. */ + mov r4, r6 + ldw r6, 0(sp) + ldw r7, 8(sp) + ldw r8, 4(sp) + + /* Do the system call. */ + movi r2, SYS_ify (clone) + + /* End FDE now, because in the child the unwind info will be + wrong. */ + cfi_endproc + trap + + /* Check for errors. */ + bne r7, zero, SYSCALL_ERROR_LABEL + /* See if we're on the newly created thread. */ + beq r2, zero, thread_start + /* Successful return from the parent */ + ret + +thread_start: + cfi_startproc + cfi_undefined (ra) +#ifdef RESET_PID + /* We expect the argument registers to be preserved across system + calls and across task cloning, so flags should be in r4 here. */ + andi r2, r4, CLONE_THREAD + bne r2, zero, 2f + andi r3, r4, CLONE_VM + movi r2, -1 + bne r3, zero, 3f + DO_CALL (getpid, 0) +3: + stw r2, PID_OFFSET(r23) + stw r2, TID_OFFSET(r23) +2: +#endif + ldw r5, 4(sp) /* Function pointer. */ + ldw r4, 0(sp) /* Argument pointer. */ + addi sp, sp, 8 + + /* Call the user's function. */ + callr r5 + + /* _exit with the result. */ + mov r4, r2 +#ifdef PIC + nextpc r22 +1: movhi r8, %hiadj(_gp_got - 1b) + addi r8, r8, %lo(_gp_got - 1b) + add r22, r22, r8 + ldw r8, %call(HIDDEN_JUMPTARGET(_exit))(r22) + jmp r8 +#else + jmpi _exit +#endif + cfi_endproc + + cfi_startproc +PSEUDO_END (__clone) +weak_alias (__clone, clone) diff --git a/sysdeps/unix/sysv/linux/nios2/configure b/sysdeps/unix/sysv/linux/nios2/configure new file mode 100644 index 0000000..371f85a --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/configure @@ -0,0 +1,4 @@ +# This file is generated from configure.in by Autoconf. DO NOT EDIT! + # Local configure fragment for sysdeps/unix/sysv/linux/nios2. + +arch_minimum_kernel=10.0.0 diff --git a/sysdeps/unix/sysv/linux/nios2/configure.ac b/sysdeps/unix/sysv/linux/nios2/configure.ac new file mode 100644 index 0000000..337618f --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/configure.ac @@ -0,0 +1,4 @@ +GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. +# Local configure fragment for sysdeps/unix/sysv/linux/nios2. + +arch_minimum_kernel=10.0.0 diff --git a/sysdeps/unix/sysv/linux/nios2/getcontext.S b/sysdeps/unix/sysv/linux/nios2/getcontext.S new file mode 100644 index 0000000..fed7e6f --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/getcontext.S @@ -0,0 +1,65 @@ +/* Copyright (C) 2014 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 "ucontext_i.h" + +/* int getcontext (ucontext_t *ucp) + + Returns 0 on success -1 and errno on failure. + */ + .text +ENTRY(__getcontext) + stw r16, (UCONTEXT_MCONTEXT + 16*4)(r4) + stw r17, (UCONTEXT_MCONTEXT + 17*4)(r4) + stw r18, (UCONTEXT_MCONTEXT + 18*4)(r4) + stw r19, (UCONTEXT_MCONTEXT + 19*4)(r4) + stw r20, (UCONTEXT_MCONTEXT + 20*4)(r4) + stw r21, (UCONTEXT_MCONTEXT + 21*4)(r4) + stw r22, (UCONTEXT_MCONTEXT + 22*4)(r4) + stw ra, (UCONTEXT_MCONTEXT + 24*4)(r4) + stw fp, (UCONTEXT_MCONTEXT + 25*4)(r4) + stw gp, (UCONTEXT_MCONTEXT + 26*4)(r4) + /* Store return address at place for EA. */ + stw ra, (UCONTEXT_MCONTEXT + 28*4)(r4) + stw sp, (UCONTEXT_MCONTEXT + 29*4)(r4) + /* Store zero for return success. */ + stw zero, (UCONTEXT_MCONTEXT + 2*4)(r4) + + /* Store value "1" at uc_flags to recognize as getcontext created. */ + movi r2, 1 + stw r2, UCONTEXT_FLAGS(r4) + + /* Store MCONTEXT_VERSION at first word of mcontext_t. */ + movi r2, MCONTEXT_VERSION + stw r2, UCONTEXT_MCONTEXT(r4) + + /* Get signal mask. */ + /* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */ + movi r7, _NSIG8 + addi r6, r4, UCONTEXT_SIGMASK + mov r5, zero + movi r4, SIG_BLOCK + movi r2, SYS_ify (rt_sigprocmask) + trap + bne r7, zero, SYSCALL_ERROR_LABEL + + mov r2, zero + ret + +PSEUDO_END(__getcontext) +weak_alias(__getcontext, getcontext) diff --git a/sysdeps/unix/sysv/linux/nios2/kernel-features.h b/sysdeps/unix/sysv/linux/nios2/kernel-features.h new file mode 100644 index 0000000..004de24 --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/kernel-features.h @@ -0,0 +1,38 @@ +/* Set flags signalling availability of kernel features based on given + kernel version number. + + Copyright (C) 2009-2014 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 + +/* The minimum supported kernel version for Nios II is 3.15.0, + guaranteeing many kernel features. */ + +#define __ASSUME_ACCEPT4_SYSCALL 1 +#define __ASSUME_DUP3 1 +#define __ASSUME_EVENTFD2 1 +#define __ASSUME_IN_NONBLOCK 1 +#define __ASSUME_O_CLOEXEC 1 +#define __ASSUME_PIPE2 1 +#define __ASSUME_RECVMMSG_SYSCALL 1 +#define __ASSUME_SENDMMSG_SYSCALL 1 +#define __ASSUME_SIGNALFD4 1 +#define __ASSUME_SOCK_CLOEXEC 1 + +#include_next diff --git a/sysdeps/unix/sysv/linux/nios2/kernel_rt_sigframe.h b/sysdeps/unix/sysv/linux/nios2/kernel_rt_sigframe.h new file mode 100644 index 0000000..c47ac9f --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/kernel_rt_sigframe.h @@ -0,0 +1,26 @@ +/* Copyright (C) 2014 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 + . */ + +/* This structure must have the same shape as the linux kernel + equivalent. */ + +struct kernel_rt_sigframe +{ + char retcode[12]; + siginfo_t info; + struct ucontext uc; +}; diff --git a/sysdeps/unix/sysv/linux/nios2/makecontext.c b/sysdeps/unix/sysv/linux/nios2/makecontext.c new file mode 100644 index 0000000..b66a4e9 --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/makecontext.c @@ -0,0 +1,78 @@ +/* Copyright (C) 2014 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 +#include +#include + +/* makecontext sets up a stack and the registers for the + user context. The stack looks like this: + + +-----------------------+ + | padding as required | + +-----------------------+ + sp -> | parameters 5 to n | + +-----------------------+ + + The registers are set up like this: + r4--r7 : parameter 1 to 4 + r16 : uc_link + sp : stack pointer. +*/ + +void +__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...) +{ + extern void __startcontext (void); + unsigned long *sp; + va_list ap; + int i; + + sp = (unsigned long *) + ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size); + + /* Allocate stack arguments. */ + sp -= argc < 4 ? 0 : argc - 4; + + /* Keep the stack aligned. */ + sp = (unsigned long*) (((uintptr_t) sp) & -4L); + + /* Init version field. */ + ucp->uc_mcontext.version = 2; + /* Keep uc_link in r16. */ + ucp->uc_mcontext.regs[15] = (uintptr_t) ucp->uc_link; + /* Return address points to __startcontext(). */ + ucp->uc_mcontext.regs[23] = (uintptr_t) &__startcontext; + /* Frame pointer is null. */ + ucp->uc_mcontext.regs[24] = (uintptr_t) 0; + /* Restart in user-space starting at 'func'. */ + ucp->uc_mcontext.regs[27] = (uintptr_t) func; + /* Set stack pointer. */ + ucp->uc_mcontext.regs[28] = (uintptr_t) sp; + + va_start (ap, argc); + for (i = 0; i < argc; ++i) + if (i < 4) + ucp->uc_mcontext.regs[i + 3] = va_arg (ap, unsigned long); + else + sp[i - 4] = va_arg (ap, unsigned long); + + va_end (ap); +} + +weak_alias (__makecontext, makecontext) diff --git a/sysdeps/unix/sysv/linux/nios2/nptl/bits/pthreadtypes.h b/sysdeps/unix/sysv/linux/nios2/nptl/bits/pthreadtypes.h new file mode 100644 index 0000000..cb756ed --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/nptl/bits/pthreadtypes.h @@ -0,0 +1,184 @@ +/* Copyright (C) 2012-2014 Free Software Foundation, Inc. Nios II version. + 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 _BITS_PTHREADTYPES_H +#define _BITS_PTHREADTYPES_H 1 + +#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_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 + deliberately not exposed. */ +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 + + +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 deliberately not exposed. */ +typedef union +{ + struct __pthread_mutex_s + { + int __lock; + unsigned int __count; + int __owner; + /* KIND must stay at this position in the structure to maintain + binary compatibility. */ + int __kind; + unsigned int __nusers; + __extension__ union + { + int __spins; + __pthread_slist_t __list; + }; + } __data; + char __size[__SIZEOF_PTHREAD_MUTEX_T]; + long int __align; +} pthread_mutex_t; + +typedef union +{ + char __size[__SIZEOF_PTHREAD_MUTEXATTR_T]; + long int __align; +} pthread_mutexattr_t; + +/* Mutex __spins initializer used by PTHREAD_MUTEX_INITIALIZER. */ +#define __PTHREAD_SPINS 0 + + +/* Data structure for conditional variable handling. The structure of + the attribute type is deliberately not exposed. */ +typedef union +{ + struct + { + int __lock; + unsigned int __futex; + __extension__ unsigned long long int __total_seq; + __extension__ unsigned long long int __wakeup_seq; + __extension__ unsigned long long int __woken_seq; + void *__mutex; + unsigned int __nwaiters; + unsigned int __broadcast_seq; + } __data; + char __size[__SIZEOF_PTHREAD_COND_T]; + __extension__ long long int __align; +} pthread_cond_t; + +typedef union +{ + char __size[__SIZEOF_PTHREAD_CONDATTR_T]; + long int __align; +} pthread_condattr_t; + + +/* Keys for thread-specific data */ +typedef unsigned int pthread_key_t; + + +/* Once-only execution */ +typedef int pthread_once_t; + + +#if defined __USE_UNIX98 || defined __USE_XOPEN2K +/* Data structure for read-write lock variable handling. The + structure of the attribute type is deliberately not exposed. */ +typedef union +{ + struct + { + int __lock; + unsigned int __nr_readers; + unsigned int __readers_wakeup; + unsigned int __writer_wakeup; + unsigned int __nr_readers_queued; + unsigned int __nr_writers_queued; +#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 + /* 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 + int __writer; + } __data; + char __size[__SIZEOF_PTHREAD_RWLOCK_T]; + long int __align; +} pthread_rwlock_t; + +typedef union +{ + char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T]; + long int __align; +} pthread_rwlockattr_t; +#endif + + +#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 +{ + char __size[__SIZEOF_PTHREAD_BARRIER_T]; + long int __align; +} pthread_barrier_t; + +typedef union +{ + char __size[__SIZEOF_PTHREAD_BARRIERATTR_T]; + int __align; +} pthread_barrierattr_t; +#endif + + +#endif /* bits/pthreadtypes.h */ diff --git a/sysdeps/unix/sysv/linux/nios2/nptl/bits/semaphore.h b/sysdeps/unix/sysv/linux/nios2/nptl/bits/semaphore.h new file mode 100644 index 0000000..6b1ac0f --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/nptl/bits/semaphore.h @@ -0,0 +1,34 @@ +/* Copyright (C) 2002-2014 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 _SEMAPHORE_H +# error "Never use directly; include instead." +#endif + +#define __SIZEOF_SEM_T 16 + +/* Value returned if `sem_open' failed. */ +#define SEM_FAILED ((sem_t *) 0) + +/* Maximum value the semaphore can have. */ +#define SEM_VALUE_MAX ((int) ((~0u) >> 1)) + +typedef union +{ + char __size[__SIZEOF_SEM_T]; + long int __align; +} sem_t; diff --git a/sysdeps/unix/sysv/linux/nios2/nptl/clone.S b/sysdeps/unix/sysv/linux/nios2/nptl/clone.S new file mode 100644 index 0000000..8dbe797 --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/nptl/clone.S @@ -0,0 +1,2 @@ +#define RESET_PID +#include diff --git a/sysdeps/unix/sysv/linux/nios2/nptl/createthread.c b/sysdeps/unix/sysv/linux/nios2/nptl/createthread.c new file mode 100644 index 0000000..becfd97 --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/nptl/createthread.c @@ -0,0 +1,23 @@ +/* Copyright (C) 2005-2014 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 + . */ + +/* Value passed to 'clone' for initialization of the thread register. */ +#define TLS_VALUE ((void *) (pd) \ + + TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE) + +/* Get the real implementation. */ +#include diff --git a/sysdeps/unix/sysv/linux/nios2/nptl/fork.c b/sysdeps/unix/sysv/linux/nios2/nptl/fork.c new file mode 100644 index 0000000..3536800 --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/nptl/fork.c @@ -0,0 +1,34 @@ +/* Copyright (C) 2005-2014 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 +#include +#include + +/* Argument 1 - Clone flags. + 2 - Child stack pointer. + 3 - Parent tid pointer. + 4 - Child tid pointer. + 5 - New TLS area pointer. */ + +#define ARCH_FORK() \ + INLINE_SYSCALL (clone, 5, \ + CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, \ + NULL, NULL, &THREAD_SELF->tid, NULL) + +#include diff --git a/sysdeps/unix/sysv/linux/nios2/nptl/lowlevellock.h b/sysdeps/unix/sysv/linux/nios2/nptl/lowlevellock.h new file mode 100644 index 0000000..4cb62f5 --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/nptl/lowlevellock.h @@ -0,0 +1,326 @@ +/* Copyright (C) 2003-2014 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 _LOWLEVELLOCK_H +#define _LOWLEVELLOCK_H 1 + +#include +#include +#include +#include +#include +#include + +#define FUTEX_WAIT 0 +#define FUTEX_WAKE 1 +#define FUTEX_REQUEUE 3 +#define FUTEX_CMP_REQUEUE 4 +#define FUTEX_WAKE_OP 5 +#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE ((4 << 24) | 1) +#define FUTEX_LOCK_PI 6 +#define FUTEX_UNLOCK_PI 7 +#define FUTEX_TRYLOCK_PI 8 +#define FUTEX_WAIT_BITSET 9 +#define FUTEX_WAKE_BITSET 10 +#define FUTEX_WAIT_REQUEUE_PI 11 +#define FUTEX_CMP_REQUEUE_PI 12 +#define FUTEX_PRIVATE_FLAG 128 +#define FUTEX_CLOCK_REALTIME 256 + +#define FUTEX_BITSET_MATCH_ANY 0xffffffff + +/* Values for 'private' parameter of locking macros. Yes, the + definition seems to be backwards. But it is not. The bit will be + reversed before passing to the system call. */ +#define LLL_PRIVATE 0 +#define LLL_SHARED FUTEX_PRIVATE_FLAG + + +#if !defined NOT_IN_libc || defined IS_IN_rtld +/* In libc.so or ld.so all futexes are private. */ +# ifdef __ASSUME_PRIVATE_FUTEX +# define __lll_private_flag(fl, private) \ + ((fl) | FUTEX_PRIVATE_FLAG) +# else +# define __lll_private_flag(fl, private) \ + ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) +# endif +#else +# ifdef __ASSUME_PRIVATE_FUTEX +# define __lll_private_flag(fl, private) \ + (((fl) | FUTEX_PRIVATE_FLAG) ^ (private)) +# else +# define __lll_private_flag(fl, private) \ + (__builtin_constant_p (private) \ + ? ((private) == 0 \ + ? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) \ + : (fl)) \ + : ((fl) | (((private) ^ FUTEX_PRIVATE_FLAG) \ + & THREAD_GETMEM (THREAD_SELF, header.private_futex)))) +# endif +#endif + + +#define lll_futex_wait(futexp, val, private) \ + lll_futex_timed_wait(futexp, val, NULL, private) + +#define lll_futex_timed_wait(futexp, val, timespec, private) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \ + __lll_private_flag (FUTEX_WAIT, private), \ + (val), (timespec)); \ + INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \ + }) + +#define lll_futex_timed_wait_bitset(futexp, val, timespec, clockbit, private) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + int __op = FUTEX_WAIT_BITSET | clockbit; \ + __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \ + __lll_private_flag (__op, private), \ + (val), (timespec), NULL /* Unused. */, \ + FUTEX_BITSET_MATCH_ANY); \ + INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \ + }) + +#define lll_futex_wake(futexp, nr, private) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \ + __lll_private_flag (FUTEX_WAKE, private), \ + (nr), 0); \ + INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \ + }) + +#define lll_robust_dead(futexv, private) \ + do \ + { \ + int *__futexp = &(futexv); \ + atomic_or (__futexp, FUTEX_OWNER_DIED); \ + lll_futex_wake (__futexp, 1, private); \ + } \ + while (0) + +/* Returns non-zero if error happened, zero if success. */ +#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), \ + __lll_private_flag (FUTEX_CMP_REQUEUE, private),\ + (nr_wake), (nr_move), (mutex), (val)); \ + INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \ + }) + +/* Returns non-zero if error happened, zero if success. */ +#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), \ + __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) ? -__ret : __ret; \ + }) + +/* Priority Inheritance support. */ +#define lll_futex_wait_requeue_pi(futexp, val, mutex, private) \ + lll_futex_timed_wait_requeue_pi (futexp, val, NULL, 0, mutex, private) + +#define lll_futex_timed_wait_requeue_pi(futexp, val, timespec, clockbit, \ + mutex, private) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + int __op = FUTEX_WAIT_REQUEUE_PI | clockbit; \ + \ + __ret = INTERNAL_SYSCALL (futex, __err, 5, (futexp), \ + __lll_private_flag (__op, private), \ + (val), (timespec), mutex); \ + INTERNAL_SYSCALL_ERROR_P (__ret, __err); \ + }) + +#define lll_futex_cmp_requeue_pi(futexp, nr_wake, nr_move, mutex, val, priv) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + \ + __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \ + __lll_private_flag (FUTEX_CMP_REQUEUE_PI, priv),\ + (nr_wake), (nr_move), (mutex), (val)); \ + INTERNAL_SYSCALL_ERROR_P (__ret, __err); \ + }) + + +#define lll_trylock(lock) \ + atomic_compare_and_exchange_val_acq(&(lock), 1, 0) + +#define lll_cond_trylock(lock) \ + atomic_compare_and_exchange_val_acq(&(lock), 2, 0) + +static inline int __attribute__((always_inline)) +__lll_robust_trylock(int *futex, int id) +{ + return atomic_compare_and_exchange_val_acq (futex, id, 0) != 0; +} +#define lll_robust_trylock(lock, id) \ + __lll_robust_trylock (&(lock), id) + +extern void __lll_lock_wait_private (int *futex) attribute_hidden; +extern void __lll_lock_wait (int *futex, int private) attribute_hidden; +extern int __lll_robust_lock_wait (int *futex, int private) attribute_hidden; + +#define __lll_lock(futex, private) \ + ((void) ({ \ + int *__futex = (futex); \ + if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex, \ + 1, 0), 0)) \ + { \ + if (__builtin_constant_p (private) && (private) == LLL_PRIVATE) \ + __lll_lock_wait_private (__futex); \ + else \ + __lll_lock_wait (__futex, private); \ + } \ + })) +#define lll_lock(futex, private) __lll_lock (&(futex), private) + + +#define __lll_robust_lock(futex, id, private) \ + ({ \ + int *__futex = (futex); \ + int __val = 0; \ + \ + if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex, id, \ + 0), 0)) \ + __val = __lll_robust_lock_wait (__futex, private); \ + __val; \ + }) +#define lll_robust_lock(futex, id, private) \ + __lll_robust_lock (&(futex), id, private) + + +static inline void __attribute__ ((always_inline)) +__lll_cond_lock (int *futex, int private) +{ + if (atomic_compare_and_exchange_bool_acq (futex, 2, 0) != 0) + __lll_lock_wait (futex, private); +} +#define lll_cond_lock(futex, private) __lll_cond_lock (&(futex), private) + + +#define lll_robust_cond_lock(futex, id, private) \ + __lll_robust_lock (&(futex), (id) | FUTEX_WAITERS, private) + + +extern int __lll_timedlock_wait (int *futex, const struct timespec *, + int private) attribute_hidden; +extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *, + int private) attribute_hidden; + +static inline int __attribute__ ((always_inline)) +__lll_timedlock (int *futex, const struct timespec *abstime, int private) +{ + int result = 0; + if (atomic_compare_and_exchange_bool_acq (futex, 1, 0) != 0) + result = __lll_timedlock_wait (futex, abstime, private); + return result; +} +#define lll_timedlock(futex, abstime, private) \ + __lll_timedlock (&(futex), abstime, private) + + +static inline int __attribute__ ((always_inline)) +__lll_robust_timedlock (int *futex, const struct timespec *abstime, + int id, int private) +{ + int result = 0; + if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0) + result = __lll_robust_timedlock_wait (futex, abstime, private); + return result; +} +#define lll_robust_timedlock(futex, abstime, id, private) \ + __lll_robust_timedlock (&(futex), abstime, id, private) + + +#define __lll_unlock(futex, private) \ + ((void) ({ \ + int *__futex = (futex); \ + int __val = atomic_exchange_rel (__futex, 0); \ + \ + if (__builtin_expect (__val > 1, 0)) \ + lll_futex_wake (__futex, 1, private); \ + })) +#define lll_unlock(futex, private) __lll_unlock(&(futex), private) + + +#define __lll_robust_unlock(futex, private) \ + ((void) ({ \ + int *__futex = (futex); \ + int __val = atomic_exchange_rel (__futex, 0); \ + \ + if (__builtin_expect (__val & FUTEX_WAITERS, 0)) \ + lll_futex_wake (__futex, 1, private); \ + })) +#define lll_robust_unlock(futex, private) \ + __lll_robust_unlock(&(futex), private) + + +#define lll_islocked(futex) \ + (futex != 0) + + +/* Our internal lock implementation is identical to the binary-compatible + mutex implementation. */ + +/* Initializers for lock. */ +#define LLL_LOCK_INITIALIZER (0) +#define LLL_LOCK_INITIALIZER_LOCKED (1) + +/* The states of a lock are: + 0 - untaken + 1 - taken by one user + >1 - taken by more users */ + +/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex + wakeup when the clone terminates. The memory location contains the + thread ID while the clone is running and is reset to zero + afterwards. */ +#define lll_wait_tid(tid) \ + do { \ + __typeof (tid) __tid; \ + while ((__tid = (tid)) != 0) \ + lll_futex_wait (&(tid), __tid, LLL_SHARED); \ + } while (0) + +extern int __lll_timedwait_tid (int *, const struct timespec *) + attribute_hidden; + +#define lll_timedwait_tid(tid, abstime) \ + ({ \ + int __res = 0; \ + if ((tid) != 0) \ + __res = __lll_timedwait_tid (&(tid), (abstime)); \ + __res; \ + }) + +#endif /* lowlevellock.h */ diff --git a/sysdeps/unix/sysv/linux/nios2/nptl/pt-vfork.S b/sysdeps/unix/sysv/linux/nios2/nptl/pt-vfork.S new file mode 100644 index 0000000..0ccab87 --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/nptl/pt-vfork.S @@ -0,0 +1,40 @@ +/* Copyright (C) 2005-2014 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 + +ENTRY (__vfork) + + ldw r6, PID_OFFSET(r23) + sub r7, zero, r6 + stw r7, PID_OFFSET(r23) + + movi r4, 0x4111 /* (CLONE_VM | CLONE_VFORK | SIGCHLD) */ + mov r5, zero + DO_CALL (clone, 2) + + beq r2, zero, 1f + stw r6, PID_OFFSET(r23) +1: + bne r7, zero, SYSCALL_ERROR_LABEL + ret + +PSEUDO_END (__vfork) +libc_hidden_def (__vfork) + +weak_alias (__vfork, vfork) diff --git a/sysdeps/unix/sysv/linux/nios2/nptl/sysdep-cancel.h b/sysdeps/unix/sysv/linux/nios2/nptl/sysdep-cancel.h new file mode 100644 index 0000000..c2e5a80 --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/nptl/sysdep-cancel.h @@ -0,0 +1,138 @@ +/* Copyright (C) 2003-2014 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 + +# undef PSEUDO +# define PSEUDO(name, syscall_name, args) \ + .type __##syscall_name##_nocancel, @function; \ + .globl __##syscall_name##_nocancel; \ + __##syscall_name##_nocancel: \ + cfi_startproc; \ + DO_CALL (syscall_name, args); \ + bne r7, zero, SYSCALL_ERROR_LABEL; \ + ret; \ + cfi_endproc; \ + .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \ + ENTRY (name) \ + SINGLE_THREAD_P(r2); \ + bne r2, zero, pseudo_cancel; \ + DO_CALL (syscall_name, args); \ + bne r7, zero, SYSCALL_ERROR_LABEL; \ + ret; \ + pseudo_cancel: \ + SAVESTK_##args; /* save syscall args and adjust stack */ \ + SAVEREG(ra, 0); /* save return address */ \ + SAVEREG(r22, 4); /* save GOT pointer */ \ + nextpc r22; \ +1: movhi r2, %hiadj(_gp_got - 1b); \ + addi r2, r2, %lo(_gp_got - 1b); \ + add r22, r22, r2; \ + CENABLE; \ + callr r3; \ + stw r2, 8(sp); /* save mask */ \ + LOADARGS_##args; \ + movi r2, SYS_ify(syscall_name); \ + trap; \ + stw r2, 12(sp); /* save syscall result */ \ + stw r7, 16(sp); /* save syscall error flag */ \ + ldw r4, 8(sp); /* pass mask as argument 1 */ \ + CDISABLE; \ + callr r3; \ + ldw r7, 16(sp); /* restore syscall error flag */ \ + ldw r2, 12(sp); /* restore syscall result */ \ + ldw ra, 0(sp); /* restore return address */ \ + ldw r22, 4(sp); /* restore GOT pointer */ \ + RESTORESTK_##args; \ + bne r7, zero, SYSCALL_ERROR_LABEL; + + +# undef PSEUDO_END +# define PSEUDO_END(sym) \ + SYSCALL_ERROR_HANDLER \ + END (sym) + +#define SAVEREG(REG, LOC) stw REG, LOC(sp); cfi_rel_offset (REG, LOC) +#define SAVESTK(X) subi sp, sp, X; cfi_adjust_cfa_offset(X) +#define SAVESTK_0 SAVESTK(20) +#define SAVEARG_1 SAVEREG(r4, 20) +#define SAVESTK_1 SAVESTK(24); SAVEARG_1 +#define SAVEARG_2 SAVEREG(r5, 24); SAVEARG_1 +#define SAVESTK_2 SAVESTK(28); SAVEARG_2 +#define SAVEARG_3 SAVEREG(r6, 28); SAVEARG_2 +#define SAVESTK_3 SAVESTK(32); SAVEARG_3 +#define SAVEARG_4 SAVEREG(r7, 32); SAVEARG_3 +#define SAVESTK_4 SAVESTK(36); SAVEARG_4 +#define SAVESTK_5 SAVESTK_4 +#define SAVESTK_6 SAVESTK_5 + +#define LOADARGS_0 +#define LOADARGS_1 ldw r4, 20(sp) +#define LOADARGS_2 LOADARGS_1; ldw r5, 24(sp) +#define LOADARGS_3 LOADARGS_2; ldw r6, 28(sp) +#define LOADARGS_4 LOADARGS_3; ldw r7, 32(sp) +#define LOADARGS_5 LOADARGS_4; ldw r8, 36(sp) +#define LOADARGS_6 LOADARGS_5; ldw r9, 40(sp) + +#define RESTORESTK(X) addi sp, sp, X; cfi_adjust_cfa_offset(-X) +#define RESTORESTK_0 RESTORESTK(20) +#define RESTORESTK_1 RESTORESTK(24) +#define RESTORESTK_2 RESTORESTK(28) +#define RESTORESTK_3 RESTORESTK(32) +#define RESTORESTK_4 RESTORESTK(36) +#define RESTORESTK_5 RESTORESTK(36) +#define RESTORESTK_6 RESTORESTK(36) + +# ifdef IS_IN_libpthread +# define CENABLE ldw r3, %call(__pthread_enable_asynccancel)(r22) +# define CDISABLE ldw r3, %call(__pthread_disable_asynccancel)(r22) +# elif defined IS_IN_librt +# define CENABLE ldw r3, %call(__librt_enable_asynccancel)(r22) +# define CDISABLE ldw r3, %call(__librt_disable_asynccancel)(r22) +# else +# define CENABLE ldw r3, %call(__libc_enable_asynccancel)(r22) +# define CDISABLE ldw r3, %call(__libc_disable_asynccancel)(r22) +# endif + +# ifndef __ASSEMBLER__ +# define SINGLE_THREAD_P \ + __builtin_expect (THREAD_GETMEM (THREAD_SELF, \ + header.multiple_threads) \ + == 0, 1) +# else +# define SINGLE_THREAD_P(reg) \ + ldw reg, MULTIPLE_THREADS_OFFSET(r23) +#endif + +#elif !defined __ASSEMBLER__ + +# define SINGLE_THREAD_P 1 +# define NO_CANCELLATION 1 + +#endif + +#ifndef __ASSEMBLER__ +# define RTLD_SINGLE_THREAD_P \ + __builtin_expect (THREAD_GETMEM (THREAD_SELF, \ + header.multiple_threads) == 0, 1) +#endif diff --git a/sysdeps/unix/sysv/linux/nios2/nptl/vfork.S b/sysdeps/unix/sysv/linux/nios2/nptl/vfork.S new file mode 100644 index 0000000..59b983f --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/nptl/vfork.S @@ -0,0 +1,43 @@ +/* Copyright (C) 2005-2014 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 + +ENTRY(__vfork) + + ldw r6, PID_OFFSET(r23) + sub r7, zero, r6 + bne r7, zero, 2f + movhi r7, %hi(0x80000000) +2: + stw r7, PID_OFFSET(r23) + + movi r4, 0x4111 /* (CLONE_VM | CLONE_VFORK | SIGCHLD) */ + mov r5, zero + DO_CALL (clone, 2) + + beq r2, zero, 1f + stw r6, PID_OFFSET(r23) +1: + bne r7, zero, SYSCALL_ERROR_LABEL + ret + +PSEUDO_END (__vfork) +libc_hidden_def (__vfork) + +weak_alias (__vfork, vfork) diff --git a/sysdeps/unix/sysv/linux/nios2/profil-counter.h b/sysdeps/unix/sysv/linux/nios2/profil-counter.h new file mode 100644 index 0000000..8a6a0bc --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/profil-counter.h @@ -0,0 +1,2 @@ +/* We can use the ix86 version. */ +#include diff --git a/sysdeps/unix/sysv/linux/nios2/setcontext.S b/sysdeps/unix/sysv/linux/nios2/setcontext.S new file mode 100644 index 0000000..60913cc --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/setcontext.S @@ -0,0 +1,102 @@ +/* Copyright (C) 2014 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 "ucontext_i.h" + +/* int setcontext (const ucontext_t *ucp) */ + .text +ENTRY(__setcontext) + ldw r5, UCONTEXT_FLAGS(r4) + movi r6, 1 + bne r5, r6, .Lsigreturn + + mov r10, r4 + + /* Restore signal mask. */ + /* rt_sigprocmask (SIG_SETMASK, NULL, &ucp->uc_sigmask, _NSIG8) */ + movi r7, _NSIG8 + addi r6, r4, UCONTEXT_SIGMASK + mov r5, zero + movi r4, SIG_SETMASK + movi r2, SYS_ify (rt_sigprocmask) + trap + bne r7, zero, SYSCALL_ERROR_LABEL + + /* Restore argument registers, for the makecontext() case. */ + ldw r4, (UCONTEXT_MCONTEXT + 4*4)(r10) + ldw r5, (UCONTEXT_MCONTEXT + 5*4)(r10) + ldw r6, (UCONTEXT_MCONTEXT + 6*4)(r10) + ldw r7, (UCONTEXT_MCONTEXT + 7*4)(r10) + + ldw r16, (UCONTEXT_MCONTEXT + 16*4)(r10) + ldw r17, (UCONTEXT_MCONTEXT + 17*4)(r10) + ldw r18, (UCONTEXT_MCONTEXT + 18*4)(r10) + ldw r19, (UCONTEXT_MCONTEXT + 19*4)(r10) + ldw r20, (UCONTEXT_MCONTEXT + 20*4)(r10) + ldw r21, (UCONTEXT_MCONTEXT + 21*4)(r10) + ldw r22, (UCONTEXT_MCONTEXT + 22*4)(r10) + ldw ra, (UCONTEXT_MCONTEXT + 24*4)(r10) + ldw fp, (UCONTEXT_MCONTEXT + 25*4)(r10) + ldw gp, (UCONTEXT_MCONTEXT + 26*4)(r10) + /* Load address to continue execution. */ + ldw r3, (UCONTEXT_MCONTEXT + 28*4)(r10) + ldw sp, (UCONTEXT_MCONTEXT + 29*4)(r10) + + mov r2, zero + jmp r3 + +.Lsigreturn: + addi sp, sp, -RT_SIGFRAME_SIZE + cfi_adjust_cfa_offset (RT_SIGFRAME_SIZE) + + addi r2, sp, RT_SIGFRAME_UCONTEXT + movi r3, UCONTEXT_SIZE-4 +1: + add r6, r4, r3 + ldw r5, 0(r6) + add r7, r2, r3 + addi r3, r3, -4 + stw r5, 0(r7) + bgt r3, zero, 1b + + movi r2, SYS_ify (rt_sigreturn) + trap + + addi sp, sp, RT_SIGFRAME_SIZE + cfi_adjust_cfa_offset (-RT_SIGFRAME_SIZE) + br SYSCALL_ERROR_LABEL + +PSEUDO_END (__setcontext) +weak_alias (__setcontext, setcontext) + +ENTRY(__startcontext) + mov r4, r16 + bne r4, zero, __setcontext + + /* If uc_link == zero, call _exit. */ +#ifdef PIC + nextpc r22 +1: movhi r8, %hiadj(_gp_got - 1b) + addi r8, r8, %lo(_gp_got - 1b) + add r22, r22, r8 + ldw r8, %call(HIDDEN_JUMPTARGET(_exit))(r22) + jmp r8 +#else + jmpi _exit +#endif +END(__startcontext) diff --git a/sysdeps/unix/sysv/linux/nios2/sigcontextinfo.h b/sysdeps/unix/sysv/linux/nios2/sigcontextinfo.h new file mode 100644 index 0000000..fd0fa05 --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/sigcontextinfo.h @@ -0,0 +1,35 @@ +/* Nios II definitions for signal handling calling conventions. + Copyright (C) 2014 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 "kernel-features.h" + +#define SIGCONTEXT siginfo_t *_si, struct ucontext * +#define GET_PC(ctx) ((void *) (ctx)->uc_mcontext.regs[27]) + +/* There is no reliable way to get the sigcontext unless we use a + three-argument signal handler. */ +#define __sigaction(sig, act, oact) ({ \ + (act)->sa_flags |= SA_SIGINFO; \ + (__sigaction) (sig, act, oact); \ +}) + +#define sigaction(sig, act, oact) ({ \ + (act)->sa_flags |= SA_SIGINFO; \ + (sigaction) (sig, act, oact); \ +}) diff --git a/sysdeps/unix/sysv/linux/nios2/swapcontext.S b/sysdeps/unix/sysv/linux/nios2/swapcontext.S new file mode 100644 index 0000000..887427b --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/swapcontext.S @@ -0,0 +1,124 @@ +/* Copyright (C) 2014 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 "ucontext_i.h" + +/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */ + .text +ENTRY(__swapcontext) + + /* Same as getcontext(). */ + stw r16, (UCONTEXT_MCONTEXT + 16*4)(r4) + stw r17, (UCONTEXT_MCONTEXT + 17*4)(r4) + stw r18, (UCONTEXT_MCONTEXT + 18*4)(r4) + stw r19, (UCONTEXT_MCONTEXT + 19*4)(r4) + stw r20, (UCONTEXT_MCONTEXT + 20*4)(r4) + stw r21, (UCONTEXT_MCONTEXT + 21*4)(r4) + stw r22, (UCONTEXT_MCONTEXT + 22*4)(r4) + stw ra, (UCONTEXT_MCONTEXT + 24*4)(r4) + stw fp, (UCONTEXT_MCONTEXT + 25*4)(r4) + stw gp, (UCONTEXT_MCONTEXT + 26*4)(r4) + /* Store return address at place for EA. */ + stw ra, (UCONTEXT_MCONTEXT + 28*4)(r4) + stw sp, (UCONTEXT_MCONTEXT + 29*4)(r4) + /* Store zero for return success. */ + stw zero, (UCONTEXT_MCONTEXT + 2*4)(r4) + + /* Store value "1" at uc_flags to recognize as getcontext created. */ + movi r2, 1 + stw r2, UCONTEXT_FLAGS(r4) + + /* Store MCONTEXT_VERSION at first word of mcontext_t. */ + movi r2, MCONTEXT_VERSION + stw r2, UCONTEXT_MCONTEXT(r4) + + /* Save ucp to non-argument syscall preserved register. */ + mov r10, r5 + + /* Get signal mask. */ + /* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */ + movi r7, _NSIG8 + addi r6, r4, UCONTEXT_SIGMASK + mov r5, zero + movi r4, SIG_BLOCK + movi r2, SYS_ify (rt_sigprocmask) + trap + bne r7, zero, SYSCALL_ERROR_LABEL + + + /* Same as setcontext(). */ + ldw r5, UCONTEXT_FLAGS(r10) + movi r6, 1 + bne r5, r6, .Lsigreturn + + /* Restore signal mask. */ + /* rt_sigprocmask (SIG_SETMASK, NULL, &ucp->uc_sigmask, _NSIG8) */ + movi r7, _NSIG8 + addi r6, r10, UCONTEXT_SIGMASK + mov r5, zero + movi r4, SIG_SETMASK + movi r2, SYS_ify (rt_sigprocmask) + trap + bne r7, zero, SYSCALL_ERROR_LABEL + + /* Restore argument registers, for the makecontext() case. */ + ldw r4, (UCONTEXT_MCONTEXT + 4*4)(r10) + ldw r5, (UCONTEXT_MCONTEXT + 5*4)(r10) + ldw r6, (UCONTEXT_MCONTEXT + 6*4)(r10) + ldw r7, (UCONTEXT_MCONTEXT + 7*4)(r10) + + ldw r16, (UCONTEXT_MCONTEXT + 16*4)(r10) + ldw r17, (UCONTEXT_MCONTEXT + 17*4)(r10) + ldw r18, (UCONTEXT_MCONTEXT + 18*4)(r10) + ldw r19, (UCONTEXT_MCONTEXT + 19*4)(r10) + ldw r20, (UCONTEXT_MCONTEXT + 20*4)(r10) + ldw r21, (UCONTEXT_MCONTEXT + 21*4)(r10) + ldw r22, (UCONTEXT_MCONTEXT + 22*4)(r10) + ldw ra, (UCONTEXT_MCONTEXT + 24*4)(r10) + ldw fp, (UCONTEXT_MCONTEXT + 25*4)(r10) + ldw gp, (UCONTEXT_MCONTEXT + 26*4)(r10) + /* Load address to continue execution. */ + ldw r3, (UCONTEXT_MCONTEXT + 28*4)(r10) + ldw sp, (UCONTEXT_MCONTEXT + 29*4)(r10) + + mov r2, zero + jmp r3 + +.Lsigreturn: + addi sp, sp, -RT_SIGFRAME_SIZE + cfi_adjust_cfa_offset (RT_SIGFRAME_SIZE) + + addi r2, sp, RT_SIGFRAME_UCONTEXT + movi r3, UCONTEXT_SIZE-4 +1: + add r6, r4, r3 + ldw r5, 0(r6) + add r7, r2, r3 + addi r3, r3, -4 + stw r5, 0(r7) + bgt r3, zero, 1b + + movi r2, SYS_ify (rt_sigreturn) + trap + + addi sp, sp, RT_SIGFRAME_SIZE + cfi_adjust_cfa_offset (-RT_SIGFRAME_SIZE) + br SYSCALL_ERROR_LABEL + +PSEUDO_END (__swapcontext) +weak_alias (__swapcontext, swapcontext) diff --git a/sysdeps/unix/sysv/linux/nios2/sys/cachectl.h b/sysdeps/unix/sysv/linux/nios2/sys/cachectl.h new file mode 100644 index 0000000..3ce141d --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/sys/cachectl.h @@ -0,0 +1,35 @@ +/* Copyright (C) 2014 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 _SYS_CACHECTL_H +#define _SYS_CACHECTL_H 1 + +#include + +/* Get the kernel definition for the op bits. */ +#include + +__BEGIN_DECLS + +#ifdef __USE_MISC +extern int cacheflush (void *__addr, const int __nbytes, const int __op) __THROW; +#endif +extern int _flush_cache (char *__addr, const int __nbytes, const int __op) __THROW; + +__END_DECLS + +#endif /* sys/cachectl.h */ diff --git a/sysdeps/unix/sysv/linux/nios2/sys/procfs.h b/sysdeps/unix/sysv/linux/nios2/sys/procfs.h new file mode 100644 index 0000000..a9102b3 --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/sys/procfs.h @@ -0,0 +1,122 @@ +/* Copyright (C) 1996-2014 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 _SYS_PROCFS_H +#define _SYS_PROCFS_H 1 + +/* This is somewhat modelled after the file of the same name on SVR4 + systems. It provides a definition of the core file format for ELF + used on Linux. It doesn't have anything to do with the /proc file + system, even though Linux has one. + + Anyway, the whole purpose of this file is for GDB and GDB only. + Don't read too much into it. Don't use it for anything other than + GDB unless you know what you are doing. */ + +#include +#include +#include +#include + +__BEGIN_DECLS + +/* Type for a general-purpose register. */ +typedef unsigned long elf_greg_t; + +/* And the whole bunch of them. We could have used `struct + user_regs' directly in the typedef, but tradition says that + the register set is an array, which does have some peculiar + semantics, so leave it that way. */ +#define ELF_NGREG (sizeof (struct user_regs) / sizeof(elf_greg_t)) +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +/* Register set for the floating-point registers. */ +typedef struct user_fpregs elf_fpregset_t; + +/* Signal info. */ +struct elf_siginfo + { + int si_signo; /* Signal number. */ + int si_code; /* Extra code. */ + int si_errno; /* Errno. */ + }; + +/* Definitions to generate Intel SVR4-like core files. These mostly + have the same names as the SVR4 types with "elf_" tacked on the + front to prevent clashes with Linux definitions, and the typedef + forms have been avoided. This is mostly like the SVR4 structure, + but more Linuxy, with things that Linux does not support and which + GDB doesn't really use excluded. */ + +struct elf_prstatus + { + struct elf_siginfo pr_info; /* Info associated with signal. */ + short int pr_cursig; /* Current signal. */ + unsigned long int pr_sigpend; /* Set of pending signals. */ + unsigned long int pr_sighold; /* Set of held signals. */ + __pid_t pr_pid; + __pid_t pr_ppid; + __pid_t pr_pgrp; + __pid_t pr_sid; + struct timeval pr_utime; /* User time. */ + struct timeval pr_stime; /* System time. */ + struct timeval pr_cutime; /* Cumulative user time. */ + struct timeval pr_cstime; /* Cumulative system time. */ + elf_gregset_t pr_reg; /* GP registers. */ + int pr_fpvalid; /* True if math copro being used. */ + }; + + +#define ELF_PRARGSZ (80) /* Number of chars for args. */ + +struct elf_prpsinfo + { + char pr_state; /* Numeric process state. */ + char pr_sname; /* Char for pr_state. */ + char pr_zomb; /* Zombie. */ + char pr_nice; /* Nice val. */ + unsigned long int pr_flag; /* Flags. */ + unsigned short int pr_uid; + unsigned short int pr_gid; + int pr_pid, pr_ppid, pr_pgrp, pr_sid; + /* Lots missing */ + char pr_fname[16]; /* Filename of executable. */ + char pr_psargs[ELF_PRARGSZ]; /* Initial part of arg list. */ + }; + +/* The rest of this file provides the types for emulation of the + Solaris interfaces that should be implemented by + users of libthread_db. */ + +/* Addresses. */ +typedef void *psaddr_t; + +/* Register sets. Linux has different names. */ +typedef elf_gregset_t prgregset_t; +typedef elf_fpregset_t prfpregset_t; + +/* We don't have any differences between processes and threads, + therefore have only one PID type. */ +typedef __pid_t lwpid_t; + +/* Process status and info. In the end we do provide typedefs for them. */ +typedef struct elf_prstatus prstatus_t; +typedef struct elf_prpsinfo prpsinfo_t; + +__END_DECLS + +#endif /* sys/procfs.h */ diff --git a/sysdeps/unix/sysv/linux/nios2/sys/ucontext.h b/sysdeps/unix/sysv/linux/nios2/sys/ucontext.h new file mode 100644 index 0000000..cf11f14 --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/sys/ucontext.h @@ -0,0 +1,48 @@ +/* Copyright (C) 2014 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 + . */ + +/* System V/Nios II ABI compliant context switching support. */ + +#ifndef _SYS_UCONTEXT_H +#define _SYS_UCONTEXT_H 1 + +#include +#include + +/* These definitions must be in sync with the kernel. */ + +#define MCONTEXT_VERSION 2 + +/* Context to describe whole processor state. */ +typedef struct mcontext + { + int version; + unsigned long regs[32]; + } mcontext_t; + +/* Userlevel context. */ +typedef struct ucontext + { + unsigned long uc_flags; + struct ucontext *uc_link; + stack_t uc_stack; + mcontext_t uc_mcontext; + __sigset_t uc_sigmask; + } ucontext_t; + +#endif /* sys/ucontext.h */ diff --git a/sysdeps/unix/sysv/linux/nios2/sys/user.h b/sysdeps/unix/sysv/linux/nios2/sys/user.h new file mode 100644 index 0000000..3231046 --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/sys/user.h @@ -0,0 +1,57 @@ +/* Copyright (C) 1998-2014 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 _SYS_USER_H +#define _SYS_USER_H 1 + +/* The whole purpose of this file is for GDB and GDB only. Don't read + too much into it. Don't use it for anything other than GDB unless + you know what you are doing. */ + +struct user_fpregs +{ +}; + +struct user_regs +{ + unsigned long int uregs[49]; +}; + +struct user +{ + struct user_regs regs; /* General registers */ + int u_fpvalid; /* True if math co-processor being used. */ + + unsigned long int u_tsize; /* Text segment size (pages). */ + unsigned long int u_dsize; /* Data segment size (pages). */ + unsigned long int u_ssize; /* Stack segment size (pages). */ + + unsigned long start_code; /* Starting virtual address of text. */ + unsigned long start_stack; /* Starting virtual address of stack. */ + + long int signal; /* Signal that caused the core dump. */ + int reserved; /* No longer used */ + struct user_regs *u_ar0; /* help gdb to find the general registers. */ + + unsigned long magic; /* uniquely identify a core file */ + char u_comm[32]; /* User command that was responsible */ + int u_debugreg[8]; + struct user_fpregs u_fp; /* Floating point registers */ + struct user_fpregs *u_fp0; /* help gdb to find the FP registers. */ +}; + +#endif /* sys/user.h */ diff --git a/sysdeps/unix/sysv/linux/nios2/syscall.S b/sysdeps/unix/sysv/linux/nios2/syscall.S new file mode 100644 index 0000000..a0422da --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/syscall.S @@ -0,0 +1,35 @@ +/* Copyright (C) 2005-2014 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 + +/* We don't need a special syscall to implement syscall(). It won't work + reliably with 64-bit arguments (but that is true on many modern platforms). +*/ + +ENTRY (syscall) + mov r2, r4 + mov r4, r5 + mov r5, r6 + mov r6, r7 + ldw r7, 0(sp) + ldw r8, 4(sp) + ldw r9, 8(sp) + trap + bne r7, zero, SYSCALL_ERROR_LABEL + ret +PSEUDO_END (syscall) diff --git a/sysdeps/unix/sysv/linux/nios2/sysdep.S b/sysdeps/unix/sysv/linux/nios2/sysdep.S new file mode 100644 index 0000000..8ca099d --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/sysdep.S @@ -0,0 +1,49 @@ +/* Copyright (C) 2014 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 + +/* The following code is only used in the static library. In the shared + library, the error handling code is at the end of each function. */ + +#ifndef PIC + +/* In the static library, the syscall stubs jump here when they detect + an error. */ + +# undef CALL_MCOUNT +# define CALL_MCOUNT /* Don't insert the profiling call, it clobbers r2. */ + +# ifdef NOT_IN_libc +# define SYSCALL_ERROR_ERRNO errno +# else +# define SYSCALL_ERROR_ERRNO __libc_errno +# endif + .text +ENTRY (__syscall_error) + nextpc r22 +1: + movhi r8, %hiadj(_gp_got - 1b) + addi r8, r8, %lo(_gp_got - 1b) + add r22, r22, r8 + ldw r3, %tls_ie(SYSCALL_ERROR_ERRNO)(r22) + add r3, r23, r3 + stw r2, 0(r3) + movi r2, -1 + ret +END (__syscall_error) +#endif diff --git a/sysdeps/unix/sysv/linux/nios2/sysdep.h b/sysdeps/unix/sysv/linux/nios2/sysdep.h new file mode 100644 index 0000000..764ddfd --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/sysdep.h @@ -0,0 +1,259 @@ +/* Copyright (C) 2000-2014 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 _LINUX_NIOS2_SYSDEP_H +#define _LINUX_NIOS2_SYSDEP_H 1 + +#include +#include +#include +#include + +/* For RTLD_PRIVATE_ERRNO. */ +#include + +#include + +/* For Linux we can use the system call table in the header file + /usr/include/asm/unistd.h + of the kernel. But these symbols do not follow the SYS_* syntax + so we have to redefine the `SYS_ify' macro here. */ +#undef SYS_ify +#define SYS_ify(syscall_name) __NR_##syscall_name + +#ifdef __ASSEMBLER__ + +#define SYSCALL_ERROR_LABEL __local_syscall_error + +#undef PSEUDO +#define PSEUDO(name, syscall_name, args) \ + ENTRY (name) \ + DO_CALL (syscall_name, args) \ + bne r7, zero, SYSCALL_ERROR_LABEL; \ + +#undef PSEUDO_END +#define PSEUDO_END(name) \ + SYSCALL_ERROR_HANDLER \ + END (name) + +#undef PSEUDO_NOERRNO +#define PSEUDO_NOERRNO(name, syscall_name, args) \ + ENTRY (name) \ + DO_CALL (syscall_name, args) + +#undef PSEUDO_END_NOERRNO +#define PSEUDO_END_NOERRNO(name) \ + END (name) + +#undef ret_NOERRNO +#define ret_NOERRNO ret + +#undef DO_CALL +#define DO_CALL(syscall_name, args) \ + DOARGS_##args \ + movi r2, SYS_ify(syscall_name); \ + trap; + +#if defined(__PIC__) || defined(PIC) + +# if RTLD_PRIVATE_ERRNO + +# define SYSCALL_ERROR_HANDLER \ + SYSCALL_ERROR_LABEL: \ + nextpc r3; \ +1: \ + movhi r8, %hiadj(rtld_errno - 1b); \ + addi r8, r8, %lo(rtld_errno - 1b); \ + add r3, r3, r8; \ + stw r2, 0(r3); \ + movi r2, -1; \ + ret; + +# else + +# ifdef NOT_IN_libc +# define SYSCALL_ERROR_ERRNO errno +# else +# define SYSCALL_ERROR_ERRNO __libc_errno +# endif +# define SYSCALL_ERROR_HANDLER \ + SYSCALL_ERROR_LABEL: \ + nextpc r22; \ +1: \ + movhi r8, %hiadj(_gp_got - 1b); \ + addi r8, r8, %lo(_gp_got - 1b); \ + add r22, r22, r8; \ + ldw r3, %tls_ie(SYSCALL_ERROR_ERRNO)(r22); \ + add r3, r23, r3; \ + stw r2, 0(r3); \ + movi r2, -1; \ + ret; + +# endif + +#else + +/* We can use a single error handler in the static library. */ +#define SYSCALL_ERROR_HANDLER \ + SYSCALL_ERROR_LABEL: \ + jmpi __syscall_error; + +#endif + +#define DOARGS_0 /* nothing */ +#define DOARGS_1 /* nothing */ +#define DOARGS_2 /* nothing */ +#define DOARGS_3 /* nothing */ +#define DOARGS_4 /* nothing */ +#define DOARGS_5 ldw r8, 0(sp); +#define DOARGS_6 ldw r9, 4(sp); ldw r8, 0(sp); + +/* The function has to return the error code. */ +#undef PSEUDO_ERRVAL +#define PSEUDO_ERRVAL(name, syscall_name, args) \ + ENTRY (name) \ + DO_CALL (syscall_name, args) + +#undef PSEUDO_END_ERRVAL +#define PSEUDO_END_ERRVAL(name) \ + END (name) + +#define ret_ERRVAL ret + +#else /* __ASSEMBLER__ */ + +/* In order to get __set_errno() definition in INLINE_SYSCALL. */ +#include + +/* Define a macro which expands into the inline wrapper code for a system + call. */ +#undef INLINE_SYSCALL +#define INLINE_SYSCALL(name, nr, args...) \ + ({ INTERNAL_SYSCALL_DECL(err); \ + unsigned int result_var = INTERNAL_SYSCALL (name, err, nr, args); \ + if ( INTERNAL_SYSCALL_ERROR_P (result_var, err) ) \ + { \ + __set_errno (INTERNAL_SYSCALL_ERRNO (result_var, err)); \ + result_var = -1L; \ + } \ + (int) result_var; }) + +#undef INTERNAL_SYSCALL_DECL +#define INTERNAL_SYSCALL_DECL(err) unsigned int err __attribute__((unused)) + +#undef INTERNAL_SYSCALL_ERROR_P +#define INTERNAL_SYSCALL_ERROR_P(val, err) ((unsigned int) (err)) + +#undef INTERNAL_SYSCALL_ERRNO +#define INTERNAL_SYSCALL_ERRNO(val, err) (val) + +#undef INTERNAL_SYSCALL_RAW +#define INTERNAL_SYSCALL_RAW(name, err, nr, args...) \ + ({ unsigned int _sys_result; \ + { \ + /* Load argument values in temporary variables + to perform side effects like function calls + before the call-used registers are set. */ \ + LOAD_ARGS_##nr (args) \ + LOAD_REGS_##nr \ + register int _r2 asm ("r2") = (int)(name); \ + register int _err asm ("r7"); \ + asm volatile ("trap" \ + : "+r" (_r2), "=r" (_err) \ + : ASM_ARGS_##nr \ + : __SYSCALL_CLOBBERS); \ + _sys_result = _r2; \ + err = _err; \ + } \ + (int) _sys_result; }) + +#undef INTERNAL_SYSCALL +#define INTERNAL_SYSCALL(name, err, nr, args...) \ + INTERNAL_SYSCALL_RAW(SYS_ify(name), err, nr, args) + +#undef INTERNAL_SYSCALL_NCS +#define INTERNAL_SYSCALL_NCS(number, err, nr, args...) \ + INTERNAL_SYSCALL_RAW(number, err, nr, args) + +#define LOAD_ARGS_0() +#define LOAD_REGS_0 +#define ASM_ARGS_0 +#define LOAD_ARGS_1(a1) \ + LOAD_ARGS_0 () \ + int __arg1 = (int) (a1); +#define LOAD_REGS_1 \ + register int _r4 asm ("r4") = __arg1; \ + LOAD_REGS_0 +#define ASM_ARGS_1 "r" (_r4) +#define LOAD_ARGS_2(a1, a2) \ + LOAD_ARGS_1 (a1) \ + int __arg2 = (int) (a2); +#define LOAD_REGS_2 \ + register int _r5 asm ("r5") = __arg2; \ + LOAD_REGS_1 +#define ASM_ARGS_2 ASM_ARGS_1, "r" (_r5) +#define LOAD_ARGS_3(a1, a2, a3) \ + LOAD_ARGS_2 (a1, a2) \ + int __arg3 = (int) (a3); +#define LOAD_REGS_3 \ + register int _r6 asm ("r6") = __arg3; \ + LOAD_REGS_2 +#define ASM_ARGS_3 ASM_ARGS_2, "r" (_r6) +#define LOAD_ARGS_4(a1, a2, a3, a4) \ + LOAD_ARGS_3 (a1, a2, a3) \ + int __arg4 = (int) (a4); +#define LOAD_REGS_4 \ + register int _r7 asm ("r7") = __arg4; \ + LOAD_REGS_3 +#define ASM_ARGS_4 ASM_ARGS_3, "r" (_r7) +#define LOAD_ARGS_5(a1, a2, a3, a4, a5) \ + LOAD_ARGS_4 (a1, a2, a3, a4) \ + int __arg5 = (int) (a5); +#define LOAD_REGS_5 \ + register int _r8 asm ("r8") = __arg5; \ + LOAD_REGS_4 +#define ASM_ARGS_5 ASM_ARGS_4, "r" (_r8) +#define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6) \ + LOAD_ARGS_5 (a1, a2, a3, a4, a5) \ + int __arg6 = (int) (a6); +#define LOAD_REGS_6 \ + register int _r9 asm ("r9") = __arg6; \ + LOAD_REGS_5 +#define ASM_ARGS_6 ASM_ARGS_5, "r" (_r9) + +#define __SYSCALL_CLOBBERS "memory" + +#endif /* __ASSEMBLER__ */ + +/* Pointer mangling support. */ +#if defined NOT_IN_libc && defined IS_IN_rtld +/* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. */ +#else +# ifdef __ASSEMBLER__ +# define PTR_MANGLE_GUARD(guard) ldw guard, POINTER_GUARD(r23) +# define PTR_MANGLE(dst, src, guard) xor dst, src, guard +# define PTR_DEMANGLE(dst, src, guard) PTR_MANGLE (dst, src, guard) +# else +# define PTR_MANGLE(var) \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ()) +# define PTR_DEMANGLE(var) PTR_MANGLE (var) +# endif +#endif + + +#endif /* linux/nios2/sysdep.h */ diff --git a/sysdeps/unix/sysv/linux/nios2/ucontext_i.sym b/sysdeps/unix/sysv/linux/nios2/ucontext_i.sym new file mode 100644 index 0000000..a844c96 --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/ucontext_i.sym @@ -0,0 +1,29 @@ +#include +#include +#include +#include + +#include "kernel_rt_sigframe.h" + +SIG_BLOCK +SIG_SETMASK + +_NSIG8 (_NSIG / 8) + +MCONTEXT_VERSION + +-- Offsets of the fields in the kernel rt_sigframe_t structure. +#define rt_sigframe(member) offsetof (struct kernel_rt_sigframe, member) + +RT_SIGFRAME_SIZE sizeof (struct kernel_rt_sigframe) +RT_SIGFRAME_UCONTEXT rt_sigframe (uc) + +-- Offsets of the fields in the ucontext_t structure. +#define ucontext(member) offsetof (ucontext_t, member) + +UCONTEXT_FLAGS ucontext (uc_flags) +UCONTEXT_LINK ucontext (uc_link) +UCONTEXT_STACK ucontext (uc_stack) +UCONTEXT_MCONTEXT ucontext (uc_mcontext) +UCONTEXT_SIGMASK ucontext (uc_sigmask) +UCONTEXT_SIZE sizeof (ucontext_t)