diff mbox series

[v4,13/17] RISC-V: Linux ABI

Message ID 20180113103816.4861-14-palmer@dabbelt.com
State New
Headers show
Series [v4,01/17] Skeleton documentation for the RISC-V port | expand

Commit Message

Palmer Dabbelt Jan. 13, 2018, 10:38 a.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/pthread-offsets.h               |  24 ++++
 sysdeps/riscv/nptl/pthreaddef.h                    |  32 ++++++
 sysdeps/unix/sysv/linux/riscv/bits/fcntl.h         |  62 ++++++++++
 sysdeps/unix/sysv/linux/riscv/bits/mman.h          |  36 ++++++
 sysdeps/unix/sysv/linux/riscv/bits/sigcontext.h    |  32 ++++++
 sysdeps/unix/sysv/linux/riscv/flush-icache.c       |  76 ++++++++++++
 sysdeps/unix/sysv/linux/riscv/getcontext.S         |  77 +++++++++++++
 sysdeps/unix/sysv/linux/riscv/init-first.c         |  58 ++++++++++
 sysdeps/unix/sysv/linux/riscv/libc-vdso.h          |  38 ++++++
 sysdeps/unix/sysv/linux/riscv/makecontext.c        |  72 ++++++++++++
 sysdeps/unix/sysv/linux/riscv/readelflib.c         |  92 +++++++++++++++
 sysdeps/unix/sysv/linux/riscv/register-dump.h      |  63 ++++++++++
 .../unix/sysv/linux/riscv/rv32/jmp_buf-macros.h    |  53 +++++++++
 .../unix/sysv/linux/riscv/rv64/jmp_buf-macros.h    |  53 +++++++++
 sysdeps/unix/sysv/linux/riscv/setcontext.S         | 114 ++++++++++++++++++
 sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h     |  28 +++++
 sysdeps/unix/sysv/linux/riscv/swapcontext.S        | 125 ++++++++++++++++++++
 sysdeps/unix/sysv/linux/riscv/sys/cachectl.h       |  32 ++++++
 sysdeps/unix/sysv/linux/riscv/sys/procfs.h         | 114 ++++++++++++++++++
 sysdeps/unix/sysv/linux/riscv/sys/ucontext.h       | 108 +++++++++++++++++
 sysdeps/unix/sysv/linux/riscv/sys/user.h           |  23 ++++
 sysdeps/unix/sysv/linux/riscv/sysdep-cancel.h      | 128 +++++++++++++++++++++
 sysdeps/unix/sysv/linux/riscv/ucontext-macros.h    |  49 ++++++++
 sysdeps/unix/sysv/linux/riscv/ucontext_i.sym       |  31 +++++
 24 files changed, 1520 insertions(+)
 create mode 100644 sysdeps/riscv/nptl/pthread-offsets.h
 create mode 100644 sysdeps/riscv/nptl/pthreaddef.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/bits/fcntl.h
 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/flush-icache.c
 create mode 100644 sysdeps/unix/sysv/linux/riscv/getcontext.S
 create mode 100644 sysdeps/unix/sysv/linux/riscv/init-first.c
 create mode 100644 sysdeps/unix/sysv/linux/riscv/libc-vdso.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/makecontext.c
 create mode 100644 sysdeps/unix/sysv/linux/riscv/readelflib.c
 create mode 100644 sysdeps/unix/sysv/linux/riscv/register-dump.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/rv32/jmp_buf-macros.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/rv64/jmp_buf-macros.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/cachectl.h
 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/sysdep-cancel.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/ucontext-macros.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/ucontext_i.sym

Comments

Joseph Myers Jan. 15, 2018, 5:37 p.m. UTC | #1
On Sat, 13 Jan 2018, Palmer Dabbelt wrote:

