diff mbox series

[v7,06/12] C-SKY: Linux ABI

Message ID 97234ea73537554aef4dd01b769836159a5d3b9c.1544151747.git.han_mao@c-sky.com
State New
Headers show
Series port C-SKY to glibc | expand

Commit Message

=?UTF-8?B?5q+b5pmX?= Dec. 10, 2018, 1:27 a.m. UTC
Linux-specific code that is required for maintaining ABI compatibility.
This doesn't contain the actual system call interface.

	* sysdeps/unix/sysv/linux/csky/Versions: New file.
	* sysdeps/unix/sysv/linux/csky/bits/mman.h: Likewise.
	* sysdeps/unix/sysv/linux/csky/bits/procfs.h: Likewise.
	* sysdeps/unix/sysv/linux/csky/bits/shmlba.h: Likewise.
	* sysdeps/unix/sysv/linux/csky/c++-types.data: Likewise.
	* sysdeps/unix/sysv/linux/csky/abiv2/ucontext_i.sym: Likewise.
	* sysdeps/unix/sysv/linux/csky/ipc_priv.h: Likewise.
	* sysdeps/unix/sysv/linux/csky/jmp_buf-macros.h: Likewise.
	* sysdeps/unix/sysv/linux/csky/kernel-features.h: Likewise.
	* sysdeps/unix/sysv/linux/csky/localplt.data: Likewise.
	* sysdeps/unix/sysv/linux/csky/makecontext.c: Likewise.
	* sysdeps/unix/sysv/linux/csky/profil-counter.h: Likewise.
	* sysdeps/unix/sysv/linux/csky/register-dump.h: Likewise.
	* sysdeps/unix/sysv/linux/csky/shlib-versions: Likewise.
	* sysdeps/unix/sysv/linux/csky/sigcontextinfo.h: Likewise.
	* sysdeps/unix/sysv/linux/csky/sys/cachectl.h: Likewise.
	* sysdeps/unix/sysv/linux/csky/sys/ucontext.h: Likewise.
	* sysdeps/unix/sysv/linux/csky/sys/user.h: Likewise.
	* sysdeps/unix/sysv/linux/csky/sysdep.h: Likewise.
---
 sysdeps/unix/sysv/linux/csky/Versions             |   5 +
 sysdeps/unix/sysv/linux/csky/abiv2/ucontext_i.sym |  32 ++
 sysdeps/unix/sysv/linux/csky/bits/procfs.h        |  34 ++
 sysdeps/unix/sysv/linux/csky/bits/shmlba.h        |  29 ++
 sysdeps/unix/sysv/linux/csky/c++-types.data       |  67 +++
 sysdeps/unix/sysv/linux/csky/ipc_priv.h           |  21 +
 sysdeps/unix/sysv/linux/csky/jmp_buf-macros.h     |   6 +
 sysdeps/unix/sysv/linux/csky/kernel-features.h    |  29 ++
 sysdeps/unix/sysv/linux/csky/localplt.data        |  19 +
 sysdeps/unix/sysv/linux/csky/makecontext.c        |  74 +++
 sysdeps/unix/sysv/linux/csky/profil-counter.h     |  31 ++
 sysdeps/unix/sysv/linux/csky/register-dump.h      | 193 ++++++++
 sysdeps/unix/sysv/linux/csky/shlib-versions       |   9 +
 sysdeps/unix/sysv/linux/csky/sigcontextinfo.h     |  32 ++
 sysdeps/unix/sysv/linux/csky/sys/cachectl.h       |  38 ++
 sysdeps/unix/sysv/linux/csky/sys/ucontext.h       |  90 ++++
 sysdeps/unix/sysv/linux/csky/sys/user.h           |  64 +++
 sysdeps/unix/sysv/linux/csky/sysdep.h             | 534 ++++++++++++++++++++++
 18 files changed, 1307 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/csky/Versions
 create mode 100644 sysdeps/unix/sysv/linux/csky/abiv2/ucontext_i.sym
 create mode 100644 sysdeps/unix/sysv/linux/csky/bits/procfs.h
 create mode 100644 sysdeps/unix/sysv/linux/csky/bits/shmlba.h
 create mode 100644 sysdeps/unix/sysv/linux/csky/c++-types.data
 create mode 100644 sysdeps/unix/sysv/linux/csky/ipc_priv.h
 create mode 100644 sysdeps/unix/sysv/linux/csky/jmp_buf-macros.h
 create mode 100644 sysdeps/unix/sysv/linux/csky/kernel-features.h
 create mode 100644 sysdeps/unix/sysv/linux/csky/localplt.data
 create mode 100644 sysdeps/unix/sysv/linux/csky/makecontext.c
 create mode 100644 sysdeps/unix/sysv/linux/csky/profil-counter.h
 create mode 100644 sysdeps/unix/sysv/linux/csky/register-dump.h
 create mode 100644 sysdeps/unix/sysv/linux/csky/shlib-versions
 create mode 100644 sysdeps/unix/sysv/linux/csky/sigcontextinfo.h
 create mode 100644 sysdeps/unix/sysv/linux/csky/sys/cachectl.h
 create mode 100644 sysdeps/unix/sysv/linux/csky/sys/ucontext.h
 create mode 100644 sysdeps/unix/sysv/linux/csky/sys/user.h
 create mode 100644 sysdeps/unix/sysv/linux/csky/sysdep.h

Comments

Joseph Myers Dec. 14, 2018, 9:09 p.m. UTC | #1
On Mon, 10 Dec 2018, Mao Han wrote:

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

> +extern int _flush_cache (char *__addr, const int __nbytes,
> +		         const int __op) __THROW;

This name is not listed in a Versions file to be exported, so it makes no 
sense to declare it in an installed header.  Either it should be exported 
in a Versions file and the ABI baselines updated accordingly, or the 
declaration should be removed from the header.
=?UTF-8?B?5q+b5pmX?= Dec. 15, 2018, 12:20 p.m. UTC | #2
On Fri, Dec 14, 2018 at 09:09:02PM +0000, Joseph Myers wrote:
> On Mon, 10 Dec 2018, Mao Han wrote:
> 
> > diff --git a/sysdeps/unix/sysv/linux/csky/sys/cachectl.h b/sysdeps/unix/sysv/linux/csky/sys/cachectl.h
> 
> > +extern int _flush_cache (char *__addr, const int __nbytes,
> > +		         const int __op) __THROW;
> 
> This name is not listed in a Versions file to be exported, so it makes no 
> sense to declare it in an installed header.  Either it should be exported 
> in a Versions file and the ABI baselines updated accordingly, or the 
> declaration should be removed from the header.

This symbol is not used by others programs. We only use flushcache to
flush cache. I'll remove the declaration.

Thanks,
Mao Han
diff mbox series

Patch

