From patchwork Wed Jun 14 18:30:47 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Palmer Dabbelt X-Patchwork-Id: 21023 Received: (qmail 99984 invoked by alias); 14 Jun 2017 18:33:30 -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 99814 invoked by uid 89); 14 Jun 2017 18:33:28 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-24.2 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS, UNSUBSCRIBE_BODY, URIBL_RED autolearn=ham version=3.3.2 spammy=Lots, Franklin X-HELO: mail-pf0-f193.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:cc:cc:cc:subject:date:message-id :in-reply-to:references; bh=7V4/XTznXBH1JSpG2erxVL4d8xWErsTKdIwHULR+lmE=; b=RqoYnmeSVDwHnwcRdGviGPA+wTH14crGhVUJkWr3Vw+7I3NmeT+o9QPrbhHGsT0IHU j146oTnNztpUddpYDZYczgMm22/gOhdOMtHEqfAd/ZUg2LBpLgsm18XoVSxYxIPTCDT5 f6ADG4MT+L2DB0zh9x6KXUXN+ChnZ88NBG9EAdqQ8qbjzY+gjXHNRTtEVZcyzog4V5+I CuqTS6ND+FdAcKUnuuB1tD+d7Yz4AmPP9uDQewl3GVroeI+XIkXo0I7/HqYSJYRuOSh/ 5b8cRo2/BlWSVkx6r+9if4z00/QzjNzMdLTtS1Sj0RdSaGH46MqkAa2TcKrM7QtHBELj O23w== X-Gm-Message-State: AKS2vOwFpgHa7lsC0eAZwespMwBxkYxJba8t4xbVIkkxEnpovudAbUKP J7w+86cjRz3FErEw1FkaIg== X-Received: by 10.84.238.196 with SMTP id l4mr1532774pln.280.1497465198212; Wed, 14 Jun 2017 11:33:18 -0700 (PDT) From: Palmer Dabbelt To: libc-alpha@sourceware.org Cc: Andrew Waterman Cc: patches@groups.riscv.org Cc: Darius Rad Cc: Palmer Dabbelt Subject: [PATCH 11/12] RISC-V: Linux ABI Date: Wed, 14 Jun 2017 11:30:47 -0700 Message-Id: <20170614183048.11040-12-palmer@dabbelt.com> In-Reply-To: <20170614183048.11040-1-palmer@dabbelt.com> References: <20170614183048.11040-1-palmer@dabbelt.com> Linux-specific code that is required for maintaining ABI compatibility. This doesn't contain the actual system call interface, that is split out in order to avoid having a patch that's too big. --- sysdeps/riscv/nptl/pthreaddef.h | 32 ++++++ sysdeps/riscv/rv32/divdi3.c | 1 + sysdeps/riscv/rv32/symbol-hacks.h | 1 + sysdeps/unix/sysv/linux/riscv/____longjmp_chk.S | 2 + sysdeps/unix/sysv/linux/riscv/bits/mman.h | 38 +++++++ sysdeps/unix/sysv/linux/riscv/bits/sigcontext.h | 33 ++++++ sysdeps/unix/sysv/linux/riscv/getcontext.S | 82 +++++++++++++++ sysdeps/unix/sysv/linux/riscv/makecontext.c | 72 +++++++++++++ sysdeps/unix/sysv/linux/riscv/register-dump.h | 65 ++++++++++++ sysdeps/unix/sysv/linux/riscv/setcontext.S | 126 +++++++++++++++++++++++ sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h | 29 ++++++ sysdeps/unix/sysv/linux/riscv/swapcontext.S | 130 ++++++++++++++++++++++++ sysdeps/unix/sysv/linux/riscv/sys/procfs.h | 113 ++++++++++++++++++++ sysdeps/unix/sysv/linux/riscv/sys/ucontext.h | 67 ++++++++++++ sysdeps/unix/sysv/linux/riscv/sys/user.h | 2 + sysdeps/unix/sysv/linux/riscv/ucontext_i.sym | 33 ++++++ 16 files changed, 826 insertions(+) create mode 100644 sysdeps/riscv/nptl/pthreaddef.h create mode 100644 sysdeps/riscv/rv32/divdi3.c create mode 100644 sysdeps/riscv/rv32/symbol-hacks.h create mode 100644 sysdeps/unix/sysv/linux/riscv/____longjmp_chk.S create mode 100644 sysdeps/unix/sysv/linux/riscv/bits/mman.h create mode 100644 sysdeps/unix/sysv/linux/riscv/bits/sigcontext.h create mode 100644 sysdeps/unix/sysv/linux/riscv/getcontext.S create mode 100644 sysdeps/unix/sysv/linux/riscv/makecontext.c create mode 100644 sysdeps/unix/sysv/linux/riscv/register-dump.h create mode 100644 sysdeps/unix/sysv/linux/riscv/setcontext.S create mode 100644 sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h create mode 100644 sysdeps/unix/sysv/linux/riscv/swapcontext.S create mode 100644 sysdeps/unix/sysv/linux/riscv/sys/procfs.h create mode 100644 sysdeps/unix/sysv/linux/riscv/sys/ucontext.h create mode 100644 sysdeps/unix/sysv/linux/riscv/sys/user.h create mode 100644 sysdeps/unix/sysv/linux/riscv/ucontext_i.sym diff --git a/sysdeps/riscv/nptl/pthreaddef.h b/sysdeps/riscv/nptl/pthreaddef.h new file mode 100644 index 0000000000..6df6bd4122 --- /dev/null +++ b/sysdeps/riscv/nptl/pthreaddef.h @@ -0,0 +1,32 @@ +/* Copyright (C) 2011-2014, 2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* Default stack size. */ +#define ARCH_STACK_DEFAULT_SIZE (2 * 1024 * 1024) + +/* Required stack pointer alignment at beginning. */ +#define STACK_ALIGN 16 + +/* Minimal stack size after allocating thread descriptor and guard size. */ +#define MINIMAL_REST_STACK 2048 + +/* Alignment requirement for TCB. */ +#define TCB_ALIGNMENT 16 + +/* Location of current stack frame. */ +#define CURRENT_STACK_FRAME __builtin_frame_address (0) diff --git a/sysdeps/riscv/rv32/divdi3.c b/sysdeps/riscv/rv32/divdi3.c new file mode 100644 index 0000000000..52f3a0396c --- /dev/null +++ b/sysdeps/riscv/rv32/divdi3.c @@ -0,0 +1 @@ +/* libgcc.a provides optimized versions of these routines. */ diff --git a/sysdeps/riscv/rv32/symbol-hacks.h b/sysdeps/riscv/rv32/symbol-hacks.h new file mode 100644 index 0000000000..22aad04437 --- /dev/null +++ b/sysdeps/riscv/rv32/symbol-hacks.h @@ -0,0 +1 @@ +#include diff --git a/sysdeps/unix/sysv/linux/riscv/____longjmp_chk.S b/sysdeps/unix/sysv/linux/riscv/____longjmp_chk.S new file mode 100644 index 0000000000..e903c7e0df --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/____longjmp_chk.S @@ -0,0 +1,2 @@ +#define __longjmp ____longjmp_chk +#include <__longjmp.S> diff --git a/sysdeps/unix/sysv/linux/riscv/bits/mman.h b/sysdeps/unix/sysv/linux/riscv/bits/mman.h new file mode 100644 index 0000000000..4a85eee71e --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/bits/mman.h @@ -0,0 +1,38 @@ +/* Definitions for POSIX memory map interface. Linux/RISC-V version. + Copyright (C) 1997, 2000, 2003, 2004, 2005, 2006, 2009, 2011, 2017 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _SYS_MMAN_H +# error "Never use directly; include instead." +#endif + +#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/riscv/bits/sigcontext.h b/sysdeps/unix/sysv/linux/riscv/bits/sigcontext.h new file mode 100644 index 0000000000..4ebf5afa2a --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/bits/sigcontext.h @@ -0,0 +1,33 @@ +/* Copyright (C) 1996, 1997, 1998, 2003, 2004, 2006, 2017 Free Software + Foundation, Inc. This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _BITS_SIGCONTEXT_H +#define _BITS_SIGCONTEXT_H 1 + +#if !defined _SIGNAL_H && !defined _SYS_UCONTEXT_H +# error "Never use directly; include instead." +#endif + +struct sigcontext { + /* gregs[0] holds the program counter. */ + unsigned long gregs[32]; + unsigned long long fpregs[32]; + unsigned int fsr; +}; + +#endif diff --git a/sysdeps/unix/sysv/linux/riscv/getcontext.S b/sysdeps/unix/sysv/linux/riscv/getcontext.S new file mode 100644 index 0000000000..b2ff959950 --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/getcontext.S @@ -0,0 +1,82 @@ +/* Save current context. + Copyright (C) 2009, 2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Maciej W. Rozycki . + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include +#include + +#include "ucontext_i.h" + +/* int getcontext (ucontext_t *ucp) */ + + .text +LEAF (__getcontext) + REG_S ra, MCONTEXT_PC(a0) + REG_S ra, ( 1 * SZREG + MCONTEXT_GREGS)(a0) + REG_S sp, ( 2 * SZREG + MCONTEXT_GREGS)(a0) + REG_S s0, ( 8 * SZREG + MCONTEXT_GREGS)(a0) + REG_S s1, ( 9 * SZREG + MCONTEXT_GREGS)(a0) + REG_S x0, (10 * SZREG + MCONTEXT_GREGS)(a0) /* return 0 */ + REG_S s2, (18 * SZREG + MCONTEXT_GREGS)(a0) + REG_S s3, (19 * SZREG + MCONTEXT_GREGS)(a0) + REG_S s4, (20 * SZREG + MCONTEXT_GREGS)(a0) + REG_S s5, (21 * SZREG + MCONTEXT_GREGS)(a0) + REG_S s6, (22 * SZREG + MCONTEXT_GREGS)(a0) + REG_S s7, (23 * SZREG + MCONTEXT_GREGS)(a0) + REG_S s8, (24 * SZREG + MCONTEXT_GREGS)(a0) + REG_S s9, (25 * SZREG + MCONTEXT_GREGS)(a0) + REG_S s10,(26 * SZREG + MCONTEXT_GREGS)(a0) + REG_S s11,(27 * SZREG + MCONTEXT_GREGS)(a0) + +#ifndef __riscv_float_abi_soft + frsr a1 + + FREG_S fs0, ( 8 * SZFREG + MCONTEXT_FPREGS)(a0) + FREG_S fs1, ( 9 * SZFREG + MCONTEXT_FPREGS)(a0) + FREG_S fs2, (18 * SZFREG + MCONTEXT_FPREGS)(a0) + FREG_S fs3, (19 * SZFREG + MCONTEXT_FPREGS)(a0) + FREG_S fs4, (20 * SZFREG + MCONTEXT_FPREGS)(a0) + FREG_S fs5, (21 * SZFREG + MCONTEXT_FPREGS)(a0) + FREG_S fs6, (22 * SZFREG + MCONTEXT_FPREGS)(a0) + FREG_S fs7, (23 * SZFREG + MCONTEXT_FPREGS)(a0) + FREG_S fs8, (24 * SZFREG + MCONTEXT_FPREGS)(a0) + FREG_S fs9, (25 * SZFREG + MCONTEXT_FPREGS)(a0) + FREG_S fs10,(26 * SZFREG + MCONTEXT_FPREGS)(a0) + FREG_S fs11,(27 * SZFREG + MCONTEXT_FPREGS)(a0) + + sw a1, MCONTEXT_FSR(a0) +#endif /* __riscv_float_abi_soft */ + +/* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */ + li a3, _NSIG8 + add a2, a0, UCONTEXT_SIGMASK + mv a1, zero + li a0, SIG_BLOCK + + li a7, SYS_ify (rt_sigprocmask) + scall + bltz a0, 99f + + ret + +99: j __syscall_error + +PSEUDO_END (__getcontext) + +weak_alias (__getcontext, getcontext) diff --git a/sysdeps/unix/sysv/linux/riscv/makecontext.c b/sysdeps/unix/sysv/linux/riscv/makecontext.c new file mode 100644 index 0000000000..0b53023166 --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/makecontext.c @@ -0,0 +1,72 @@ +/* Copyright (C) 2001-2003, 2005, 2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + + +#include +#include +#include +#include +#include + +void +__makecontext (ucontext_t *ucp, void (*func) (void), int argc, + long a0, long a1, long a2, long a3, long a4, ...) +{ + extern void __start_context (void) attribute_hidden; + long i, sp; + + _Static_assert (REG_NARGS == 8, "__makecontext assumes 8 argument registers"); + + /* Set up the stack. */ + sp = ((long)ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size) & ALMASK; + + /* Set up the register context. + ra = s0 = 0, terminating the stack for backtracing purposes. + s1 = the function we must call. + s2 = the subsequent context to run. */ + ucp->uc_mcontext.gregs[REG_RA] = 0; + ucp->uc_mcontext.gregs[REG_S0 + 0] = 0; + ucp->uc_mcontext.gregs[REG_S0 + 1] = (long)func; + ucp->uc_mcontext.gregs[REG_S0 + 2] = (long)ucp->uc_link; + ucp->uc_mcontext.gregs[REG_SP] = sp; + ucp->uc_mcontext.gregs[REG_PC] = (long)&__start_context; + + /* Put args in a0-a7, then put any remaining args on the stack. */ + ucp->uc_mcontext.gregs[REG_A0 + 0] = a0; + ucp->uc_mcontext.gregs[REG_A0 + 1] = a1; + ucp->uc_mcontext.gregs[REG_A0 + 2] = a2; + ucp->uc_mcontext.gregs[REG_A0 + 3] = a3; + ucp->uc_mcontext.gregs[REG_A0 + 4] = a4; + + if (__builtin_expect (argc > 5, 0)) + { + va_list vl; + va_start (vl, a4); + + long reg_args = argc < REG_NARGS ? argc : REG_NARGS; + sp = (sp - (argc - reg_args) * sizeof (long)) & ALMASK; + for (i = 5; i < reg_args; i++) + ucp->uc_mcontext.gregs[REG_A0 + i] = va_arg (vl, long); + for (i = 0; i < argc - reg_args; i++) + ((long*)sp)[i] = va_arg (vl, long); + + va_end (vl); + } +} + +weak_alias (__makecontext, makecontext) diff --git a/sysdeps/unix/sysv/linux/riscv/register-dump.h b/sysdeps/unix/sysv/linux/riscv/register-dump.h new file mode 100644 index 0000000000..7ce4edfc9e --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/register-dump.h @@ -0,0 +1,65 @@ +/* Dump registers. + Copyright (C) 2000, 2001, 2002, 2006, 2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger , 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include <_itoa.h> + +static void +hexvalue (unsigned long int value, char *buf, size_t len) +{ + char *cp = _itoa_word (value, buf + len, 16, 0); + while (cp > buf) + *--cp = '0'; +} + +#define REGDUMP_NREGS 32 +#define REGDUMP_PER_LINE (80 / (__WORDSIZE/4 + 4)) + +static void +register_dump (int fd, struct ucontext *ctx) +{ + int i; + char regvalue[__WORDSIZE/4 + 1]; + char str[82 * ((REGDUMP_NREGS + REGDUMP_PER_LINE - 1) / REGDUMP_PER_LINE)]; + + static const char names[REGDUMP_NREGS][4] = { + "pc", "ra", "sp", "gp", "tp", "t0", "t1", "t2", + "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", + "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", + "s8", "s9", "sA", "sB", "t3", "t4", "t5", "t6" + }; + + str[0] = 0; + for (i = 0; i < REGDUMP_NREGS; i++) + { + strcat (str, names[i]); + strcat (str, " "); + hexvalue (ctx->uc_mcontext.gregs[i], regvalue, __WORDSIZE/4); + strcat (str, regvalue); + + if ((i + 1) % REGDUMP_PER_LINE == 0) + strcat (str, "\n"); + } + + write (fd, str, strlen (str)); +} + +#define REGISTER_DUMP register_dump (fd, ctx) diff --git a/sysdeps/unix/sysv/linux/riscv/setcontext.S b/sysdeps/unix/sysv/linux/riscv/setcontext.S new file mode 100644 index 0000000000..2cfaae5e4b --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/setcontext.S @@ -0,0 +1,126 @@ +/* Set current context. + Copyright (C) 2009, 2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Maciej W. Rozycki . + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include +#include + +#include "ucontext_i.h" + +#define RESTORE_FP_REG(name, num, base) \ + FREG_L name, ((num) * SZFREG + MCONTEXT_FPREGS)(base) + +#define RESTORE_FP_REG_CFI(name, num, base) \ + RESTORE_FP_REG (name, num, base); \ + cfi_offset (name, (num) * SZREG + MCONTEXT_GREGS) + +#define RESTORE_INT_REG(name, num, base) \ + REG_L name, ((num) * SZREG + MCONTEXT_GREGS)(base) + +#define RESTORE_INT_REG_CFI(name, num, base) \ + RESTORE_INT_REG (name, num, base); \ + cfi_offset (name, (num) * SZREG + MCONTEXT_GREGS) + +/* int setcontext (const ucontext_t *ucp) */ + + .text +LEAF (__setcontext) + + mv t0, a0 /* t0 <- ucp */ + +/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, NULL, _NSIG8) */ + li a3, _NSIG8 + mv a2, zero + add a1, a0, UCONTEXT_SIGMASK + li a0, SIG_SETMASK + + li a7, SYS_ify (rt_sigprocmask) + scall + + bltz a0, 99f + + cfi_def_cfa (t0, 0) + +#ifndef __riscv_float_abi_soft + lw t1, MCONTEXT_FSR(t0) + + RESTORE_FP_REG_CFI (fs0, 8, t0) + RESTORE_FP_REG_CFI (fs1, 9, t0) + RESTORE_FP_REG_CFI (fs2, 18, t0) + RESTORE_FP_REG_CFI (fs3, 19, t0) + RESTORE_FP_REG_CFI (fs4, 20, t0) + RESTORE_FP_REG_CFI (fs5, 21, t0) + RESTORE_FP_REG_CFI (fs6, 22, t0) + RESTORE_FP_REG_CFI (fs7, 23, t0) + RESTORE_FP_REG_CFI (fs8, 24, t0) + RESTORE_FP_REG_CFI (fs9, 25, t0) + RESTORE_FP_REG_CFI (fs10, 26, t0) + RESTORE_FP_REG_CFI (fs11, 27, t0) + + fssr t1 +#endif /* __riscv_float_abi_soft */ + + /* Note the contents of argument registers will be random + unless makecontext() has been called. */ + REG_L t1, MCONTEXT_PC(t0) + RESTORE_INT_REG_CFI (ra, 1, t0) + RESTORE_INT_REG (sp, 2, t0) + RESTORE_INT_REG_CFI (s0, 8, t0) + RESTORE_INT_REG_CFI (s1, 9, t0) + RESTORE_INT_REG (a0, 10, t0) + RESTORE_INT_REG (a1, 11, t0) + RESTORE_INT_REG (a2, 12, t0) + RESTORE_INT_REG (a3, 13, t0) + RESTORE_INT_REG (a4, 14, t0) + RESTORE_INT_REG (a5, 15, t0) + RESTORE_INT_REG (a6, 16, t0) + RESTORE_INT_REG (a7, 17, t0) + RESTORE_INT_REG_CFI (s2, 18, t0) + RESTORE_INT_REG_CFI (s3, 19, t0) + RESTORE_INT_REG_CFI (s4, 20, t0) + RESTORE_INT_REG_CFI (s5, 21, t0) + RESTORE_INT_REG_CFI (s6, 22, t0) + RESTORE_INT_REG_CFI (s7, 23, t0) + RESTORE_INT_REG_CFI (s8, 24, t0) + RESTORE_INT_REG_CFI (s9, 25, t0) + RESTORE_INT_REG_CFI (s10, 26, t0) + RESTORE_INT_REG_CFI (s11, 27, t0) + + jr t1 + +99: j __syscall_error + +PSEUDO_END (__setcontext) +weak_alias (__setcontext, setcontext) + +LEAF (__start_context) + + /* Terminate call stack by noting ra == 0. Happily, s0 == 0 here. */ + cfi_register (ra, s0) + + /* Call the function passed to makecontext. */ + jalr s1 + + /* Invoke subsequent context if present, else exit(0). */ + mv a0, s2 + beqz s2, 1f + jal __setcontext +1: j exit + +PSEUDO_END (__start_context) diff --git a/sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h b/sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h new file mode 100644 index 0000000000..ae4069b293 --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h @@ -0,0 +1,29 @@ +/* Copyright (C) 2000, 2001, 2003, 2004, 2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger , 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +#define SIGCONTEXT siginfo_t *_si, struct ucontext * +#define SIGCONTEXT_EXTRA_ARGS _si, +#define GET_PC(ctx) ((void *) ctx->uc_mcontext.gregs[REG_PC]) +#define GET_FRAME(ctx) ((void *) ctx->uc_mcontext.gregs[REG_S0]) +#define GET_STACK(ctx) ((void *) ctx->uc_mcontext.gregs[REG_SP]) + +#define CALL_SIGHANDLER(handler, signo, ctx) \ + (handler)((signo), SIGCONTEXT_EXTRA_ARGS (ctx)) diff --git a/sysdeps/unix/sysv/linux/riscv/swapcontext.S b/sysdeps/unix/sysv/linux/riscv/swapcontext.S new file mode 100644 index 0000000000..5b2508c25b --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/swapcontext.S @@ -0,0 +1,130 @@ +/* Save and set current context. + Copyright (C) 2009, 2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Maciej W. Rozycki . + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include +#include + +#include "ucontext_i.h" + +/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */ + +LEAF (__swapcontext) + mv t0, a1 /* t0 <- ucp */ + + REG_S ra, MCONTEXT_PC(a0) + REG_S ra, ( 1 * SZREG + MCONTEXT_GREGS)(a0) + REG_S sp, ( 2 * SZREG + MCONTEXT_GREGS)(a0) + REG_S s0, ( 8 * SZREG + MCONTEXT_GREGS)(a0) + REG_S s1, ( 9 * SZREG + MCONTEXT_GREGS)(a0) + REG_S x0, (10 * SZREG + MCONTEXT_GREGS)(a0) /* return 0 */ + REG_S s2, (18 * SZREG + MCONTEXT_GREGS)(a0) + REG_S s3, (19 * SZREG + MCONTEXT_GREGS)(a0) + REG_S s4, (20 * SZREG + MCONTEXT_GREGS)(a0) + REG_S s5, (21 * SZREG + MCONTEXT_GREGS)(a0) + REG_S s6, (22 * SZREG + MCONTEXT_GREGS)(a0) + REG_S s7, (23 * SZREG + MCONTEXT_GREGS)(a0) + REG_S s8, (24 * SZREG + MCONTEXT_GREGS)(a0) + REG_S s9, (25 * SZREG + MCONTEXT_GREGS)(a0) + REG_S s10,(26 * SZREG + MCONTEXT_GREGS)(a0) + REG_S s11,(27 * SZREG + MCONTEXT_GREGS)(a0) + +#ifndef __riscv_float_abi_soft + frsr a1 + + FREG_S fs0, ( 8 * SZFREG + MCONTEXT_FPREGS)(a0) + FREG_S fs1, ( 9 * SZFREG + MCONTEXT_FPREGS)(a0) + FREG_S fs2, (18 * SZFREG + MCONTEXT_FPREGS)(a0) + FREG_S fs3, (19 * SZFREG + MCONTEXT_FPREGS)(a0) + FREG_S fs4, (20 * SZFREG + MCONTEXT_FPREGS)(a0) + FREG_S fs5, (21 * SZFREG + MCONTEXT_FPREGS)(a0) + FREG_S fs6, (22 * SZFREG + MCONTEXT_FPREGS)(a0) + FREG_S fs7, (23 * SZFREG + MCONTEXT_FPREGS)(a0) + FREG_S fs8, (24 * SZFREG + MCONTEXT_FPREGS)(a0) + FREG_S fs9, (25 * SZFREG + MCONTEXT_FPREGS)(a0) + FREG_S fs10,(26 * SZFREG + MCONTEXT_FPREGS)(a0) + FREG_S fs11,(27 * SZFREG + MCONTEXT_FPREGS)(a0) + + sw a1, MCONTEXT_FSR(a0) +#endif /* __riscv_float_abi_soft */ + +/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, NULL, _NSIG8) */ + li a3, _NSIG8 + mv a2, zero + add a1, a0, UCONTEXT_SIGMASK + li a0, SIG_SETMASK + + li a7, SYS_ify (rt_sigprocmask) + scall + + bltz a0, 99f + +#ifndef __riscv_float_abi_soft + lw t1, MCONTEXT_FSR(t0) + + FREG_L fs0, ( 8 * SZFREG + MCONTEXT_FPREGS)(t0) + FREG_L fs1, ( 9 * SZFREG + MCONTEXT_FPREGS)(t0) + FREG_L fs2, (18 * SZFREG + MCONTEXT_FPREGS)(t0) + FREG_L fs3, (19 * SZFREG + MCONTEXT_FPREGS)(t0) + FREG_L fs4, (20 * SZFREG + MCONTEXT_FPREGS)(t0) + FREG_L fs5, (21 * SZFREG + MCONTEXT_FPREGS)(t0) + FREG_L fs6, (22 * SZFREG + MCONTEXT_FPREGS)(t0) + FREG_L fs7, (23 * SZFREG + MCONTEXT_FPREGS)(t0) + FREG_L fs8, (24 * SZFREG + MCONTEXT_FPREGS)(t0) + FREG_L fs9, (25 * SZFREG + MCONTEXT_FPREGS)(t0) + FREG_L fs10,(26 * SZFREG + MCONTEXT_FPREGS)(t0) + FREG_L fs11,(27 * SZFREG + MCONTEXT_FPREGS)(t0) + + fssr t1 +#endif /* __riscv_float_abi_soft */ + + /* Note the contents of argument registers will be random + unless makecontext() has been called. */ + REG_L t1, MCONTEXT_PC(t0) + REG_L ra, ( 1 * SZREG + MCONTEXT_GREGS)(t0) + REG_L sp, ( 2 * SZREG + MCONTEXT_GREGS)(t0) + REG_L s0, ( 8 * SZREG + MCONTEXT_GREGS)(t0) + REG_L s1, ( 9 * SZREG + MCONTEXT_GREGS)(t0) + REG_L a0, (10 * SZREG + MCONTEXT_GREGS)(t0) + REG_L a1, (11 * SZREG + MCONTEXT_GREGS)(t0) + REG_L a2, (12 * SZREG + MCONTEXT_GREGS)(t0) + REG_L a3, (13 * SZREG + MCONTEXT_GREGS)(t0) + REG_L a4, (14 * SZREG + MCONTEXT_GREGS)(t0) + REG_L a5, (15 * SZREG + MCONTEXT_GREGS)(t0) + REG_L a6, (16 * SZREG + MCONTEXT_GREGS)(t0) + REG_L a7, (17 * SZREG + MCONTEXT_GREGS)(t0) + REG_L s2, (18 * SZREG + MCONTEXT_GREGS)(t0) + REG_L s3, (19 * SZREG + MCONTEXT_GREGS)(t0) + REG_L s4, (20 * SZREG + MCONTEXT_GREGS)(t0) + REG_L s5, (21 * SZREG + MCONTEXT_GREGS)(t0) + REG_L s6, (22 * SZREG + MCONTEXT_GREGS)(t0) + REG_L s7, (23 * SZREG + MCONTEXT_GREGS)(t0) + REG_L s8, (24 * SZREG + MCONTEXT_GREGS)(t0) + REG_L s9, (25 * SZREG + MCONTEXT_GREGS)(t0) + REG_L s10,(26 * SZREG + MCONTEXT_GREGS)(t0) + REG_L s11,(27 * SZREG + MCONTEXT_GREGS)(t0) + + jr t1 + + +99: j __syscall_error + +PSEUDO_END (__swapcontext) + +weak_alias (__swapcontext, swapcontext) diff --git a/sysdeps/unix/sysv/linux/riscv/sys/procfs.h b/sysdeps/unix/sysv/linux/riscv/sys/procfs.h new file mode 100644 index 0000000000..3ba1f07d7e --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/sys/procfs.h @@ -0,0 +1,113 @@ +/* Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2017 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _SYS_PROCFS_H +#define _SYS_PROCFS_H 1 + +/* This is somehow modelled after the file of the same name on SysVr4 + systems. It provides a definition of the core file format for ELF + used on Linux. */ + +#include +#include +#include +#include +#include + +/* ELF register definitions */ +#define ELF_NGREG NGREG +#define ELF_NFPREG NFPREG + +typedef greg_t elf_greg_t; +typedef gregset_t elf_gregset_t; +typedef fpreg_t elf_fpreg_t; +typedef fpregset_t elf_fpregset_t; + +__BEGIN_DECLS + +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. Fields present but not used are + marked with "XXX". */ +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. */ + long pr_uid; + long 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. */ + }; + + +/* 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 habe only ine PID type. */ +typedef __pid_t lwpid_t; + + +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/riscv/sys/ucontext.h b/sysdeps/unix/sysv/linux/riscv/sys/ucontext.h new file mode 100644 index 0000000000..d9cce75449 --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/sys/ucontext.h @@ -0,0 +1,67 @@ +/* Copyright (C) 1997, 1998, 2000, 2003, 2004, 2006, 2009, 2017 Free Software + Foundation, Inc. This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* Don't rely on this, the interface is currently messed up and may need to + be broken to be fixed. */ +#ifndef _SYS_UCONTEXT_H +#define _SYS_UCONTEXT_H 1 + +#include +#include + +/* We need the signal context definitions even if they are not used + included in . */ +#include + +/* Type for general register. Even in o32 we assume 64-bit registers, + like the kernel. */ +__extension__ typedef unsigned long long int greg_t; +typedef double fpreg_t; + +/* Number of general registers. */ +#define NGREG 32 +#define NFPREG 32 + +#define REG_PC 0 +#define REG_RA 1 +#define REG_SP 2 +#define REG_TP 4 +#define REG_S0 8 +#define REG_A0 10 +#define REG_NARGS 8 + +/* Container for all general registers. */ +typedef greg_t gregset_t[NGREG]; + +/* Container for all FPU registers. */ +typedef fpreg_t fpregset_t[NFPREG]; + +/* Context to describe whole processor state. */ +typedef struct sigcontext mcontext_t; + +/* Userlevel context. */ +typedef struct ucontext + { + unsigned long int 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/riscv/sys/user.h b/sysdeps/unix/sysv/linux/riscv/sys/user.h new file mode 100644 index 0000000000..faf307936b --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/sys/user.h @@ -0,0 +1,2 @@ +/* x86 puts "struct user_regs_struct" in here, this is just a shim. */ +#include diff --git a/sysdeps/unix/sysv/linux/riscv/ucontext_i.sym b/sysdeps/unix/sysv/linux/riscv/ucontext_i.sym new file mode 100644 index 0000000000..67f50d4a5b --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/ucontext_i.sym @@ -0,0 +1,33 @@ +#include +#include +#include +#include + +-- Constants used by the rt_sigprocmask call. + +SIG_BLOCK +SIG_SETMASK + +_NSIG8 (_NSIG / 8) + +-- Offsets of the fields in the ucontext_t structure. +#define ucontext(member) offsetof (ucontext_t, member) +#define stack(member) ucontext (uc_stack.member) +#define mcontext(member) ucontext (uc_mcontext.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) + +STACK_SP stack (ss_sp) +STACK_SIZE stack (ss_size) +STACK_FLAGS stack (ss_flags) + +MCONTEXT_GREGS mcontext (gregs) +MCONTEXT_FPREGS mcontext (fpregs) +MCONTEXT_PC mcontext (gregs) +MCONTEXT_FSR mcontext (fsr) + +UCONTEXT_SIZE sizeof (ucontext_t)