about summary refs log tree commit diff
path: root/sysdeps/unix/sysv
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv')
-rw-r--r--sysdeps/unix/sysv/linux/riscv/bits/fcntl.h62
-rw-r--r--sysdeps/unix/sysv/linux/riscv/bits/mman.h36
-rw-r--r--sysdeps/unix/sysv/linux/riscv/bits/sigcontext.h32
-rw-r--r--sysdeps/unix/sysv/linux/riscv/dl-cache.h75
-rw-r--r--sysdeps/unix/sysv/linux/riscv/flush-icache.c73
-rw-r--r--sysdeps/unix/sysv/linux/riscv/getcontext.S77
-rw-r--r--sysdeps/unix/sysv/linux/riscv/init-first.c58
-rw-r--r--sysdeps/unix/sysv/linux/riscv/libc-vdso.h38
-rw-r--r--sysdeps/unix/sysv/linux/riscv/makecontext.c78
-rw-r--r--sysdeps/unix/sysv/linux/riscv/readelflib.c96
-rw-r--r--sysdeps/unix/sysv/linux/riscv/register-dump.h63
-rw-r--r--sysdeps/unix/sysv/linux/riscv/rv64/jmp_buf-macros.h53
-rw-r--r--sysdeps/unix/sysv/linux/riscv/setcontext.S114
-rw-r--r--sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h28
-rw-r--r--sysdeps/unix/sysv/linux/riscv/swapcontext.S125
-rw-r--r--sysdeps/unix/sysv/linux/riscv/sys/cachectl.h32
-rw-r--r--sysdeps/unix/sysv/linux/riscv/sys/procfs.h114
-rw-r--r--sysdeps/unix/sysv/linux/riscv/sys/ucontext.h110
-rw-r--r--sysdeps/unix/sysv/linux/riscv/sys/user.h23
-rw-r--r--sysdeps/unix/sysv/linux/riscv/ucontext-macros.h49
-rw-r--r--sysdeps/unix/sysv/linux/riscv/ucontext_i.sym31
21 files changed, 1367 insertions, 0 deletions
diff --git a/sysdeps/unix/sysv/linux/riscv/bits/fcntl.h b/sysdeps/unix/sysv/linux/riscv/bits/fcntl.h
new file mode 100644
index 0000000000..6bea085c70
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/bits/fcntl.h
@@ -0,0 +1,62 @@
+/* O_*, F_*, FD_* bit values for Linux / RISC-V.
+   Copyright (C) 2011-2018 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef	_FCNTL_H
+# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
+#endif
+
+#include <bits/wordsize.h>
+
+/* In 64-bit ISA files are always with 64bit off_t and F_*LK64 are the same as
+   non-64-bit versions.  It will need to be revised for 128-bit.  */
+#if __WORDSIZE == 64
+# define __O_LARGEFILE	0
+
+# define F_GETLK64	5	/* Get record locking info.  */
+# define F_SETLK64	6	/* Set record locking info (non-blocking).  */
+# define F_SETLKW64	7	/* Set record locking info (blocking).	*/
+#endif
+
+struct flock
+  {
+    short int l_type;   /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK.  */
+    short int l_whence; /* Where `l_start' is relative to (like `lseek').  */
+#if __WORDSIZE == 64 || !defined __USE_FILE_OFFSET64
+    __off_t l_start;    /* Offset where the lock begins.  */
+    __off_t l_len;      /* Size of the locked area; zero means until EOF.  */
+#else
+    __off64_t l_start;  /* Offset where the lock begins.  */
+    __off64_t l_len;    /* Size of the locked area; zero means until EOF.  */
+#endif
+    __pid_t l_pid;      /* Process holding the lock.  */
+  };
+
+#ifdef __USE_LARGEFILE64
+struct flock64
+  {
+    short int l_type;   /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK.  */
+    short int l_whence; /* Where `l_start' is relative to (like `lseek').  */
+    __off64_t l_start;  /* Offset where the lock begins.  */
+    __off64_t l_len;    /* Size of the locked area; zero means until EOF.  */
+    __pid_t l_pid;      /* Process holding the lock.  */
+  };
+#endif
+
+/* Include generic Linux declarations.  */
+#include <bits/fcntl-linux.h>
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..0e64f1eea7
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/bits/mman.h
@@ -0,0 +1,36 @@
+/* Definitions for POSIX memory map interface.  Linux/RISC-V version.
+   Copyright (C) 1997-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#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..9b896a6262
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/bits/sigcontext.h
@@ -0,0 +1,32 @@
+/* Machine-dependent signal context structure for Linux.  RISC-V version.
+   Copyright (C) 1996-2018 Free Software
+   Foundation, Inc.  This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#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 int gregs[32];
+  unsigned long long int fpregs[66] __attribute__ ((__aligned__ (16)));
+};
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/riscv/dl-cache.h b/sysdeps/unix/sysv/linux/riscv/dl-cache.h
new file mode 100644
index 0000000000..cbd6ef5e09
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/dl-cache.h
@@ -0,0 +1,75 @@
+/* Support for reading /etc/ld.so.cache files written by Linux ldconfig.
+   Copyright (C) 2003-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <ldconfig.h>
+
+/* For now we only support the natural XLEN ABI length on all targets, so the
+   only bits that need to go into ld.so.cache are the FLEG ABI length.  */
+#if defined __riscv_float_abi_double
+# define _DL_CACHE_DEFAULT_ID    (FLAG_RISCV_FLOAT_ABI_DOUBLE | FLAG_ELF_LIBC6)
+#else
+# define _DL_CACHE_DEFAULT_ID    (FLAG_RISCV_FLOAT_ABI_SOFT | FLAG_ELF_LIBC6)
+#endif
+
+#define _dl_cache_check_flags(flags)		    			\
+  ((flags) == _DL_CACHE_DEFAULT_ID)
+
+/* If given a path to one of our library directories, adds every library
+   directory via add_dir (), otherwise just adds the giver directory.  On
+   RISC-V, libraries can be found in paths ending in:
+     - /lib64/lp64d
+     - /lib64/lp64
+     - /lib (only ld.so)
+   so this will add all of those paths.
+
+   According to Joseph Myers:
+       My reasoning for that would be: generic autoconf-configured (etc.)
+       software may only know about using the lib directory, so you want the
+       lib directory to be searched regardless of the ABI - but it's also
+       useful to be able to e.g. list /usr/local/lib in /etc/ld.so.conf for all
+       architectures and have that automatically imply /usr/local/lib64/lp64d
+       etc. so that libraries can be found that come from software that does
+       use the ABI-specific directories.  */
+#define add_system_dir(dir) 						\
+  do							    		\
+    {									\
+      size_t len = strlen (dir);					\
+      char path[len + 9];						\
+      memcpy (path, dir, len + 1);					\
+      if (len >= 12 && ! memcmp(path + len - 12, "/lib64/lp64d", 12))	\
+	{								\
+	  len -= 8;							\
+	  path[len] = '\0';						\
+	}								\
+      if (len >= 11 && ! memcmp(path + len - 11, "/lib64/lp64", 11))	\
+	{								\
+	  len -= 7;							\
+	  path[len] = '\0';						\
+	}								\
+      add_dir (path);							\
+      if (len >= 4 && ! memcmp(path + len - 4, "/lib", 4))		\
+	{								\
+	  memcpy (path + len, "64/lp64d", 9);				\
+	  add_dir (path);						\
+	  memcpy (path + len, "64/lp64", 8);				\
+	  add_dir (path);						\
+	}								\
+    } while (0)
+
+
+#include_next <dl-cache.h>
diff --git a/sysdeps/unix/sysv/linux/riscv/flush-icache.c b/sysdeps/unix/sysv/linux/riscv/flush-icache.c
new file mode 100644
index 0000000000..d612ef4c6c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/flush-icache.c
@@ -0,0 +1,73 @@
+/* RISC-V instruction cache flushing VDSO calls
+   Copyright (C) 2017-2018 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <dl-vdso.h>
+#include <stdlib.h>
+#include <atomic.h>
+#include <sys/cachectl.h>
+#include <asm/syscalls.h>
+
+typedef int (*func_type) (void *, void *, unsigned long int);
+
+static int
+__riscv_flush_icache_syscall (void *start, void *end, unsigned long int flags)
+{
+  return INLINE_SYSCALL (riscv_flush_icache, 3, start, end, flags);
+}
+
+static func_type
+__lookup_riscv_flush_icache (void)
+{
+  PREPARE_VERSION_KNOWN (linux_version, LINUX_4_15);
+
+  func_type func = _dl_vdso_vsym ("__vdso_flush_icache", &linux_version);
+
+  /* If there is no vDSO entry then call the system call directly.  All Linux
+     versions provide the vDSO entry, but QEMU's user-mode emulation doesn't
+     provide a vDSO.  */
+  if (!func)
+    func = &__riscv_flush_icache_syscall;
+
+  return func;
+}
+
+#ifdef SHARED
+
+# define INIT_ARCH()
+libc_ifunc (__riscv_flush_icache, __lookup_riscv_flush_icache ())
+
+#else
+
+int
+__riscv_flush_icache (void *start, void *end, unsigned long int flags)
+{
+  static volatile func_type cached_func;
+
+  func_type func = atomic_load_relaxed (&cached_func);
+
+  if (!func)
+    {
+      func = __lookup_riscv_flush_icache ();
+      atomic_store_relaxed (&cached_func, func);
+    }
+
+  return func (start, end, flags);
+}
+
+#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..bde350f721
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/getcontext.S
@@ -0,0 +1,77 @@
+/* Save current context.
+   Copyright (C) 2009-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "ucontext-macros.h"
+
+/* int getcontext (ucontext_t *ucp) */
+
+	.text
+LEAF (__getcontext)
+	SAVE_INT_REG (ra,   0, a0)
+	SAVE_INT_REG (ra,   1, a0)
+	SAVE_INT_REG (sp,   2, a0)
+	SAVE_INT_REG (s0,   8, a0)
+	SAVE_INT_REG (s1,   9, a0)
+	SAVE_INT_REG (x0,  10, a0)	/* return 0 by overwriting a0.  */
+	SAVE_INT_REG (s2,  18, a0)
+	SAVE_INT_REG (s3,  19, a0)
+	SAVE_INT_REG (s4,  20, a0)
+	SAVE_INT_REG (s5,  21, a0)
+	SAVE_INT_REG (s6,  22, a0)
+	SAVE_INT_REG (s7,  23, a0)
+	SAVE_INT_REG (s8,  24, a0)
+	SAVE_INT_REG (s9,  25, a0)
+	SAVE_INT_REG (s10, 26, a0)
+	SAVE_INT_REG (s11, 27, a0)
+
+#ifndef __riscv_float_abi_soft
+	frsr	a1
+
+	SAVE_FP_REG (fs0,   8, a0)
+	SAVE_FP_REG (fs1,   9, a0)
+	SAVE_FP_REG (fs2,  18, a0)
+	SAVE_FP_REG (fs3,  19, a0)
+	SAVE_FP_REG (fs4,  20, a0)
+	SAVE_FP_REG (fs5,  21, a0)
+	SAVE_FP_REG (fs6,  22, a0)
+	SAVE_FP_REG (fs7,  23, a0)
+	SAVE_FP_REG (fs8,  24, a0)
+	SAVE_FP_REG (fs9,  25, a0)
+	SAVE_FP_REG (fs10, 26, a0)
+	SAVE_FP_REG (fs11, 27, 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/init-first.c b/sysdeps/unix/sysv/linux/riscv/init-first.c
new file mode 100644
index 0000000000..56abe51d96
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/init-first.c
@@ -0,0 +1,58 @@
+/* RISC-V VDSO initialization
+   Copyright (C) 2017-2018 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifdef SHARED
+# include <dl-vdso.h>
+# include <libc-vdso.h>
+
+long int (*VDSO_SYMBOL (getcpu)) (unsigned int *, unsigned int *, void *)
+    attribute_hidden;
+long int (*VDSO_SYMBOL (gettimeofday)) (struct timeval *, void *)
+    attribute_hidden;
+long int (*VDSO_SYMBOL (clock_gettime)) (clockid_t, struct timespec *)
+    attribute_hidden;
+long int (*VDSO_SYMBOL (clock_getres)) (clockid_t, struct timespec *)
+    attribute_hidden;
+
+static inline void
+_libc_vdso_platform_setup (void)
+{
+  PREPARE_VERSION_KNOWN (linux_version, LINUX_4_15);
+
+  void *p = _dl_vdso_vsym ("__vdso_getcpu", &linux_version);
+  PTR_MANGLE (p);
+  VDSO_SYMBOL (getcpu) = p;
+
+  p = _dl_vdso_vsym ("__vdso_gettimeofday", &linux_version);
+  PTR_MANGLE (p);
+  VDSO_SYMBOL (gettimeofday) = p;
+
+  p = _dl_vdso_vsym ("__vdso_clock_gettime", &linux_version);
+  PTR_MANGLE (p);
+  VDSO_SYMBOL (clock_gettime) = p;
+
+  p = _dl_vdso_vsym ("__vdso_clock_getres", &linux_version);
+  PTR_MANGLE (p);
+  VDSO_SYMBOL (clock_getres) = p;
+}
+
+# define VDSO_SETUP _libc_vdso_platform_setup
+#endif
+
+#include <csu/init-first.c>
diff --git a/sysdeps/unix/sysv/linux/riscv/libc-vdso.h b/sysdeps/unix/sysv/linux/riscv/libc-vdso.h
new file mode 100644
index 0000000000..1d44b34e02
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/libc-vdso.h
@@ -0,0 +1,38 @@
+/* RISC-V VDSO function declarations
+   Copyright (C) 2017-2018 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _LIBC_VDSO_H
+#define _LIBC_VDSO_H
+
+#ifdef SHARED
+
+# include <sysdep-vdso.h>
+
+extern long int (*VDSO_SYMBOL (getcpu)) (unsigned int *, unsigned int *, void *)
+    attribute_hidden;
+extern long int (*VDSO_SYMBOL (gettimeofday)) (struct timeval *, void *)
+    attribute_hidden;
+extern long int (*VDSO_SYMBOL (clock_gettime)) (clockid_t, struct timespec *)
+    attribute_hidden;
+extern long int (*VDSO_SYMBOL (clock_getres)) (clockid_t, struct timespec *)
+    attribute_hidden;
+
+#endif
+
+#endif /* _LIBC_VDSO_H */
diff --git a/sysdeps/unix/sysv/linux/riscv/makecontext.c b/sysdeps/unix/sysv/linux/riscv/makecontext.c
new file mode 100644
index 0000000000..b8054a29b0
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/makecontext.c
@@ -0,0 +1,78 @@
+/* Create new context.  RISC-V version.
+   Copyright (C) 2001-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#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 int a0, long int a1, long int a2, long int a3, long int a4,
+	       ...)
+{
+  extern void __start_context (void) attribute_hidden;
+  long int i, sp;
+
+  _Static_assert (REG_NARGS == 8, "__makecontext assumes 8 argument registers");
+
+  /* Set up the stack.  */
+  sp = ((long int) 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;
+  ucp->uc_mcontext.__gregs[REG_S1] = (long int) func;
+  ucp->uc_mcontext.__gregs[REG_S2] = (long int) ucp->uc_link;
+  ucp->uc_mcontext.__gregs[REG_SP] = sp;
+  ucp->uc_mcontext.__gregs[REG_PC] = (long int) &__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 (__glibc_unlikely (argc > 5))
+    {
+      va_list vl;
+      va_start (vl, a4);
+
+      long reg_args = argc < REG_NARGS ? argc : REG_NARGS;
+      for (i = 5; i < reg_args; i++)
+        ucp->uc_mcontext.__gregs[REG_A0 + i] = va_arg (vl, long);
+
+      long int stack_args = argc - reg_args;
+      if (stack_args > 0)
+	{
+	  sp = (sp - stack_args * sizeof (long int)) & ALMASK;
+	  ucp->uc_mcontext.__gregs[REG_SP] = sp;
+	  for (i = 0; i < stack_args; i++)
+	    ((long int *) sp)[i] = va_arg (vl, long int);
+	}
+
+      va_end (vl);
+    }
+}
+
+weak_alias (__makecontext, makecontext)
diff --git a/sysdeps/unix/sysv/linux/riscv/readelflib.c b/sysdeps/unix/sysv/linux/riscv/readelflib.c
new file mode 100644
index 0000000000..6e249ff82f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/readelflib.c
@@ -0,0 +1,96 @@
+/* Support for reading ELF files.
+   Copyright (C) 1999-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+
+int process_elf32_file (const char *file_name, const char *lib, int *flag,
+			unsigned int *osversion, char **soname,
+			void *file_contents, size_t file_length);
+int process_elf64_file (const char *file_name, const char *lib, int *flag,
+			unsigned int *osversion, char **soname,
+			void *file_contents, size_t file_length);
+
+/* The ELF flags supported by our current glibc port:
+   - EF_RISCV_FLOAT_ABI: We support the soft and double ABIs.
+   - EF_RISCV_RVC: While the Linux ABI mandates the presence of the C
+     extension, we can still support libraries compiled without that extension
+     so we just ignore this flag.
+   - EF_RISCV_RVE: glibc (and Linux) don't support RV32E based systems.
+   - EF_RISCV_TSO: The TSO extension isn't supported, as doing so would require
+     some mechanism to ensure that the TSO extension is enabled which doesn't
+     currently exist.  */
+#define SUPPORTED_ELF_FLAGS (EF_RISCV_FLOAT_ABI | EF_RISCV_RVC)
+
+/* Returns 0 if everything is ok, != 0 in case of error.  */
+int
+process_elf_file (const char *file_name, const char *lib, int *flag,
+		  unsigned int *osversion, char **soname, void *file_contents,
+		  size_t file_length)
+{
+  ElfW(Ehdr) *elf_header = (ElfW(Ehdr) *) file_contents;
+  Elf32_Ehdr *elf32_header = (Elf32_Ehdr *) elf_header;
+  int ret;
+  long flags;
+
+  /* RISC-V libraries are always libc.so.6+.  */
+  *flag = FLAG_ELF_LIBC6;
+
+  if (elf_header->e_ident [EI_CLASS] == ELFCLASS32)
+    {
+      ret = process_elf32_file (file_name, lib, flag, osversion, soname,
+				file_contents, file_length);
+      flags = elf32_header->e_flags;
+    }
+  else
+    {
+      ret = process_elf64_file (file_name, lib, flag, osversion, soname,
+				file_contents, file_length);
+      flags = elf32_header->e_flags;
+    }
+
+  /* RISC-V linkers encode the floating point ABI as part of the ELF headers.  */
+  switch (flags & EF_RISCV_FLOAT_ABI)
+    {
+      case EF_RISCV_FLOAT_ABI_SOFT:
+        *flag |= FLAG_RISCV_FLOAT_ABI_SOFT;
+	break;
+      case EF_RISCV_FLOAT_ABI_DOUBLE:
+        *flag |= FLAG_RISCV_FLOAT_ABI_DOUBLE;
+	break;
+      default:
+        return 1;
+    }
+
+  /* If there are any other ELF flags set then glibc doesn't support this
+     library.  */
+  if (flags & ~SUPPORTED_ELF_FLAGS)
+    return 1;
+
+  return ret;
+}
+
+#undef __ELF_NATIVE_CLASS
+#undef process_elf_file
+#define process_elf_file process_elf32_file
+#define __ELF_NATIVE_CLASS 32
+#include "elf/readelflib.c"
+
+#undef __ELF_NATIVE_CLASS
+#undef process_elf_file
+#define process_elf_file process_elf64_file
+#define __ELF_NATIVE_CLASS 64
+#include "elf/readelflib.c"
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..234ce630f9
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/register-dump.h
@@ -0,0 +1,63 @@
+/* Dump registers.
+   Copyright (C) 2000-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <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, ucontext_t *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/rv64/jmp_buf-macros.h b/sysdeps/unix/sysv/linux/riscv/rv64/jmp_buf-macros.h
new file mode 100644
index 0000000000..34434a8d93
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/jmp_buf-macros.h
@@ -0,0 +1,53 @@
+/* jump buffer constants for RISC-V
+   Copyright (C) 2017-2018 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Produced by this program:
+
+   #include <stdio.h>
+   #include <unistd.h>
+   #include <setjmp.h>
+   #include <stddef.h>
+
+   int main (int argc, char **argv)
+   {
+       printf ("#define JMP_BUF_SIZE %d\n", sizeof (jmp_buf));
+       printf ("#define JMP_BUF_ALIGN %d\n", __alignof__ (jmp_buf));
+       printf ("#define SIGJMP_BUF_SIZE %d\n", sizeof (sigjmp_buf));
+       printf ("#define SIGJMP_BUF_ALIGN %d\n", __alignof__ (sigjmp_buf));
+       printf ("#define MASK_WAS_SAVED_OFFSET %d\n", offsetof (struct __jmp_buf_tag, __mask_was_saved));
+       printf ("#define SAVED_MASK_OFFSET %d\n", offsetof (struct __jmp_buf_tag, __saved_mask));
+   } */
+
+#if defined __riscv_float_abi_soft
+# define JMP_BUF_SIZE 248
+# define JMP_BUF_ALIGN 8
+# define SIGJMP_BUF_SIZE 248
+# define SIGJMP_BUF_ALIGN 8
+# define MASK_WAS_SAVED_OFFSET 112
+# define SAVED_MASK_OFFSET 120
+#elif defined __riscv_float_abi_double
+# define JMP_BUF_SIZE 344
+# define JMP_BUF_ALIGN 8
+# define SIGJMP_BUF_SIZE 344
+# define SIGJMP_BUF_ALIGN 8
+# define MASK_WAS_SAVED_OFFSET 208
+# define SAVED_MASK_OFFSET 216
+#else
+# error "Unknown RISC-V floating-point ABI"
+#endif
diff --git a/sysdeps/unix/sysv/linux/riscv/setcontext.S b/sysdeps/unix/sysv/linux/riscv/setcontext.S
new file mode 100644
index 0000000000..9f1c7b41fd
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/setcontext.S
@@ -0,0 +1,114 @@
+/* Set current context.
+   Copyright (C) 2009-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "ucontext-macros.h"
+
+/*  int __setcontext (const ucontext_t *ucp)
+
+  Restores the machine context in UCP and thereby resumes execution
+  in that context.
+
+  This implementation is intended to be used for *synchronous* context
+  switches only.  Therefore, it does not have to restore anything
+  other than the PRESERVED state.  */
+
+	.text
+LEAF (__setcontext)
+
+	mv	t0, a0	/* Save ucp into t0.  */
+
+/* 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.  */
+	RESTORE_INT_REG     (t1,   0, 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..3ca8a80d8b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h
@@ -0,0 +1,28 @@
+/* RISC-V definitions for signal handling calling conventions.
+   Copyright (C) 2000-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sys/ucontext.h>
+
+#define SIGCONTEXT siginfo_t *_si, ucontext_t *
+#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..75b58dc668
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/swapcontext.S
@@ -0,0 +1,125 @@
+/* Save and set current context.
+   Copyright (C) 2009-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "ucontext-macros.h"
+
+/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */
+
+LEAF (__swapcontext)
+	mv	t0, a1			/* Save ucp into t0.  */
+
+	SAVE_INT_REG (ra,   0, a0)
+	SAVE_INT_REG (ra,   1, a0)
+	SAVE_INT_REG (sp,   2, a0)
+	SAVE_INT_REG (s0,   8, a0)
+	SAVE_INT_REG (s1,   9, a0)
+	SAVE_INT_REG (x0,  10, a0)	/* return 0 by overwriting a0.  */
+	SAVE_INT_REG (s2,  18, a0)
+	SAVE_INT_REG (s3,  19, a0)
+	SAVE_INT_REG (s4,  20, a0)
+	SAVE_INT_REG (s5,  21, a0)
+	SAVE_INT_REG (s6,  22, a0)
+	SAVE_INT_REG (s7,  23, a0)
+	SAVE_INT_REG (s8,  24, a0)
+	SAVE_INT_REG (s9,  25, a0)
+	SAVE_INT_REG (s10, 26, a0)
+	SAVE_INT_REG (s11, 27, a0)
+
+#ifndef __riscv_float_abi_soft
+	frsr a1
+
+	SAVE_FP_REG (fs0,   8, a0)
+	SAVE_FP_REG (fs1,   9, a0)
+	SAVE_FP_REG (fs2,  18, a0)
+	SAVE_FP_REG (fs3,  19, a0)
+	SAVE_FP_REG (fs4,  20, a0)
+	SAVE_FP_REG (fs5,  21, a0)
+	SAVE_FP_REG (fs6,  22, a0)
+	SAVE_FP_REG (fs7,  23, a0)
+	SAVE_FP_REG (fs8,  24, a0)
+	SAVE_FP_REG (fs9,  25, a0)
+	SAVE_FP_REG (fs10, 26, a0)
+	SAVE_FP_REG (fs11, 27, a0)
+
+	sw	a1, MCONTEXT_FSR(a0)
+#endif /* __riscv_float_abi_soft */
+
+/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask, _NSIG8) */
+	li	a3, _NSIG8
+	add	a2, a0, UCONTEXT_SIGMASK
+	add     a1, t0, 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)
+
+	RESTORE_FP_REG (fs0,   8, t0)
+	RESTORE_FP_REG (fs1,   9, t0)
+	RESTORE_FP_REG (fs2,  18, t0)
+	RESTORE_FP_REG (fs3,  19, t0)
+	RESTORE_FP_REG (fs4,  20, t0)
+	RESTORE_FP_REG (fs5,  21, t0)
+	RESTORE_FP_REG (fs6,  22, t0)
+	RESTORE_FP_REG (fs7,  23, t0)
+	RESTORE_FP_REG (fs8,  24, t0)
+	RESTORE_FP_REG (fs9,  25, t0)
+	RESTORE_FP_REG (fs10, 26, t0)
+	RESTORE_FP_REG (fs11, 27, t0)
+
+	fssr	t1
+#endif /* __riscv_float_abi_soft */
+
+	/* Note the contents of argument registers will be random
+	   unless makecontext() has been called.  */
+	RESTORE_INT_REG (t1,   0, t0)
+	RESTORE_INT_REG (ra,   1, t0)
+	RESTORE_INT_REG (sp,   2, t0)
+	RESTORE_INT_REG (s0,   8, t0)
+	RESTORE_INT_REG (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 (s2,  18, t0)
+	RESTORE_INT_REG (s3,  19, t0)
+	RESTORE_INT_REG (s4,  20, t0)
+	RESTORE_INT_REG (s5,  21, t0)
+	RESTORE_INT_REG (s6,  22, t0)
+	RESTORE_INT_REG (s7,  23, t0)
+	RESTORE_INT_REG (s8,  24, t0)
+	RESTORE_INT_REG (s9,  25, t0)
+	RESTORE_INT_REG (s10, 26, t0)
+	RESTORE_INT_REG (s11, 27, t0)
+
+	jr	t1
+
+
+99:	j	__syscall_error
+
+PSEUDO_END (__swapcontext)
+
+weak_alias (__swapcontext, swapcontext)
diff --git a/sysdeps/unix/sysv/linux/riscv/sys/cachectl.h b/sysdeps/unix/sysv/linux/riscv/sys/cachectl.h
new file mode 100644
index 0000000000..46a2cb6082
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/sys/cachectl.h
@@ -0,0 +1,32 @@
+/* RISC-V instruction cache flushing interface
+   Copyright (C) 2017-2018 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_CACHECTL_H
+#define _SYS_CACHECTL_H 1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+extern int __riscv_flush_icache (void *__start, void *__end,
+				 unsigned long int __flags);
+
+__END_DECLS
+
+#endif /* sys/cachectl.h */
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..518de56741
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/sys/procfs.h
@@ -0,0 +1,114 @@
+/* Core image file related definitions, RISC-V version.
+   Copyright (C) 1996-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#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 unsigned long int elf_greg_t;
+typedef unsigned long int elf_gregset_t[32];
+typedef union __riscv_mc_fp_state 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 int pr_uid;
+    long 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 <proc_service.h> 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 habe only ine 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/riscv/sys/ucontext.h b/sysdeps/unix/sysv/linux/riscv/sys/ucontext.h
new file mode 100644
index 0000000000..7df430b504
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/sys/ucontext.h
@@ -0,0 +1,110 @@
+/* struct ucontext definition, RISC-V version.
+   Copyright (C) 1997-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* 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 <bits/types/sigset_t.h>
+#include <bits/types/stack_t.h>
+
+typedef unsigned long int __riscv_mc_gp_state[32];
+
+#ifdef __USE_MISC
+# define NGREG	32
+
+# define REG_PC 0
+# define REG_RA 1
+# define REG_SP 2
+# define REG_TP 4
+# define REG_S0 8
+# define REG_S1 9
+# define REG_A0 10
+# define REG_S2 18
+# define REG_NARGS 8
+
+typedef unsigned long int greg_t;
+
+/* Container for all general registers.  */
+typedef __riscv_mc_gp_state gregset_t;
+
+/* Container for floating-point state.  */
+typedef union __riscv_mc_fp_state fpregset_t;
+#endif
+
+struct __riscv_mc_f_ext_state
+  {
+    unsigned int __f[32];
+    unsigned int __fcsr;
+  };
+
+struct __riscv_mc_d_ext_state
+  {
+    unsigned long long int __f[32];
+    unsigned int __fcsr;
+  };
+
+struct __riscv_mc_q_ext_state
+  {
+    unsigned long long int __f[64] __attribute__ ((__aligned__ (16)));
+    unsigned int __fcsr;
+    /* Reserved for expansion of sigcontext structure.  Currently zeroed
+       upon signal, and must be zero upon sigreturn.  */
+    unsigned int __glibc_reserved[3];
+  };
+
+union __riscv_mc_fp_state
+  {
+    struct __riscv_mc_f_ext_state __f;
+    struct __riscv_mc_d_ext_state __d;
+    struct __riscv_mc_q_ext_state __q;
+  };
+
+typedef struct mcontext_t
+  {
+    __riscv_mc_gp_state __gregs;
+    union  __riscv_mc_fp_state __fpregs;
+  } mcontext_t;
+
+/* Userlevel context.  */
+typedef struct ucontext_t
+  {
+    unsigned long int  __uc_flags;
+    struct ucontext_t *uc_link;
+    stack_t            uc_stack;
+    sigset_t           uc_sigmask;
+    /* There's some padding here to allow sigset_t to be expanded in the
+       future.  Though this is unlikely, other architectures put uc_sigmask
+       at the end of this structure and explicitly state it can be
+       expanded, so we didn't want to box ourselves in here.  */
+    char               __glibc_reserved[1024 / 8 - sizeof (sigset_t)];
+    /* We can't put uc_sigmask at the end of this structure because we need
+       to be able to expand sigcontext in the future.  For example, the
+       vector ISA extension will almost certainly add ISA state.  We want
+       to ensure all user-visible ISA state can be saved and restored via a
+       ucontext, so we're putting this at the end in order to allow for
+       infinite extensibility.  Since we know this will be extended and we
+       assume sigset_t won't be extended an extreme amount, we're
+       prioritizing this.  */
+    mcontext_t uc_mcontext;
+  } 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..7e648f2d5c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/sys/user.h
@@ -0,0 +1,23 @@
+/* Copyright (C) 2001-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_USER_H
+#define _SYS_USER_H	1
+
+
+
+#endif	/* _SYS_USER_H */
diff --git a/sysdeps/unix/sysv/linux/riscv/ucontext-macros.h b/sysdeps/unix/sysv/linux/riscv/ucontext-macros.h
new file mode 100644
index 0000000000..a73c3a9b04
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/ucontext-macros.h
@@ -0,0 +1,49 @@
+/* Macros for ucontext routines.
+   Copyright (C) 2017-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _LINUX_RISCV_UCONTEXT_MACROS_H
+#define _LINUX_RISCV_UCONTEXT_MACROS_H
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+#include "ucontext_i.h"
+
+#define MCONTEXT_FSR (32 * SZFREG + MCONTEXT_FPREGS)
+
+#define SAVE_FP_REG(name, num, base)			\
+  FREG_S name, ((num) * SZFREG + MCONTEXT_FPREGS)(base)
+
+#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) * SZFREG + MCONTEXT_FPREGS)
+
+#define SAVE_INT_REG(name, num, base)			\
+  REG_S name, ((num) * SZREG + MCONTEXT_GREGS)(base)
+
+#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)
+
+#endif /* _LINUX_RISCV_UCONTEXT_MACROS_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..be55b26310
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/ucontext_i.sym
@@ -0,0 +1,31 @@
+#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)
+
+UCONTEXT_SIZE			sizeof (ucontext_t)