diff --git a/sysdeps/unix/sysv/linux/csky/Versions b/sysdeps/unix/sysv/linux/csky/Versions
new file mode 100644
index 0000000..b61b3b2
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/Versions
@@ -0,0 +1,5 @@ 
+libc {
+  GLIBC_2.29 {
+    cacheflush;
+  }
+}
diff --git a/sysdeps/unix/sysv/linux/csky/abiv2/ucontext_i.sym b/sysdeps/unix/sysv/linux/csky/abiv2/ucontext_i.sym
new file mode 100644
index 0000000..4581b65
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/abiv2/ucontext_i.sym
@@ -0,0 +1,32 @@ 
+#include <inttypes.h>
+#include <signal.h>
+#include <stddef.h>
+#include <sys/ucontext.h>
+
+SIG_BLOCK
+SIG_SETMASK
+
+-- Offsets of the fields in the ucontext_t structure.
+#define ucontext(member)	offsetof (ucontext_t, member)
+#define mcontext(member)	ucontext (uc_mcontext.member)
+#define greg(member)		mcontext (__gregs.member)
+#define fpreg(member)		mcontext (__fpregs.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)
+
+MCONTEXT_CSKY_PC		greg (__pc)
+MCONTEXT_CSKY_SP		greg (__usp)
+MCONTEXT_CSKY_LR		greg (__lr)
+MCONTEXT_CSKY_A0		greg (__a0)
+MCONTEXT_CSKY_R8		greg (__regs[2])
+MCONTEXT_CSKY_R16		greg (__exregs[0])
+MCONTEXT_CSKY_HI		greg (__rhi)
+MCONTEXT_CSKY_LO		greg (__rlo)
+MCONTEXT_CSKY_R4		greg (__regs[0])
+MCONTEXT_CSKY_FESR		fpreg (__fesr)
+MCONTEXT_CSKY_FCR		fpreg (__fcr)
+MCONTEXT_CSKY_FR0		fpreg (__vr[0])
diff --git a/sysdeps/unix/sysv/linux/csky/bits/procfs.h b/sysdeps/unix/sysv/linux/csky/bits/procfs.h
new file mode 100644
index 0000000..83e37b0
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/bits/procfs.h
@@ -0,0 +1,34 @@ 
+/* Types for registers for sys/procfs.h.  C-SKY version.
+   Copyright (C) 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
+# error "Never include <bits/procfs.h> directly; use <sys/procfs.h> instead."
+#endif
+
+/* Type for a general-purpose register.  */
+typedef unsigned long elf_greg_t;
+
+/* And the whole bunch of them.  We could have used `struct
+   user_regs' directly in the typedef, but tradition says that
+   the register set is an array, which does have some peculiar
+   semantics, so leave it that way.  */
+#define ELF_NGREG (sizeof (struct user_regs) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+/* Register set for the floating-point registers.  */
+typedef struct user_fpregs elf_fpregset_t;
diff --git a/sysdeps/unix/sysv/linux/csky/bits/shmlba.h b/sysdeps/unix/sysv/linux/csky/bits/shmlba.h
new file mode 100644
index 0000000..3eb6c27
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/bits/shmlba.h
@@ -0,0 +1,29 @@ 
+/* Define SHMLBA.  C-SKY version.
+   Copyright (C) 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_SHM_H
+# error "Never use <bits/shmlba.h> directly; include <sys/shm.h> instead."
+#endif
+
+__BEGIN_DECLS
+
+/* Segment low boundary address multiple.  */
+#define SHMLBA		(__getpagesize () << 2)
+extern int __getpagesize (void) __THROW __attribute__ ((__const__));
+
+__END_DECLS
diff --git a/sysdeps/unix/sysv/linux/csky/c++-types.data b/sysdeps/unix/sysv/linux/csky/c++-types.data
new file mode 100644
index 0000000..303f457
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/c++-types.data
@@ -0,0 +1,67 @@ 
+blkcnt64_t:x
+blkcnt_t:l
+blksize_t:i
+caddr_t:Pc
+clockid_t:i
+clock_t:l
+daddr_t:i
+dev_t:y
+fd_mask:l
+fsblkcnt64_t:y
+fsblkcnt_t:m
+fsfilcnt64_t:y
+fsfilcnt_t:m
+fsid_t:8__fsid_t
+gid_t:j
+id_t:j
+ino64_t:y
+ino_t:m
+int16_t:s
+int32_t:i
+int64_t:x
+int8_t:a
+intptr_t:i
+key_t:i
+loff_t:x
+mode_t:j
+nlink_t:j
+off64_t:x
+off_t:l
+pid_t:i
+pthread_attr_t:14pthread_attr_t
+pthread_barrier_t:17pthread_barrier_t
+pthread_barrierattr_t:21pthread_barrierattr_t
+pthread_cond_t:14pthread_cond_t
+pthread_condattr_t:18pthread_condattr_t
+pthread_key_t:j
+pthread_mutex_t:15pthread_mutex_t
+pthread_mutexattr_t:19pthread_mutexattr_t
+pthread_once_t:i
+pthread_rwlock_t:16pthread_rwlock_t
+pthread_rwlockattr_t:20pthread_rwlockattr_t
+pthread_spinlock_t:i
+pthread_t:m
+quad_t:x
+register_t:i
+rlim64_t:y
+rlim_t:m
+sigset_t:10__sigset_t
+size_t:j
+socklen_t:j
+ssize_t:i
+suseconds_t:l
+time_t:l
+u_char:h
+uid_t:j
+uint:j
+u_int:j
+u_int16_t:t
+u_int32_t:j
+u_int64_t:y
+u_int8_t:h
+ulong:m
+u_long:m
+u_quad_t:y
+useconds_t:j
+ushort:t
+u_short:t
diff --git a/sysdeps/unix/sysv/linux/csky/ipc_priv.h b/sysdeps/unix/sysv/linux/csky/ipc_priv.h
new file mode 100644
index 0000000..56ded89
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/ipc_priv.h
@@ -0,0 +1,21 @@ 
+/* Old SysV permission definition for Linux.  C-SKY version.
+   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 <sys/ipc.h>  /* For __key_t  */
+
+#define __IPC_64	0x0
diff --git a/sysdeps/unix/sysv/linux/csky/jmp_buf-macros.h b/sysdeps/unix/sysv/linux/csky/jmp_buf-macros.h
new file mode 100644
index 0000000..5a390c7
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/jmp_buf-macros.h
@@ -0,0 +1,6 @@ 
+#define JMP_BUF_SIZE 268
+#define SIGJMP_BUF_SIZE 268
+#define JMP_BUF_ALIGN 4
+#define SIGJMP_BUF_ALIGN 4
+#define MASK_WAS_SAVED_OFFSET 136
+#define SAVED_MASK_OFFSET 140
diff --git a/sysdeps/unix/sysv/linux/csky/kernel-features.h b/sysdeps/unix/sysv/linux/csky/kernel-features.h
new file mode 100644
index 0000000..f1fbc71
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/kernel-features.h
@@ -0,0 +1,29 @@ 
+/* Set flags signalling availability of kernel features based on given
+   kernel version number.
+   Copyright (C) 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_next <kernel-features.h>
+
+/* fadvise64_64 reorganize the syscall arguments.  */
+#define __ASSUME_FADVISE64_64_6ARG	1
+
+/* Define this if your 32-bit syscall API requires 64-bit register
+   pairs to start with an even-number register.  */
+#ifdef __CSKYABIV1__
+# define __ASSUME_ALIGNED_REGISTER_PAIRS	1
+#endif
diff --git a/sysdeps/unix/sysv/linux/csky/localplt.data b/sysdeps/unix/sysv/linux/csky/localplt.data
new file mode 100644
index 0000000..14c02cb
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/localplt.data
@@ -0,0 +1,19 @@ 
+# See scripts/check-localplt.awk for how this file is processed.
+# PLT use is required for the malloc family and for matherr because
+# users can define their own functions and have library internals call them.
+libc.so: calloc
+libc.so: free
+libc.so: malloc
+libc.so: memalign
+libc.so: realloc
+# The main malloc is interposed into the dynamic linker, for
+# allocations after the initial link (when dlopen is used).
+ld.so: malloc
+ld.so: calloc
+ld.so: realloc
+ld.so: free
+# The TLS-enabled version of these functions is interposed from libc.so.
+ld.so: _dl_signal_error
+ld.so: _dl_catch_error
+ld.so: _dl_signal_exception
+ld.so: _dl_catch_exception
diff --git a/sysdeps/unix/sysv/linux/csky/makecontext.c b/sysdeps/unix/sysv/linux/csky/makecontext.c
new file mode 100644
index 0000000..c0d7d1e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/makecontext.c
@@ -0,0 +1,74 @@ 
+/* Create new context.  C-SKY version.
+   Copyright (C) 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 <stdarg.h>
+#include <ucontext.h>
+
+/* Number of arguments that go in registers.  */
+#define NREG_ARGS  4
+
+/* Take a context previously prepared via getcontext() and set to
+   call func() with the given int only args.  */
+void
+__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
+{
+  extern void __startcontext (void);
+  unsigned long *funcstack;
+  va_list vl;
+  unsigned long *regptr;
+  unsigned int reg;
+  int misaligned;
+
+  /* Start at the top of stack.  */
+  funcstack = (unsigned long *) (ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
+
+  /* Ensure the stack stays eight byte aligned.  */
+  misaligned = ((unsigned long) funcstack & 4) != 0;
+
+  if ((argc > NREG_ARGS) && (argc & 1) != 0)
+    misaligned = !misaligned;
+
+  if (misaligned)
+    funcstack -= 1;
+
+  va_start (vl, argc);
+
+  /* Reserve space for the on-stack arguments.  */
+  if (argc > NREG_ARGS)
+    funcstack -= (argc - NREG_ARGS);
+
+  ucp->uc_mcontext.__gregs.__usp = (unsigned long) funcstack;
+  ucp->uc_mcontext.__gregs.__pc = (unsigned long) func;
+
+  /* Exit to startcontext() with the next context in R9.  */
+  ucp->uc_mcontext.__gregs.__regs[5] = (unsigned long) ucp->uc_link;
+  ucp->uc_mcontext.__gregs.__lr = (unsigned long) __startcontext;
+
+  /* The first four arguments go into registers.  */
+  regptr = &(ucp->uc_mcontext.__gregs.__a0);
+
+  for (reg = 0; (reg < argc) && (reg < NREG_ARGS); reg++)
+    *regptr++ = va_arg (vl, unsigned long);
+
+  /* And the remainder on the stack.  */
+  for (; reg < argc; reg++)
+    *funcstack++ = va_arg (vl, unsigned long);
+
+  va_end (vl);
+}
+weak_alias (__makecontext, makecontext)
diff --git a/sysdeps/unix/sysv/linux/csky/profil-counter.h b/sysdeps/unix/sysv/linux/csky/profil-counter.h
new file mode 100644
index 0000000..1f7ec7a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/profil-counter.h
@@ -0,0 +1,31 @@ 
+/* Low-level statistical profiling support function.  Linux/C-SKY version.
+   Copyright (C) 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 <signal.h>
+#include <sigcontextinfo.h>
+
+void
+__profil_counter (int signo, const SIGCONTEXT scp)
+{
+  profil_count ((void *) GET_PC (scp));
+
+  /* This is a hack to prevent the compiler from implementing the
+     above function call as a sibcall.  The sibcall would overwrite
+     the signal context.  */
+  asm volatile ("");
+}
diff --git a/sysdeps/unix/sysv/linux/csky/register-dump.h b/sysdeps/unix/sysv/linux/csky/register-dump.h
new file mode 100644
index 0000000..9abe87a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/register-dump.h
@@ -0,0 +1,193 @@ 
+/* Dump registers.
+   Copyright (C) 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/uio.h>
+#include <_itoa.h>
+#include <bits/sigcontext.h>
+#include <sys/ucontext.h>
+
+/* abiv1 register dump in this format:
+
+ PSR: XXXXXXXX  PC: XXXXXXXX   SP: XXXXXXXX   LR: XXXXXXXX
+ MASK: XXXXXXXX
+
+ A0: XXXXXXXX   A1: XXXXXXXX   A2: XXXXXXXX   A3: XXXXXXXX
+ R6: XXXXXXXX   R7: XXXXXXXX   R8: XXXXXXXX   R9: XXXXXXXX
+ R10: XXXXXXXX  R11: XXXXXXXX  R12: XXXXXXXX  R13: XXXXXXXX
+ R14: XXXXXXXX  R1: XXXXXXXX
+
+ abiv2 register dump in this format:
+
+ PSR: XXXXXXXX  PC: XXXXXXXX   SP: XXXXXXXX   LR: XXXXXXXX
+ MASK: XXXXXXXX
+
+ A0: XXXXXXXX   A1: XXXXXXXX   A2: XXXXXXXX   A3: XXXXXXXX
+ R4: XXXXXXXX   R5: XXXXXXXX   R6: XXXXXXXX   R7: XXXXXXXX
+ R8: XXXXXXXX   R9: XXXXXXXX   R10: XXXXXXXX  R11: XXXXXXXX
+ R12: XXXXXXXX  R13: XXXXXXXX  R14: XXXXXXXX  R15: XXXXXXXX
+ R16: XXXXXXXX  R17: XXXXXXXX  R18: XXXXXXXX  R19: XXXXXXXX
+ R20: XXXXXXXX  R21: XXXXXXXX  R22: XXXXXXXX  R23: XXXXXXXX
+ R24: XXXXXXXX  R25: XXXXXXXX  R26: XXXXXXXX  R27: XXXXXXXX
+ R28: XXXXXXXX  R29: XXXXXXXX  R30: XXXXXXXX  R31: XXXXXXXX
+
+ */
+
+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';
+}
+
+static void
+register_dump (int fd, const struct ucontext_t *ctx)
+{
+  char regs[35][8];
+  struct iovec iov[97];
+  size_t nr = 0;
+
+#define ADD_STRING(str) \
+  iov[nr].iov_base = (char *) str;					      \
+  iov[nr].iov_len = strlen (str);					      \
+  ++nr
+#define ADD_MEM(str, len) \
+  iov[nr].iov_base = str;						      \
+  iov[nr].iov_len = len;						      \
+  ++nr
+
+  /* Generate strings of register contents.  */
+  hexvalue (ctx->uc_mcontext.__gregs.__sr, regs[0], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__pc, regs[1], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__usp, regs[2], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__lr, regs[3], 8);
+  hexvalue (ctx->uc_mcontext.__mask, regs[4], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__a0, regs[5], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__a1, regs[6], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__a2, regs[7], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__a3, regs[8], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__regs[0], regs[9], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__regs[1], regs[10], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__regs[2], regs[11], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__regs[3], regs[12], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__regs[4], regs[13], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__regs[5], regs[14], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__regs[6], regs[15], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__regs[7], regs[16], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__regs[8], regs[17], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__regs[9], regs[18], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[0], regs[19], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[1], regs[20], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[2], regs[21], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[3], regs[22], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[4], regs[23], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[5], regs[24], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[6], regs[25], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[7], regs[26], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[8], regs[27], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[9], regs[28], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[10], regs[29], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[11], regs[30], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[12], regs[31], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[13], regs[32], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__exregs[14], regs[33], 8);
+  hexvalue (ctx->uc_mcontext.__gregs.__tls, regs[34], 8);
+
+  /* Generate the output.  */
+  ADD_STRING ("Register dump:\n\n PSR: ");
+  ADD_MEM (regs[0], 8);
+  ADD_STRING ("  PC: ");
+  ADD_MEM (regs[1], 8);
+  ADD_STRING ("   SP: ");
+  ADD_MEM (regs[2], 8);
+  ADD_STRING ("   LR: ");
+  ADD_MEM (regs[3], 8);
+  ADD_STRING ("\n MASK: ");
+  ADD_MEM (regs[4], 8);
+  ADD_STRING ("\n\n A0: ");
+  ADD_MEM (regs[5], 8);
+  ADD_STRING ("   A1: ");
+  ADD_MEM (regs[6], 8);
+  ADD_STRING ("   A2: ");
+  ADD_MEM (regs[7], 8);
+  ADD_STRING ("   A3: ");
+  ADD_MEM (regs[8], 8);
+  ADD_STRING ("\n R4: ");
+  ADD_MEM (regs[9], 8);
+  ADD_STRING ("   r5: ");
+  ADD_MEM (regs[10], 8);
+  ADD_STRING ("   r6: ");
+  ADD_MEM (regs[11], 8);
+  ADD_STRING ("   r7: ");
+  ADD_MEM (regs[12], 8);
+  ADD_STRING ("\n R8: ");
+  ADD_MEM (regs[13], 8);
+  ADD_STRING ("   R9: ");
+  ADD_MEM (regs[14], 8);
+  ADD_STRING ("   R10: ");
+  ADD_MEM (regs[15], 8);
+  ADD_STRING ("  R11: ");
+  ADD_MEM (regs[16], 8);
+  ADD_STRING ("\n R12: ");
+  ADD_MEM (regs[17], 8);
+  ADD_STRING ("  R13: ");
+  ADD_MEM (regs[18], 8);
+  ADD_STRING ("  R14: ");
+  ADD_MEM (regs[19], 8);
+  ADD_STRING ("  R15: ");
+  ADD_MEM (regs[20], 8);
+  ADD_STRING ("\n R16: ");
+  ADD_MEM (regs[21], 8);
+  ADD_STRING ("  R17: ");
+  ADD_MEM (regs[22], 8);
+  ADD_STRING ("  R18: ");
+  ADD_MEM (regs[23], 8);
+  ADD_STRING ("  R19: ");
+  ADD_MEM (regs[24], 8);
+  ADD_STRING ("\n R20: ");
+  ADD_MEM (regs[25], 8);
+  ADD_STRING ("  R21: ");
+  ADD_MEM (regs[26], 8);
+  ADD_STRING ("  R22: ");
+  ADD_MEM (regs[27], 8);
+  ADD_STRING ("  R23: ");
+  ADD_MEM (regs[28], 8);
+  ADD_STRING ("\n R24: ");
+  ADD_MEM (regs[29], 8);
+  ADD_STRING ("  R25: ");
+  ADD_MEM (regs[30], 8);
+  ADD_STRING ("  R26: ");
+  ADD_MEM (regs[31], 8);
+  ADD_STRING ("  R27: ");
+  ADD_MEM (regs[32], 8);
+  ADD_STRING ("\n R28: ");
+  ADD_MEM (regs[33], 8);
+  ADD_STRING ("  R29: ");
+  ADD_MEM (regs[34], 8);
+  ADD_STRING ("  R30: ");
+  ADD_MEM (regs[33], 8);
+  ADD_STRING ("  TP: ");
+  ADD_MEM (regs[34], 8);
+
+  ADD_STRING ("\n");
+
+  /* Write the stuff out.  */
+  writev (fd, iov, nr);
+}
+
+#define REGISTER_DUMP register_dump (fd, ctx)
diff --git a/sysdeps/unix/sysv/linux/csky/shlib-versions b/sysdeps/unix/sysv/linux/csky/shlib-versions
new file mode 100644
index 0000000..8c02635
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/shlib-versions
@@ -0,0 +1,9 @@ 
+DEFAULT			GLIBC_2.29
+
+%if CSKYABI == 2 && CSKY_HARD_FLOAT == 1
+ld=ld-linux-cskyv2-hf.so.1
+%elif CSKYABI == 2 && CSKY_HARD_FLOAT == 0
+ld=ld-linux-cskyv2.so.1
+%else
+%error cannot determine ABI
+%endif
diff --git a/sysdeps/unix/sysv/linux/csky/sigcontextinfo.h b/sysdeps/unix/sysv/linux/csky/sigcontextinfo.h
new file mode 100644
index 0000000..b9054d3
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/sigcontextinfo.h
@@ -0,0 +1,32 @@ 
+/* C-SKY definitions for signal handling calling conventions.
+   Copyright (C) 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 SIGCONTEXT siginfo_t *_si, struct ucontext_t *
+#define GET_PC(ctx)     ((void *) (ctx)->uc_mcontext.__gregs.__pc)
+
+/* There is no reliable way to get the sigcontext unless we use a
+   three-argument signal handler.  */
+#define __sigaction(sig, act, oact) ({ \
+  (act)->sa_flags |= SA_SIGINFO; \
+  (__sigaction) (sig, act, oact); \
+})
+
+#define sigaction(sig, act, oact) ({ \
+  (act)->sa_flags |= SA_SIGINFO; \
+  (sigaction) (sig, act, oact); \
+})
diff --git a/sysdeps/unix/sysv/linux/csky/sys/cachectl.h b/sysdeps/unix/sysv/linux/csky/sys/cachectl.h
new file mode 100644
index 0000000..bdc7dbb
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/sys/cachectl.h
@@ -0,0 +1,38 @@ 
+/* C-SKY cache flushing interface.
+   Copyright (C) 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>
+
+/* Get the kernel definition for the op bits.  */
+#include <asm/cachectl.h>
+
+__BEGIN_DECLS
+
+#ifdef __USE_MISC
+extern int cacheflush (void *__addr, const int __nbytes,
+		       const int __op) __THROW;
+#endif
+extern int _flush_cache (char *__addr, const int __nbytes,
+		         const int __op) __THROW;
+
+__END_DECLS
+
+#endif /* sys/cachectl.h */
diff --git a/sysdeps/unix/sysv/linux/csky/sys/ucontext.h b/sysdeps/unix/sysv/linux/csky/sys/ucontext.h
new file mode 100644
index 0000000..7ecb3ff
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/sys/ucontext.h
@@ -0,0 +1,90 @@ 
+/* struct ucontext definition, C-SKY version.
+   Copyright (C) 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_UCONTEXT_H
+#define _SYS_UCONTEXT_H	1
+
+#include <features.h>
+
+#include <bits/types/sigset_t.h>
+#include <bits/types/stack_t.h>
+
+typedef struct
+  {
+    unsigned long __tls;
+    unsigned long __lr;
+    unsigned long __pc;
+    unsigned long __sr;
+    unsigned long __usp;
+
+    /*
+     * a0, a1, a2, a3:
+     * abiv1: r2, r3, r4, r5
+     * abiv2: r0, r1, r2, r3
+     */
+
+    unsigned long __orig_a0;
+    unsigned long __a0;
+    unsigned long __a1;
+    unsigned long __a2;
+    unsigned long __a3;
+
+    /*
+     * ABIV2: r4 ~ r13
+     */
+    unsigned long __regs[10];
+
+    /* r16 ~ r30 */
+    unsigned long __exregs[15];
+
+    unsigned long __rhi;
+    unsigned long __rlo;
+    unsigned long __glibc_reserved;
+  } gregset_t;
+
+typedef struct
+  {
+    unsigned long __vr[64];
+    unsigned long __fcr;
+    unsigned long __fesr;
+    unsigned long __fid;
+    unsigned long __glibc_reserved;
+  } fpregset_t;
+
+/* Context to describe whole processor state.  */
+typedef struct
+  {
+    unsigned long __mask;
+    gregset_t __gregs;
+    fpregset_t __fpregs;
+  } mcontext_t;
+
+/* Userlevel context.  */
+typedef struct ucontext_t
+  {
+    unsigned long int __uc_flags;
+    struct ucontext_t *uc_link;
+    stack_t uc_stack;
+    mcontext_t uc_mcontext;
+    sigset_t uc_sigmask;
+  } ucontext_t;
+
+#undef __ctx
+
+
+#endif /* sys/ucontext.h */
diff --git a/sysdeps/unix/sysv/linux/csky/sys/user.h b/sysdeps/unix/sysv/linux/csky/sys/user.h
new file mode 100644
index 0000000..d9253b5
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/sys/user.h
@@ -0,0 +1,64 @@ 
+/* ptrace register data format definitions.  C-SKY version.
+   Copyright (C) 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
+
+struct user_fpregs {
+  unsigned long fsr;		/* fpu status reg */
+  unsigned long fesr;		/* fpu exception status reg */
+  unsigned long fp[32];		/* fpu general regs */
+};
+
+struct user_regs {
+#if defined(__ck807__) || defined(__ck810__) || defined(__ck860__)
+  unsigned long int uregs[34];	/* CSKY V2 has 32 general rgister.  */
+#else
+  unsigned long int uregs[18];	/* CSKY V1 has 16 general rgister.  */
+#endif
+};
+
+/* When the kernel dumps core, it starts by dumping the user struct -
+   this will be used by gdb to figure out where the data and stack segments
+   are within the file, and what virtual addresses to use.  */
+struct user{
+/* We start with the registers, to mimic the way that "memory" is returned
+   from the ptrace(3,...) function.  */
+  struct user_regs    regs;        /* The registers are actually stored.  */
+  int                 u_fpvalid;   /* True if math co-processor being used.  */
+
+/* The rest of this junk is to help gdb figure out what goes where.  */
+  unsigned long int   u_tsize;     /* Text segment size (pages).  */
+  unsigned long int   u_dsize;     /* Data segment size (pages).  */
+  unsigned long int   u_ssize;     /* Stack segment size (pages).  */
+  unsigned long       start_code;  /* Starting virtual address of text.  */
+  unsigned long       start_stack; /* Starting virtual address of stack area.
+				      This is actually the bottom of the stack
+				      the top of the stack is always found in
+				      the esp register.  */
+  long int            signal;      /* Signal that caused the core dump.  */
+  int                 reserved;    /* No longer used.  */
+  struct user_regs *  u_ar0;       /* Used by gdb to help find the values
+				      for the registers.  */
+  unsigned long       magic;       /* To uniquely identify a core file.  */
+  char                u_comm[32];  /* User command that was responsible.  */
+  struct user_fpregs  u_fp;
+  struct user_fpregs* u_fpstate;   /* Math Co-processor pointer.  */
+};
+
+#endif /* _SYS_USER_H */
diff --git a/sysdeps/unix/sysv/linux/csky/sysdep.h b/sysdeps/unix/sysv/linux/csky/sysdep.h
new file mode 100644
index 0000000..cec6f95
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/sysdep.h
@@ -0,0 +1,534 @@ 
+/* Assembly macros for C-SKY.
+   Copyright (C) 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_CSKY_SYSDEP_H
+#define _LINUX_CSKY_SYSDEP_H 1
+
+/* There is some commonality.  */
+#include <sysdeps/unix/sysv/linux/generic/sysdep.h>
+#include <sysdeps/unix/sysv/linux/sysdep.h>
+#include <sysdeps/csky/sysdep.h>
+
+/* Defines RTLD_PRIVATE_ERRNO and USE_DL_SYSINFO.  */
+#include <dl-sysdep.h>
+
+#include <tls.h>
+
+/* In order to get __set_errno() definition in INLINE_SYSCALL.  */
+#ifndef __ASSEMBLER__
+# include <errno.h>
+#endif
+
+#undef SYS_ify
+#define SYS_ify(syscall_name)  (__NR_##syscall_name)
+
+#ifdef __ASSEMBLER__
+/* Linux uses a negative return value to indicate syscall errors,
+   unlike most Unices, which use the condition codes' carry flag.
+
+   Since version 2.1 the return value of a system call might be
+   negative even if the call succeeded.  E.g., the `lseek' system call
+   might return a large offset.  Therefore we must not anymore test
+   for < 0, but test for a real error by making sure the value in R0
+   is a real error number.  Linus said he will make sure the no syscall
+   returns a value in -1 .. -4095 as a valid result so we can safely
+   test with -4095.  */
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)	\
+  .text;					\
+  ENTRY (name);					\
+  DO_CALL (syscall_name, args);
+
+# define GETGB				\
+	grs	t0, .Lgetpc;		\
+.Lgetpc:				\
+	lrw	gb, .Lgetpc@GOTPC;	\
+	addu	gb, t0;
+
+# if IS_IN (libc)
+#  ifdef __PIC__
+#   define PSEUDO_RET			\
+	btsti	a0, 31;			\
+	bf	1f;			\
+	subi	sp, 8;			\
+	st.w	lr, (sp);		\
+	st.w	gb, (sp, 4);		\
+	GETGB;				\
+	lrw	a2, SYSCALL_ERROR@PLT;	\
+	add	a2, gb;			\
+	ld.w	a2, (a2);		\
+	jsr	a2;			\
+	ld.w	lr, (sp);		\
+	ld.w	gb, (sp, 4);		\
+	addi	sp, 8;			\
+1:					\
+	rts
+#  else
+#   define PSEUDO_RET			\
+	btsti	a0, 31;			\
+	bf	1f;			\
+	jmpi	SYSCALL_ERROR;		\
+1:					\
+	rts
+#  endif
+# else
+#  ifdef __PIC__
+#   define PSEUDO_RET			\
+	btsti	a0, 31;			\
+	bf	1f;			\
+	subi	sp, 8;			\
+	st.w	lr, (sp);		\
+	st.w	gb, (sp, 4);		\
+	GETGB;				\
+	bsr	SYSCALL_ERROR;		\
+	ld.w	lr, (sp);		\
+	ld.w	gb, (sp, 4);		\
+	addi	sp, 8;			\
+1:					\
+	rts
+#  else
+#   define PSEUDO_RET			\
+	btsti	a0, 31;			\
+	bt	SYSCALL_ERROR;		\
+	rts
+#  endif
+# endif
+
+# undef ret
+# define ret PSEUDO_RET
+
+# undef PSEUDO_END
+# define PSEUDO_END(name)		\
+  .align 4;				\
+  SYSCALL_ERROR_HANDLER;		\
+  END (name)
+
+# undef PSEUDO_NOERRNO
+# define PSEUDO_NOERRNO(name, syscall_name, args)	\
+  .text;						\
+  ENTRY (name);						\
+  DO_CALL (syscall_name, args)
+
+# define PSEUDO_RET_NOERRNO rts
+
+# undef ret_NOERRNO
+# define ret_NOERRNO PSEUDO_RET_NOERRNO
+
+# undef PSEUDO_END_NOERRNO
+# define PSEUDO_END_NOERRNO(name) END (name)
+
+/* The function has to return the error code.  */
+# undef PSEUDO_ERRVAL
+# define PSEUDO_ERRVAL(name, syscall_name, args)	\
+  .text;						\
+  ENTRY (name)						\
+  DO_CALL (syscall_name, args);				\
+  not	a0;						\
+  addi	a0, 1
+
+# undef PSEUDO_END_ERRVAL
+# define PSEUDO_END_ERRVAL(name) END (name)
+
+# define ret_ERRVAL rts
+
+# if !IS_IN (libc)
+#  define SYSCALL_ERROR __local_syscall_error
+#  if RTLD_PRIVATE_ERRNO
+#   ifdef __PIC__
+#    define SYSCALL_ERROR_HANDLER	\
+__local_syscall_error:			\
+	lrw	a1, rtld_errno@PLT; 	\
+	addu	a1, gb;			\
+	ldw	a1, (a1);		\
+	rsubi	a0, 0;			\
+	stw	a0, (a1);		\
+	bmaski	a0, 0;			\
+	rts
+#   else /* __PIC__ */
+#    define SYSCALL_ERROR_HANDLER	\
+__local_syscall_error:			\
+	lrw	a1, rtld_errno;		\
+	rsubi	a0, 0;			\
+	stw	a0, (a1);		\
+	bmaski	a0, 0;			\
+	rts
+#   endif /* __PIC__ */
+#  else /* !RTLD_PRIVATE_ERRNO */
+#   ifdef __PIC__
+#    define SYSCALL_ERROR_HANDLER		\
+__local_syscall_error:				\
+	subi	sp, 8;				\
+	stw	a0, (sp, 0);			\
+	stw	r15, (sp, 4);			\
+	lrw	a1, __errno_location@PLT;	\
+	add	a1, gb;				\
+	ldw	a1, (a1);			\
+	jsr	a1;				\
+	ldw	a1, (sp, 0); /* load errno*/	\
+	ldw	r15, (sp, 4);			\
+	addi	sp, 8;				\
+	movi	a2, 0;				\
+	rsub	a1, a1, a2;			\
+	stw	a1, (a0);			\
+	bmaski	a0, 0;				\
+	rts
+#    else
+#     define SYSCALL_ERROR_HANDLER 		\
+__local_syscall_error:				\
+	subi	sp, 8;				\
+	stw	a0, (sp, 0);			\
+	stw	r15, (sp, 4);			\
+	lrw	a1, __errno_location;		\
+	jsr	a1;				\
+	ldw	a1, (sp, 0); /* load errno */	\
+	ldw	r15, (sp, 4);			\
+	addi	sp, 8;				\
+	movi	a2, 0;				\
+	rsub	a1, a1, a2;			\
+	stw	a1, (a0);			\
+	bmaski	a0, 0;				\
+	rts
+#   endif /* __PIC__ */
+#  endif/* RTLD_PRIVATE_ERROR */
+# else
+#  define SYSCALL_ERROR_HANDLER  /* Nothing here; code in sysdep.S is used.  */
+#  define SYSCALL_ERROR __syscall_error
+# endif/* IS_IN (libc) */
+
+/* define DO_CALL */
+# undef DO_CALL
+# define DO_CALL(syscall_name, args)	\
+  DOARGS_##args;			\
+  lrw	r7, SYS_ify(syscall_name);	\
+  trap	0;				\
+  UNDOARGS_##args
+
+# undef  DOARGS_0
+# define DOARGS_0			\
+	subi	sp, 8;			\
+	cfi_adjust_cfa_offset (8);	\
+	stw	r7, (sp, 0);		\
+	cfi_rel_offset (r7, 0);
+
+# undef  DOARGS_1
+# define DOARGS_1 DOARGS_0
+# undef  DOARGS_2
+# define DOARGS_2 DOARGS_0
+# undef  DOARGS_3
+# define DOARGS_3 DOARGS_0
+# undef  DOARGS_4
+# define DOARGS_4 DOARGS_0
+# undef  DOARGS_5
+# define DOARGS_5			\
+	subi	sp, 8;			\
+	cfi_adjust_cfa_offset (8);	\
+	stw	r7, (sp, 0);		\
+	cfi_rel_offset (7, 0);		\
+	stw	r4, (sp, 4);		\
+	cfi_rel_offset (4, 4);		\
+	ldw	r4, (sp, 8)
+# undef  DOARGS_6
+# define DOARGS_6			\
+	subi	sp, 16;			\
+	cfi_adjust_cfa_offset (16);	\
+	stw	r7, (sp, 0);		\
+	cfi_rel_offset (7, 0);		\
+	stw	r4, (sp, 4);		\
+	cfi_rel_offset (4, 4);		\
+	stw	r5, (sp, 8);		\
+	cfi_rel_offset (5, 8);		\
+	ldw	r4, (sp, 16);		\
+	ldw	r5, (sp, 20)
+
+# undef  UNDOARGS_0
+# define UNDOARGS_0 \
+  ldw  r7, (sp, 0); \
+  cfi_restore (r7); \
+  addi sp, 8;   \
+  cfi_adjust_cfa_offset (-8);
+
+# undef  UNDOARGS_1
+# define UNDOARGS_1 UNDOARGS_0
+# undef  UNDOARGS_2
+# define UNDOARGS_2 UNDOARGS_0
+# undef  UNDOARGS_3
+# define UNDOARGS_3 UNDOARGS_0
+# undef  UNDOARGS_4
+# define UNDOARGS_4 UNDOARGS_0
+# undef  UNDOARGS_5
+# define UNDOARGS_5			\
+	ldw	r7, (sp, 0);		\
+	cfi_restore (r4);		\
+	ldw	r4, (sp, 4);		\
+	cfi_restore (r4);		\
+	addi	sp, 8;			\
+	cfi_adjust_cfa_offset (-8);
+
+# undef  UNDOARGS_6
+# define UNDOARGS_6			\
+	ldw	r7, (sp, 0);		\
+	cfi_restore (r7);		\
+	ldw	r4, (sp, 4);		\
+	cfi_restore (r4);		\
+	ldw	r5, (sp, 8);		\
+	cfi_restore (r5);		\
+	addi	sp, 16;			\
+	cfi_adjust_cfa_offset (-16);
+
+#else /* not __ASSEMBLER__ */
+
+/* Define a macro which expands into the inline wrapper code for a system
+   call.  */
+# undef INLINE_SYSCALL
+# define INLINE_SYSCALL(name, nr, args...)				\
+  ({ unsigned int _sys_result = INTERNAL_SYSCALL (name, , nr, args);	\
+     if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (_sys_result,), 0))	\
+       {								\
+	 __set_errno (INTERNAL_SYSCALL_ERRNO (_sys_result, ));		\
+	 _sys_result = (unsigned int) -1;				\
+       }								\
+     (int) _sys_result; })
+
+# undef INTERNAL_SYSCALL_DECL
+# define INTERNAL_SYSCALL_DECL(err) do { } while (0)
+
+# undef INTERNAL_SYSCALL_ERROR_P
+# define INTERNAL_SYSCALL_ERROR_P(val, err) \
+  ((unsigned int) (val) >= 0xffffff01u)
+
+# undef INTERNAL_SYSCALL_ERRNO
+# define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))
+
+# undef INTERNAL_SYSCALL_RAW
+#  define INTERNAL_SYSCALL_RAW0(name, err, dummy...)			\
+  ({unsigned int __sys_result;						\
+     {									\
+       register int _a1 __asm__ ("a0"), _nr __asm__ ("r7");		\
+       _nr = name;							\
+       __asm__ __volatile__ ("trap  0 \n\t"				\
+			     : "=r" (_a1)				\
+			     : "r" (_nr)				\
+			     : "memory");				\
+	       __sys_result = _a1;					\
+     }									\
+     (int) __sys_result; })
+
+#  define INTERNAL_SYSCALL_RAW1(name, err, arg1)			\
+  ({unsigned int __sys_result;						\
+    register int _tmp_arg1 = (int)(arg1);				\
+     {									\
+       register int _a1 __asm__ ("a0"), _nr __asm__ ("r7");		\
+       _a1 = _tmp_arg1;							\
+       _nr = name;							\
+       __asm__ __volatile__ ("trap  0 \n\t"				\
+			     : "=r" (_a1)				\
+			     : "r" (_nr), "r" (_a1)			\
+			     : "memory");				\
+	       __sys_result = _a1;					\
+     }									\
+     (int) __sys_result; })
+
+#  define INTERNAL_SYSCALL_RAW2(name, err, arg1, arg2)			\
+  ({unsigned int __sys_result;						\
+    register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2);	\
+     {									\
+       register int _nr __asm__ ("r7");					\
+       register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1");		\
+       _a1 = _tmp_arg1, _a2 = _tmp_arg2;				\
+       _nr = name;							\
+       __asm__ __volatile__ ("trap  0 \n\t"				\
+			     : "=r" (_a1)				\
+			     : "r" (_nr), "r" (_a1), "r" (_a2)		\
+			     : "memory");				\
+	       __sys_result = _a1;					\
+     }									\
+     (int) __sys_result; })
+
+#  define INTERNAL_SYSCALL_RAW3(name, err, arg1, arg2, arg3)		\
+  ({unsigned int __sys_result;						\
+    register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2);	\
+    register int _tmp_arg3 = (int)(arg3);				\
+     {									\
+       register int _nr __asm__ ("r7");					\
+       register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1");		\
+       register int _a3 __asm__ ("a2");					\
+       _a1 = _tmp_arg1;							\
+       _a2 = _tmp_arg2;							\
+       _a3 = _tmp_arg3;							\
+       _nr = name;							\
+       __asm__ __volatile__ ("trap  0 \n\t"				\
+			     : "=r" (_a1)				\
+			     : "r" (_nr), "r" (_a1), "r" (_a2),		\
+			       "r" (_a3)				\
+			     : "memory");				\
+	       __sys_result = _a1;					\
+     }									\
+     (int) __sys_result; })
+
+#  define INTERNAL_SYSCALL_RAW4(name, err, arg1, arg2, arg3, arg4)	\
+  ({unsigned int __sys_result;						\
+    register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2);	\
+    register int _tmp_arg3 = (int)(arg3), _tmp_arg4 = (int)(arg4);	\
+     {									\
+       register int _nr __asm__ ("r7");					\
+       register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1");		\
+       register int _a3 __asm__ ("a2"), _a4 __asm__ ("a3");		\
+       _a1 = _tmp_arg1, _a2 = _tmp_arg2, _a3 = _tmp_arg3;		\
+       _a4 = _tmp_arg4;							\
+       _nr = name;							\
+       __asm__ __volatile__ ("trap  0 \n\t"				\
+			     : "=r" (_a1)				\
+			     : "r" (_nr), "r" (_a1), "r" (_a2),		\
+			       "r" (_a3), "r" (_a4)			\
+			     : "memory");				\
+	       __sys_result = _a1;					\
+     }									\
+     (int) __sys_result; })
+
+#  define INTERNAL_SYSCALL_RAW5(name, err, arg1, arg2, arg3, arg4,	\
+			      arg5)					\
+  ({unsigned int __sys_result;						\
+    register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2);	\
+    register int _tmp_arg3 = (int)(arg3), _tmp_arg4 = (int)(arg4);	\
+    register int _tmp_arg5 = (int)(arg5);				\
+     {									\
+       register int _nr __asm__ ("r7");					\
+       register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1");		\
+       register int _a3 __asm__ ("a2"), _a4 __asm__ ("a3");		\
+       register int _a5 __asm__ ("r4");					\
+       _a1 = _tmp_arg1, _a2 = _tmp_arg2, _a3 = _tmp_arg3;		\
+       _a4 = _tmp_arg4, _a5 = _tmp_arg5;				\
+       _nr = name;							\
+       __asm__ __volatile__ ("trap  0 \n\t"				\
+			     : "=r" (_a1)				\
+			     : "r" (_nr), "r" (_a1), "r" (_a2),		\
+			       "r" (_a3), "r" (_a4), "r" (_a5)		\
+			     : "memory");				\
+	       __sys_result = _a1;					\
+     }									\
+     (int) __sys_result; })
+
+#  define INTERNAL_SYSCALL_RAW6(name, err, arg1, arg2, arg3, arg4,	\
+			      arg5, arg6)				\
+  ({unsigned int __sys_result;						\
+    register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2);	\
+    register int _tmp_arg3 = (int)(arg3), _tmp_arg4 = (int)(arg4);	\
+    register int _tmp_arg5 = (int)(arg5), _tmp_arg6 = (int)(arg6);	\
+     {									\
+       register int _nr __asm__ ("r7");					\
+       register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1");		\
+       register int _a3 __asm__ ("a2"), _a4 __asm__ ("a3");		\
+       register int _a5 __asm__ ("r4"), _a6 __asm__ ("r5");		\
+       _a1 = _tmp_arg1, _a2 = _tmp_arg2, _a3 = _tmp_arg3;		\
+       _a4 = _tmp_arg4, _a5 = _tmp_arg5, _a6 = _tmp_arg6;		\
+       _nr = name;							\
+       __asm__ __volatile__ ("trap  0 \n\t"				\
+			     : "=r" (_a1)				\
+			     : "r" (_nr), "r" (_a1), "r" (_a2),		\
+			       "r" (_a3), "r" (_a4), "r" (_a5),		\
+			       "r" (_a6)				\
+			     : "memory");				\
+	       __sys_result = _a1;					\
+     }									\
+     (int) __sys_result; })
+
+#  define INTERNAL_SYSCALL_RAW7(name, err, arg1, arg2, arg3, arg4,	\
+			      arg5, arg6, arg7)				\
+  ({unsigned int __sys_result;						\
+    register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2);	\
+    register int _tmp_arg3 = (int)(arg3), _tmp_arg4 = (int)(arg4);	\
+    register int _tmp_arg5 = (int)(arg5), _tmp_arg6 = (int)(arg6);	\
+    register int _tmp_arg7 = (int)(arg7);				\
+     {									\
+       register int _nr __asm__ ("r7");					\
+       register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1");		\
+       register int _a3 __asm__ ("a2"), _a4 __asm__ ("a3");		\
+       register int _a5 __asm__ ("r4"), _a6 __asm__ ("r5");		\
+       register int _a7 __asm__ ("r6");					\
+       _a1 = _tmp_arg1, _a2 = _tmp_arg2, _a3 = _tmp_arg3;		\
+       _a4 = _tmp_arg4, _a5 = _tmp_arg5, _a6 = _tmp_arg6;		\
+       _a7 = _tmp_arg7;							\
+       _nr = name;							\
+       __asm__ __volatile__ ("trap  0 \n\t"				\
+			     : "=r" (_a1)				\
+			     : "r" (_nr), "r" (_a1), "r" (_a2),		\
+			       "r" (_a3), "r" (_a4), "r" (_a5),		\
+			       "r" (_a6), "r" (_a7)			\
+			     : "memory");				\
+	       __sys_result = _a1;					\
+     }									\
+     (int) __sys_result; })
+
+# undef INTERNAL_SYSCALL
+# define INTERNAL_SYSCALL(name, err, nr, args...)		\
+  INTERNAL_SYSCALL_RAW##nr(SYS_ify(name), err, args)
+
+# undef INTERNAL_SYSCALL_NCS
+# define INTERNAL_SYSCALL_NCS(number, err, nr, args...)		\
+  INTERNAL_SYSCALL_RAW##nr (number, err, args)
+
+#endif /* __ASSEMBLER__ */
+
+/* Pointer mangling support.  */
+#if (IS_IN (rtld) || \
+     (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread))))
+# ifdef __ASSEMBLER__
+#  define PTR_MANGLE(dst, src, guard)			\
+	grs	t0, 1f;					\
+1:							\
+	lrw	guard, 1b@GOTPC;			\
+	addu	t0, guard;				\
+	lrw	guard, __pointer_chk_guard_local@GOT;	\
+	ldr.w	guard, (t0, guard << 0);		\
+	ldw	guard, (guard, 0);			\
+	xor	dst, src, guard;
+#  define PTR_DEMANGLE(dst, src, guard) PTR_MANGLE (dst, src, guard)
+#  define PTR_MANGLE2(dst, src, guard) \
+	xor	dst, src, guard
+#  define PTR_DEMANGLE2(dst, src, guard) PTR_MANGLE2 (dst, src, guard)
+# else
+extern uintptr_t __pointer_chk_guard_local;
+#  define PTR_MANGLE(var) \
+  (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local)
+#  define PTR_DEMANGLE(var) PTR_MANGLE (var)
+# endif
+#else
+# ifdef __ASSEMBLER__
+#  define PTR_MANGLE(dst, src, guard)		\
+	grs	t0, 1f;				\
+1:						\
+	lrw	guard, 1b@GOTPC;		\
+	addu	t0, guard;			\
+	lrw	guard, __pointer_chk_guard@GOT;	\
+	ldr.w	guard, (t0, guard << 0);	\
+	ldw	guard, (guard, 0);		\
+	xor	dst, src, guard;
+#  define PTR_DEMANGLE(dst, src, guard) PTR_MANGLE (dst, src, guard)
+#  define PTR_MANGLE2(dst, src, guard) \
+	xor	dst, src, guard
+#  define PTR_DEMANGLE2(dst, src, guard) PTR_MANGLE2 (dst, src, guard)
+# else
+extern uintptr_t __pointer_chk_guard;
+#  define PTR_MANGLE(var) \
+  (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard)
+#  define PTR_DEMANGLE(var) PTR_MANGLE (var)
+# endif
+#endif
+
+#endif /* linux/csky/sysdep.h */