> +static int __riscv_flush_icache_syscall (void *start, void *end,
> +					 unsigned long int flags)
> +{
> +#ifdef __NR_riscv_flush_icache
> +	return INLINE_SYSCALL (riscv_flush_icache, 3, start, end, flags);
> +#else
> +	/* FIXME: This should go away, as it's actually not quite correct. */
> +	__asm__ volatile ("fence.i");
> +	return 0;
> +#endif

Shouldn't have this #ifdef.  Just assume that the __NR_riscv_flush_icache 
macro is present (I take it that it's in Linux 4.15) - 
architecture-specific code should only ever need #ifdefs on __NR_* if the 
syscall is newer than the oldest Linux kernel headers version supported by 
glibc for that architecture.

> diff --git a/sysdeps/unix/sysv/linux/riscv/readelflib.c b/sysdeps/unix/sysv/linux/riscv/readelflib.c
> new file mode 100644
> index 000000000000..c8475241e31e
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/riscv/readelflib.c
> @@ -0,0 +1,92 @@
> +/* Copyright (C) 1999-2018 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +   Contributed by Andreas Jaeger <aj@suse.de>, 1999 and
> +		  Jakub Jelinek <jakub@redhat.com>, 1999.

Remove "Contributed by".  Descriptive comment needed before copyright 
notice.

> +  /* 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;
> +      case EF_RISCV_FLOAT_ABI_QUAD:
> +        return 1;
> +    }

You have an error here for the quad ABI, I'd expect one for the single ABI 
(or just have "default:" for the error case, which amounts to the same 
thing).

> +  /* RISC-V Linux ABIs mandate the presence of the C extension.  */
> +  if (flags & EF_RISCV_RVC)
> +    return 1;

Given that C support is required in the processor, surely you *shouldn't* 
return 1 (error) for it?

> +  /* The remainder of the header bits are reserved, so just be on the safe side
> +     and don't support them at all.  */
> +  if (flags & SUPPORTED_ELF_FLAGS)
> +    return 1;

I read this as returning 1 (failure) if EF_RISCV_FLOAT_ABI_DOUBLE is 
specified, simply because that happens to have a nonzero value.  Did you 
mean to use ~SUPPORTED_ELF_FLAGS in this test?  (And it's not actually 
true all the other bits are reserved, the ABI document defines 
EF_RISCV_RVE and EF_RISCV_TSO.)

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

> +extern int __riscv_flush_icache (void *start, void *end,
> +				 unsigned long int flags);

As noted, still missing leading __ on parameter names.

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

> +    /* 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               __unused[1024 / 8 - sizeof (sigset_t)];

Should use __glibc_reserved naming convention.
Palmer Dabbelt Jan. 23, 2018, 12:40 a.m. UTC | #2
On Mon, 15 Jan 2018 09:37:46 PST (-0800), joseph@codesourcery.com wrote:
> On Sat, 13 Jan 2018, Palmer Dabbelt wrote:
>
>> +static int __riscv_flush_icache_syscall (void *start, void *end,
>> +					 unsigned long int flags)
>> +{
>> +#ifdef __NR_riscv_flush_icache
>> +	return INLINE_SYSCALL (riscv_flush_icache, 3, start, end, flags);
>> +#else
>> +	/* FIXME: This should go away, as it's actually not quite correct. */
>> +	__asm__ volatile ("fence.i");
>> +	return 0;
>> +#endif
>
> Shouldn't have this #ifdef.  Just assume that the __NR_riscv_flush_icache
> macro is present (I take it that it's in Linux 4.15) -
> architecture-specific code should only ever need #ifdefs on __NR_* if the
> syscall is newer than the oldest Linux kernel headers version supported by
> glibc for that architecture.

Sorry about that -- this was added late to Linux so I put the FIXME version in 
there and forgot to remove it.

>> diff --git a/sysdeps/unix/sysv/linux/riscv/readelflib.c b/sysdeps/unix/sysv/linux/riscv/readelflib.c
>> new file mode 100644
>> index 000000000000..c8475241e31e
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/riscv/readelflib.c
>> @@ -0,0 +1,92 @@
>> +/* Copyright (C) 1999-2018 Free Software Foundation, Inc.
>> +   This file is part of the GNU C Library.
>> +   Contributed by Andreas Jaeger <aj@suse.de>, 1999 and
>> +		  Jakub Jelinek <jakub@redhat.com>, 1999.
>
> Remove "Contributed by".  Descriptive comment needed before copyright
> notice.

Thanks, I fixed it.  I copied this from elsewhere in glibc and I guess I forgot 
the rules.

>> +  /* 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;
>> +      case EF_RISCV_FLOAT_ABI_QUAD:
>> +        return 1;
>> +    }
>
> You have an error here for the quad ABI, I'd expect one for the single ABI
> (or just have "default:" for the error case, which amounts to the same
> thing).

Thanks for catching that.

>> +  /* RISC-V Linux ABIs mandate the presence of the C extension.  */
>> +  if (flags & EF_RISCV_RVC)
>> +    return 1;
>
> Given that C support is required in the processor, surely you *shouldn't*
> return 1 (error) for it?

Yes, sorry about that -- I had the test reversed.  After talking to some other 
people, we actually don't want to even check this here: it's legal to link C 
and non-C objects together, so we should support loading them together as well.

>> +  /* The remainder of the header bits are reserved, so just be on the safe side
>> +     and don't support them at all.  */
>> +  if (flags & SUPPORTED_ELF_FLAGS)
>> +    return 1;
>
> I read this as returning 1 (failure) if EF_RISCV_FLOAT_ABI_DOUBLE is
> specified, simply because that happens to have a nonzero value.  Did you
> mean to use ~SUPPORTED_ELF_FLAGS in this test?  (And it's not actually
> true all the other bits are reserved, the ABI document defines
> EF_RISCV_RVE and EF_RISCV_TSO.)

Yep, sorry, I had that backwards -- I guess I was being an idiot when writing 
this code, as multiple people have pointed out how poorly it went.  RVE and 
RVTSO aren't supported in glibc yet.  I've added a comment explaining this 
better

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

>> diff --git a/sysdeps/unix/sysv/linux/riscv/sys/cachectl.h b/sysdeps/unix/sysv/linux/riscv/sys/cachectl.h
>
>> +extern int __riscv_flush_icache (void *start, void *end,
>> +				 unsigned long int flags);
>
> As noted, still missing leading __ on parameter names.

Thanks.

>> diff --git a/sysdeps/unix/sysv/linux/riscv/sys/ucontext.h b/sysdeps/unix/sysv/linux/riscv/sys/ucontext.h
>
>> +    /* 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               __unused[1024 / 8 - sizeof (sigset_t)];
>
> Should use __glibc_reserved naming convention.

I've called it "__glibc_reserved", which from my reading is what I'm supposed 
to do?
Joseph Myers Jan. 23, 2018, 12:54 a.m. UTC | #3
On Mon, 22 Jan 2018, Palmer Dabbelt wrote:

> > Should use __glibc_reserved naming convention.
> 
> I've called it "__glibc_reserved", which from my reading is what I'm supposed
> to do?

Yes.
diff mbox series

Patch

diff --git a/sysdeps/riscv/nptl/pthread-offsets.h b/sysdeps/riscv/nptl/pthread-offsets.h
new file mode 100644
index 000000000000..5f7031834f42
--- /dev/null
+++ b/sysdeps/riscv/nptl/pthread-offsets.h
@@ -0,0 +1,24 @@ 
+/* RISC-V pthread offsets
+   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/>.  */
+
+#define __PTHREAD_MUTEX_NUSERS_OFFSET   12
+#define __PTHREAD_MUTEX_KIND_OFFSET     16
+#define __PTHREAD_MUTEX_SPINS_OFFSET    20
+#define __PTHREAD_MUTEX_ELISION_OFFSET  22
+#define __PTHREAD_MUTEX_LIST_OFFSET     24
diff --git a/sysdeps/riscv/nptl/pthreaddef.h b/sysdeps/riscv/nptl/pthreaddef.h
new file mode 100644
index 000000000000..442422aefb63
--- /dev/null
+++ b/sysdeps/riscv/nptl/pthreaddef.h
@@ -0,0 +1,32 @@ 
+/* pthread machine parameter definitions,  RISC-V version.
+   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/>.  */
+
+/* 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/unix/sysv/linux/riscv/bits/fcntl.h b/sysdeps/unix/sysv/linux/riscv/bits/fcntl.h
new file mode 100644
index 000000000000..6bea085c709c
--- /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 000000000000..ab33e05bc9c9
--- /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 000000000000..c50189c610a8
--- /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/flush-icache.c b/sysdeps/unix/sysv/linux/riscv/flush-icache.c
new file mode 100644
index 000000000000..e64d8091dbbb
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/flush-icache.c
@@ -0,0 +1,76 @@ 
+/* 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>
+
+typedef int (*func_type) (void *, void *, unsigned long int);
+
+static int __riscv_flush_icache_syscall (void *start, void *end,
+					 unsigned long int flags)
+{
+#ifdef __NR_riscv_flush_icache
+	return INLINE_SYSCALL (riscv_flush_icache, 3, start, end, flags);
+#else
+	/* FIXME: This should go away, as it's actually not quite correct. */
+	__asm__ volatile ("fence.i");
+	return 0;
+#endif
+}
+
+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);
+
+  /* The vDSO is required, as there is no exposed system call equivalent.  */
+  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 000000000000..70bfef31caee
--- /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 */
+	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 000000000000..56abe51d96cb
--- /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 000000000000..1d44b34e025f
--- /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 000000000000..6f808632f07c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/makecontext.c
@@ -0,0 +1,72 @@ 
+/* 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] = 0;
+  ucp->uc_mcontext.__gregs[REG_S0 + 1] = (long int) func;
+  ucp->uc_mcontext.__gregs[REG_S0 + 2] = (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 int reg_args = argc < REG_NARGS ? argc : REG_NARGS;
+      sp = (sp - (argc - reg_args) * sizeof (long int)) & ALMASK;
+      for (i = 5; i < reg_args; i++)
+        ucp->uc_mcontext.__gregs[REG_A0 + i] = va_arg (vl, long int);
+      for (i = 0; i < argc - reg_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 000000000000..c8475241e31e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/readelflib.c
@@ -0,0 +1,92 @@ 
+/* Copyright (C) 1999-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Andreas Jaeger <aj@suse.de>, 1999 and
+		  Jakub Jelinek <jakub@redhat.com>, 1999.
+
+   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);
+
+#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;
+      case EF_RISCV_FLOAT_ABI_QUAD:
+        return 1;
+    }
+
+  /* RISC-V Linux ABIs mandate the presence of the C extension.  */
+  if (flags & EF_RISCV_RVC)
+    return 1;
+
+  /* The remainder of the header bits are reserved, so just be on the safe side
+     and don't support them at all.  */
+  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 000000000000..234ce630f90f
--- /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/rv32/jmp_buf-macros.h b/sysdeps/unix/sysv/linux/riscv/rv32/jmp_buf-macros.h
new file mode 100644
index 000000000000..f7bedd70b6ff
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/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 188
+# define JMP_BUF_ALIGN 4
+# define SIGJMP_BUF_SIZE 188
+# define SIGJMP_BUF_ALIGN 4
+# define MASK_WAS_SAVED_OFFSET 56
+# define SAVED_MASK_OFFSET 60
+#elif defined __riscv_float_abi_double
+# define JMP_BUF_SIZE 288
+# define JMP_BUF_ALIGN 8
+# define SIGJMP_BUF_SIZE 288
+# define SIGJMP_BUF_ALIGN 8
+# define MASK_WAS_SAVED_OFFSET 152
+# define SAVED_MASK_OFFSET 156
+#else
+# error "Unknown RISC-V floating-point ABI"
+#endif
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 000000000000..1dc546fb1473
--- /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 000000000000..a1191bac3a25
--- /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					/* 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.  */
+	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 000000000000..3ca8a80d8b2e
--- /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 000000000000..e8a31510caf3
--- /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					/* t0 <- ucp */
+
+	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 */
+	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, 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)
+
+	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 000000000000..0e7e0912ffa0
--- /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 000000000000..518de567410d
--- /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 000000000000..92e8b8c174bc
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/sys/ucontext.h
@@ -0,0 +1,108 @@ 
+/* 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_A0 10
+# 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               __unused[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 000000000000..7e648f2d5ccd
--- /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/sysdep-cancel.h b/sysdeps/unix/sysv/linux/riscv/sysdep-cancel.h
new file mode 100644
index 000000000000..2b1f3ffeacd6
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/sysdep-cancel.h
@@ -0,0 +1,128 @@ 
+/* Assembler macros with cancellation support, RISC-V version.
+   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 <sysdep.h>
+#include <sysdeps/generic/sysdep.h>
+#include <tls.h>
+#ifndef __ASSEMBLER__
+# include <nptl/pthreadP.h>
+#endif
+#include <sys/asm.h>
+
+/* Gas will put the initial save of $gp into the CIE, because it appears to
+   happen before any instructions.  So we use cfi_same_value instead of
+   cfi_restore.  */
+
+#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)				\
+      .align 2;								\
+  L(pseudo_start):							\
+  99: j __syscall_error;						\
+  ENTRY (name)								\
+    SINGLE_THREAD_P(t0);						\
+    bnez t0, L(pseudo_cancel);  					\
+  .type __##syscall_name##_nocancel, @function;				\
+  .globl __##syscall_name##_nocancel;					\
+  __##syscall_name##_nocancel:						\
+    li a7, SYS_ify(syscall_name);					\
+    scall;								\
+    bltz a0, 99b;							\
+    ret;								\
+  .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel;	\
+  L(pseudo_cancel):							\
+    addi sp, sp, -STKSPACE;						\
+    REG_S ra, STKOFF_RA(sp);						\
+    cfi_rel_offset (ra, STKOFF_RA);					\
+    PUSHARGS_##args;			/* save syscall args */		\
+    CENABLE;								\
+    REG_S a0, STKOFF_SVMSK(sp);		/* save mask */			\
+    POPARGS_##args;			/* restore syscall args */	\
+    li a7, SYS_ify (syscall_name);					\
+    scall;								\
+    REG_S a0, STKOFF_A0(sp);		/* save syscall result */	\
+    REG_L a0, STKOFF_SVMSK(sp);		/* pass mask as arg1 */		\
+    CDISABLE;								\
+    REG_L ra, STKOFF_RA(sp);		/* restore return address */	\
+    REG_L a0, STKOFF_A0(sp);		/* restore syscall result */	\
+    addi sp, sp, STKSPACE;						\
+    bltz a0, 99b;							\
+  L(pseudo_end):
+
+
+# define PUSHARGS_0	/* nothing to do */
+# define PUSHARGS_1	PUSHARGS_0 REG_S a0, STKOFF_A0(sp); cfi_rel_offset (a0, STKOFF_A0);
+# define PUSHARGS_2	PUSHARGS_1 REG_S a1, STKOFF_A1(sp); cfi_rel_offset (a1, STKOFF_A1);
+# define PUSHARGS_3	PUSHARGS_2 REG_S a2, STKOFF_A2(sp); cfi_rel_offset (a2, STKOFF_A2);
+# define PUSHARGS_4	PUSHARGS_3 REG_S a3, STKOFF_A3(sp); cfi_rel_offset (a3, STKOFF_A3);
+# define PUSHARGS_5	PUSHARGS_4 REG_S a4, STKOFF_A4(sp); cfi_rel_offset (a4, STKOFF_A4);
+# define PUSHARGS_6	PUSHARGS_5 REG_S a5, STKOFF_A5(sp); cfi_rel_offset (a5, STKOFF_A5);
+
+# define POPARGS_0	/* nothing to do */
+# define POPARGS_1	POPARGS_0 REG_L a0, STKOFF_A0(sp);
+# define POPARGS_2	POPARGS_1 REG_L a1, STKOFF_A1(sp);
+# define POPARGS_3	POPARGS_2 REG_L a2, STKOFF_A2(sp);
+# define POPARGS_4	POPARGS_3 REG_L a3, STKOFF_A3(sp);
+# define POPARGS_5	POPARGS_4 REG_L a4, STKOFF_A4(sp);
+# define POPARGS_6	POPARGS_5 REG_L a5, STKOFF_A5(sp);
+
+/* Avoid D$ misses by keeping less-used arguments further down stack.  */
+# define STKOFF_A5	0
+# define STKOFF_A4	(STKOFF_A5 + SZREG)
+# define STKOFF_A3	(STKOFF_A4 + SZREG)
+# define STKOFF_A2	(STKOFF_A3 + SZREG)
+# define STKOFF_A1	(STKOFF_A2 + SZREG)
+# define STKOFF_A0	(STKOFF_A1 + SZREG)
+# define STKOFF_SVMSK	(STKOFF_A0 + SZREG)
+# define STKOFF_RA	(STKOFF_SVMSK + SZREG)
+# define STKSPACE	(STKOFF_RA + SZREG)
+
+# if IS_IN (libpthread)
+#  define CENABLE  call __pthread_enable_asynccancel
+#  define CDISABLE call __pthread_disable_asynccancel
+# elif IS_IN (librt)
+#  define CENABLE  call __librt_enable_asynccancel
+#  define CDISABLE call __librt_disable_asynccancel
+# else
+#  define CENABLE  call __libc_enable_asynccancel
+#  define CDISABLE call __libc_disable_asynccancel
+# endif
+
+# ifndef __ASSEMBLER__
+#  define SINGLE_THREAD_P						\
+	__glibc_likely (THREAD_GETMEM (THREAD_SELF,			\
+				       header.multiple_threads)	== 0)
+# else
+#  include "tcb-offsets.h"
+#  define SINGLE_THREAD_P(reg)						\
+	lw reg, MULTIPLE_THREADS_OFFSET(tp)
+#endif
+
+#elif !defined __ASSEMBLER__
+
+# define SINGLE_THREAD_P 1
+# define NO_CANCELLATION 1
+
+#endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+  __glibc_likely (THREAD_GETMEM (THREAD_SELF, \
+				 header.multiple_threads) == 0)
+#endif
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 000000000000..a73c3a9b049b
--- /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 000000000000..be55b26310bb
--- /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)