[11/12] RISC-V: Linux ABI

Message ID 20170614183048.11040-12-palmer@dabbelt.com
State New, archived
Headers

Commit Message

Palmer Dabbelt June 14, 2017, 6:30 p.m. UTC
  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
  

Comments

Florian Weimer June 14, 2017, 8:39 p.m. UTC | #1
Palmer Dabbelt <palmer@dabbelt.com> writes:

> 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.

You likely need to override bits/sigstack.h in one of these patches
because the generic MINSIGSTKSZ and SIGSTKSZ values are likely too
small, especially if you want to add more or broader vector registers in
the future.

PTHREAD_STACK_MIN might warrant adjustment, too.

Florian
  
Joseph Myers June 14, 2017, 9:23 p.m. UTC | #2
On Wed, 14 Jun 2017, Palmer Dabbelt wrote:

> 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.  */

divdi3.c is now only used if an architecture explicitly requests it.  You 
shouldn't need this file.

> 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 <sysdeps/generic/symbol-hacks.h>

Likewise, you shouldn't need this file either.

> diff --git a/sysdeps/unix/sysv/linux/riscv/sys/ucontext.h b/sysdeps/unix/sysv/linux/riscv/sys/ucontext.h

> +/* 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];

See my recent cleanups, and make sure your sys/ucontext.h is 
namespace-clean in all the ways in which I've cleaned up other 
sys/ucontext.h files so far.
  
Palmer Dabbelt June 20, 2017, 9:29 p.m. UTC | #3
On Wed, 14 Jun 2017 13:39:50 PDT (-0700), fweimer@redhat.com wrote:
> Palmer Dabbelt <palmer@dabbelt.com> writes:
>
>> 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.
>
> You likely need to override bits/sigstack.h in one of these patches
> because the generic MINSIGSTKSZ and SIGSTKSZ values are likely too
> small, especially if you want to add more or broader vector registers in
> the future.
>
> PTHREAD_STACK_MIN might warrant adjustment, too.

We're going to pick the most common values, which I believe are

  MINSIGSTKSZ = 4KiB (alpha, powerpc, sparc, with aarch64 setting 5KiB)
  SIGSTKSZ = 16KiB (aarch64, alpha, powerpc, sparc)
  PTHERAD_STACK_MIN = 128KiB (aarch64, mips, ppc, tile)

We're writing a vector extension, but it'll configurable vector sizes so
reserving the worst case space now will be pretty big.  Andrew and I think the
best thing to do here is similar to what aarch64 is doing with their SVE stuff
and have a system call to determine the minimum signal stack size dynamically
instead of reserving the space statically.

Does that seem reasonable?
  
Florian Weimer June 21, 2017, 8:56 a.m. UTC | #4
On 06/20/2017 11:29 PM, Palmer Dabbelt wrote:
> On Wed, 14 Jun 2017 13:39:50 PDT (-0700), fweimer@redhat.com wrote:
>> Palmer Dabbelt <palmer@dabbelt.com> writes:
>>
>>> 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.
>>
>> You likely need to override bits/sigstack.h in one of these patches
>> because the generic MINSIGSTKSZ and SIGSTKSZ values are likely too
>> small, especially if you want to add more or broader vector registers in
>> the future.
>>
>> PTHREAD_STACK_MIN might warrant adjustment, too.
> 
> We're going to pick the most common values, which I believe are
> 
>   MINSIGSTKSZ = 4KiB (alpha, powerpc, sparc, with aarch64 setting 5KiB)

You need to check what your architecture actually needs: the amount of
data pushed by the kernel, and it's also good to take into account the
save area used by the dynamic linker trampoline.  Then maybe add a
couple of kilobytes so that there is room for some actually work
performed by the application signal handler.

Thanks,
Florian
  

Patch

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 <sysdeps/generic/symbol-hacks.h>
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 <bits/mman.h> directly; include <sys/mman.h> 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 <bits/mman-linux.h>
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 <bits/sigcontext.h> directly; include <signal.h> 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 <macro@codesourcery.com>.
+
+   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 <sysdep.h>
+#include <sys/asm.h>
+
+#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 <sysdep.h>
+#include <sys/asm.h>
+#include <sys/ucontext.h>
+#include <stdarg.h>
+#include <assert.h>
+
+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 <aj@suse.de>, 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 <unistd.h>
+#include <string.h>
+#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 <macro@codesourcery.com>.
+
+   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 <sysdep.h>
+#include <sys/asm.h>
+
+#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 <aj@suse.de>, 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 <sys/ucontext.h>
+
+#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 <macro@codesourcery.com>.
+
+   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 <sysdep.h>
+#include <sys/asm.h>
+
+#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 <features.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/user.h>
+#include <sys/ucontext.h>
+
+/* 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 <features.h>
+#include <signal.h>
+
+/* We need the signal context definitions even if they are not used
+   included in <signal.h>.  */
+#include <bits/sigcontext.h>
+
+/* 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 <asm/ptrace.h>
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 <inttypes.h>
+#include <signal.h>
+#include <stddef.h>
+#include <sys/ucontext.h>
+
+-- 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)