diff mbox series

[v6,09/13] LoongArch: Linux ABI

Message ID 20220708065255.2316410-10-caiyinyu@loongson.cn
State New
Headers show
Series GLIBC LoongArch PATCHES | expand

Commit Message

caiyinyu July 8, 2022, 6:52 a.m. UTC
---
 sysdeps/loongarch/dl-irel.h                   |  54 ++++++++++
 sysdeps/loongarch/nptl/pthreaddef.h           |  32 ++++++
 sysdeps/loongarch/sys/ifunc.h                 |  30 ++++++
 .../unix/sysv/linux/loongarch/bits/fcntl.h    |  61 +++++++++++
 .../unix/sysv/linux/loongarch/bits/procfs.h   |  52 +++++++++
 .../linux/loongarch/bits/pthread_stack_min.h  |  20 ++++
 .../unix/sysv/linux/loongarch/bits/sigstack.h |  32 ++++++
 .../unix/sysv/linux/loongarch/getcontext.S    |  59 +++++++++++
 .../unix/sysv/linux/loongarch/localplt.data   |  12 +++
 .../unix/sysv/linux/loongarch/makecontext.c   |  79 ++++++++++++++
 .../unix/sysv/linux/loongarch/setcontext.S    | 100 ++++++++++++++++++
 .../sysv/linux/loongarch/sigcontextinfo.h     |  32 ++++++
 .../unix/sysv/linux/loongarch/swapcontext.S   |  95 +++++++++++++++++
 .../unix/sysv/linux/loongarch/sys/ucontext.h  |  61 +++++++++++
 sysdeps/unix/sysv/linux/loongarch/sys/user.h  |  42 ++++++++
 .../sysv/linux/loongarch/ucontext-macros.h    |  32 ++++++
 .../unix/sysv/linux/loongarch/ucontext_i.sym  |  31 ++++++
 17 files changed, 824 insertions(+)
 create mode 100644 sysdeps/loongarch/dl-irel.h
 create mode 100644 sysdeps/loongarch/nptl/pthreaddef.h
 create mode 100644 sysdeps/loongarch/sys/ifunc.h
 create mode 100644 sysdeps/unix/sysv/linux/loongarch/bits/fcntl.h
 create mode 100644 sysdeps/unix/sysv/linux/loongarch/bits/procfs.h
 create mode 100644 sysdeps/unix/sysv/linux/loongarch/bits/pthread_stack_min.h
 create mode 100644 sysdeps/unix/sysv/linux/loongarch/bits/sigstack.h
 create mode 100644 sysdeps/unix/sysv/linux/loongarch/getcontext.S
 create mode 100644 sysdeps/unix/sysv/linux/loongarch/localplt.data
 create mode 100644 sysdeps/unix/sysv/linux/loongarch/makecontext.c
 create mode 100644 sysdeps/unix/sysv/linux/loongarch/setcontext.S
 create mode 100644 sysdeps/unix/sysv/linux/loongarch/sigcontextinfo.h
 create mode 100644 sysdeps/unix/sysv/linux/loongarch/swapcontext.S
 create mode 100644 sysdeps/unix/sysv/linux/loongarch/sys/ucontext.h
 create mode 100644 sysdeps/unix/sysv/linux/loongarch/sys/user.h
 create mode 100644 sysdeps/unix/sysv/linux/loongarch/ucontext-macros.h
 create mode 100644 sysdeps/unix/sysv/linux/loongarch/ucontext_i.sym

Comments

Adhemerval Zanella Netto July 13, 2022, 4:35 p.m. UTC | #1
Looks ok, some comments below.

On 08/07/22 03:52, caiyinyu wrote:
> ---
>  sysdeps/loongarch/dl-irel.h                   |  54 ++++++++++
>  sysdeps/loongarch/nptl/pthreaddef.h           |  32 ++++++
>  sysdeps/loongarch/sys/ifunc.h                 |  30 ++++++
>  .../unix/sysv/linux/loongarch/bits/fcntl.h    |  61 +++++++++++
>  .../unix/sysv/linux/loongarch/bits/procfs.h   |  52 +++++++++
>  .../linux/loongarch/bits/pthread_stack_min.h  |  20 ++++
>  .../unix/sysv/linux/loongarch/bits/sigstack.h |  32 ++++++
>  .../unix/sysv/linux/loongarch/getcontext.S    |  59 +++++++++++
>  .../unix/sysv/linux/loongarch/localplt.data   |  12 +++
>  .../unix/sysv/linux/loongarch/makecontext.c   |  79 ++++++++++++++
>  .../unix/sysv/linux/loongarch/setcontext.S    | 100 ++++++++++++++++++
>  .../sysv/linux/loongarch/sigcontextinfo.h     |  32 ++++++
>  .../unix/sysv/linux/loongarch/swapcontext.S   |  95 +++++++++++++++++
>  .../unix/sysv/linux/loongarch/sys/ucontext.h  |  61 +++++++++++
>  sysdeps/unix/sysv/linux/loongarch/sys/user.h  |  42 ++++++++
>  .../sysv/linux/loongarch/ucontext-macros.h    |  32 ++++++
>  .../unix/sysv/linux/loongarch/ucontext_i.sym  |  31 ++++++
>  17 files changed, 824 insertions(+)
>  create mode 100644 sysdeps/loongarch/dl-irel.h
>  create mode 100644 sysdeps/loongarch/nptl/pthreaddef.h
>  create mode 100644 sysdeps/loongarch/sys/ifunc.h
>  create mode 100644 sysdeps/unix/sysv/linux/loongarch/bits/fcntl.h
>  create mode 100644 sysdeps/unix/sysv/linux/loongarch/bits/procfs.h
>  create mode 100644 sysdeps/unix/sysv/linux/loongarch/bits/pthread_stack_min.h
>  create mode 100644 sysdeps/unix/sysv/linux/loongarch/bits/sigstack.h
>  create mode 100644 sysdeps/unix/sysv/linux/loongarch/getcontext.S
>  create mode 100644 sysdeps/unix/sysv/linux/loongarch/localplt.data
>  create mode 100644 sysdeps/unix/sysv/linux/loongarch/makecontext.c
>  create mode 100644 sysdeps/unix/sysv/linux/loongarch/setcontext.S
>  create mode 100644 sysdeps/unix/sysv/linux/loongarch/sigcontextinfo.h
>  create mode 100644 sysdeps/unix/sysv/linux/loongarch/swapcontext.S
>  create mode 100644 sysdeps/unix/sysv/linux/loongarch/sys/ucontext.h
>  create mode 100644 sysdeps/unix/sysv/linux/loongarch/sys/user.h
>  create mode 100644 sysdeps/unix/sysv/linux/loongarch/ucontext-macros.h
>  create mode 100644 sysdeps/unix/sysv/linux/loongarch/ucontext_i.sym
> 
> diff --git a/sysdeps/loongarch/dl-irel.h b/sysdeps/loongarch/dl-irel.h
> new file mode 100644
> index 0000000000..4440453f06
> --- /dev/null
> +++ b/sysdeps/loongarch/dl-irel.h
> @@ -0,0 +1,54 @@
> +/* Machine-dependent ELF indirect relocation inline functions.
> +   Copyright (C) 2022 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef _DL_IREL_H
> +#define _DL_IREL_H
> +
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <sys/ifunc.h>
> +
> +#define ELF_MACHINE_IRELA 1
> +
> +static inline ElfW (Addr) __attribute ((always_inline))
> +elf_ifunc_invoke (ElfW (Addr) addr)
> +{
> +  __ifunc_arg_t arg =
> +  {
> +    ._size = sizeof (__ifunc_arg_t),
> +    ._hwcap = GLRO(dl_hwcap),
> +  };
> +  return ((ElfW(Addr) (*) (const __ifunc_arg_t *)) (addr)) (&arg);
> +}
> +
> +static inline void __attribute ((always_inline))
> +elf_irela (const ElfW (Rela) *reloc)
> +{
> +  ElfW (Addr) *const reloc_addr = (void *) reloc->r_offset;
> +  const unsigned long int r_type = ELFW (R_TYPE) (reloc->r_info);
> +
> +  if (__glibc_likely (r_type == R_LARCH_IRELATIVE))
> +    {
> +      ElfW (Addr) value = elf_ifunc_invoke (reloc->r_addend);
> +      *reloc_addr = value;
> +    }
> +  else
> +    __libc_fatal ("Unexpected reloc type in static binary.\n");
> +}
> +
> +#endif /* dl-irel.h */

Ok.

> diff --git a/sysdeps/loongarch/nptl/pthreaddef.h b/sysdeps/loongarch/nptl/pthreaddef.h
> new file mode 100644
> index 0000000000..955566cddc
> --- /dev/null
> +++ b/sysdeps/loongarch/nptl/pthreaddef.h
> @@ -0,0 +1,32 @@
> +/* pthread machine parameter definitions.
> +   Copyright (C) 2022 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +/* Default stack size.  */
> +#define ARCH_STACK_DEFAULT_SIZE (2 * 1024 * 1024)
> +
> +/* Minimum guard size.  */
> +#define ARCH_MIN_GUARD_SIZE 0
> +
> +/* 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
> +
> +/* Location of current stack frame.  */
> +#define CURRENT_STACK_FRAME __builtin_frame_address (0)
> diff --git a/sysdeps/loongarch/sys/ifunc.h b/sysdeps/loongarch/sys/ifunc.h
> new file mode 100644
> index 0000000000..461df20c96
> --- /dev/null
> +++ b/sysdeps/loongarch/sys/ifunc.h
> @@ -0,0 +1,30 @@
> +/* Definitions used by LoongArch indirect function resolvers.
> +   Copyright (C) 2022 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef _SYS_IFUNC_H
> +#define _SYS_IFUNC_H
> +
> +struct __ifunc_arg_t
> +{
> +  unsigned long _size; /* Size of the struct, so it can grow.  */
> +  unsigned long _hwcap;
> +};
> +
> +typedef struct __ifunc_arg_t __ifunc_arg_t;
> +
> +#endif

Ok.

> diff --git a/sysdeps/unix/sysv/linux/loongarch/bits/fcntl.h b/sysdeps/unix/sysv/linux/loongarch/bits/fcntl.h
> new file mode 100644
> index 0000000000..bf1e254234
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/loongarch/bits/fcntl.h
> @@ -0,0 +1,61 @@
> +/* O_*, F_*, FD_* bit values for the generic Linux/LoongArch ABI.
> +   Copyright (C) 2022 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
> +   <https://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').  */
> +#ifndef __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>

Ok.

> diff --git a/sysdeps/unix/sysv/linux/loongarch/bits/procfs.h b/sysdeps/unix/sysv/linux/loongarch/bits/procfs.h
> new file mode 100644
> index 0000000000..2db777b38c
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/loongarch/bits/procfs.h
> @@ -0,0 +1,52 @@
> +/* Types for registers for sys/procfs.h.
> +   Copyright (C) 2022 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
> +   <https://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 __uint64_t elf_greg_t;
> +
> +/* And the whole bunch of them.  We could have used `struct
> +   pt_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_struct) / sizeof (elf_greg_t))
> +typedef elf_greg_t elf_gregset_t[ELF_NGREG];
> +
> +#define ELF_NFPREG 34 /* 32 FPRs + 8-byte byte-vec for fcc + 4-byte FCR */
> +typedef union
> +{
> +  double d;
> +  float f;
> +} elf_fpreg_t;
> +typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
> +
> +typedef union
> +{
> +  double d[2];
> +  float f[4];
> +} __attribute__ ((__aligned__ (16))) elf_lsxregset_t[32];
> +
> +typedef union
> +{
> +  double d[4];
> +  float f[8];
> +} __attribute__ ((__aligned__ (32))) elf_lasxregset_t[32];

Ok.

> diff --git a/sysdeps/unix/sysv/linux/loongarch/bits/pthread_stack_min.h b/sysdeps/unix/sysv/linux/loongarch/bits/pthread_stack_min.h
> new file mode 100644
> index 0000000000..072c2ade42
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/loongarch/bits/pthread_stack_min.h
> @@ -0,0 +1,20 @@
> +/* Definition of PTHREAD_STACK_MIN.  LoongArch Linux version.
> +   Copyright (C) 2022 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +/* Minimum size for a thread.  At least two pages with 64k pages.  */
> +#define PTHREAD_STACK_MIN	131072

Ok.

> diff --git a/sysdeps/unix/sysv/linux/loongarch/bits/sigstack.h b/sysdeps/unix/sysv/linux/loongarch/bits/sigstack.h
> new file mode 100644
> index 0000000000..238c1a98e6
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/loongarch/bits/sigstack.h
> @@ -0,0 +1,32 @@
> +/* sigstack, sigaltstack definitions.
> +   Copyright (C) 2022 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef _BITS_SIGSTACK_H
> +#define _BITS_SIGSTACK_H 1
> +
> +#if !defined _SIGNAL_H && !defined _SYS_UCONTEXT_H
> +# error "Never include this file directly.  Use <signal.h> instead"
> +#endif
> +
> +/* Minimum stack size for a signal handler.  */
> +#define MINSIGSTKSZ	4096
> +
> +/* System default stack size.  */
> +#define SIGSTKSZ	16384
> +
> +#endif /* bits/sigstack.h */

Ok.

> diff --git a/sysdeps/unix/sysv/linux/loongarch/getcontext.S b/sysdeps/unix/sysv/linux/loongarch/getcontext.S
> new file mode 100644
> index 0000000000..43b95e9715
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/loongarch/getcontext.S
> @@ -0,0 +1,59 @@
> +/* Save current context.
> +   Copyright (C) 2022 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include "ucontext-macros.h"
> +
> +/* int getcontext (ucontext_t *ucp) */
> +
> +	.text
> +LEAF (__getcontext)
> +	SAVE_INT_REG (ra,   1, a0)
> +	SAVE_INT_REG (sp,   3, a0)
> +	SAVE_INT_REG (zero, 4, a0) /* return 0 by overwriting a0.  */
> +	SAVE_INT_REG (x,   21, a0)
> +	SAVE_INT_REG (fp,  22, a0)
> +	SAVE_INT_REG (s0,  23, a0)
> +	SAVE_INT_REG (s1,  24, a0)
> +	SAVE_INT_REG (s2,  25, a0)
> +	SAVE_INT_REG (s3,  26, a0)
> +	SAVE_INT_REG (s4,  27, a0)
> +	SAVE_INT_REG (s5,  28, a0)
> +	SAVE_INT_REG (s6,  29, a0)
> +	SAVE_INT_REG (s7,  30, a0)
> +	SAVE_INT_REG (s8,  31, a0)
> +	st.d		ra, a0, MCONTEXT_PC
> +
> +/* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */
> +	li.d		a3, _NSIG8
> +	li.d		a2, UCONTEXT_SIGMASK
> +	add.d		a2, a2, a0
> +	ori		a1, zero,0
> +	li.d		a0, SIG_BLOCK
> +
> +	li.d		a7, SYS_ify (rt_sigprocmask)
> +	syscall		0
> +	blt		a0, zero, 99f
> +
> +	jirl		$r0, $r1, 0
> +
> +99:
> +	b		__syscall_error
> +
> +PSEUDO_END (__getcontext)
> +
> +weak_alias (__getcontext, getcontext)

Ok.

> diff --git a/sysdeps/unix/sysv/linux/loongarch/localplt.data b/sysdeps/unix/sysv/linux/loongarch/localplt.data
> new file mode 100644
> index 0000000000..817ab2659a
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/loongarch/localplt.data
> @@ -0,0 +1,12 @@
> +# 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: realloc
> +# 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

Ok.

> diff --git a/sysdeps/unix/sysv/linux/loongarch/makecontext.c b/sysdeps/unix/sysv/linux/loongarch/makecontext.c
> new file mode 100644
> index 0000000000..d29c8056cb
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/loongarch/makecontext.c
> @@ -0,0 +1,79 @@
> +/* Create new context.
> +   Copyright (C) 2022 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
> +   <https://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;

The __gregs is unsigned, why are you using signed variable for the stack?

> +
> +  _Static_assert(LARCH_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[LARCH_REG_RA] = 0;
> +  ucp->uc_mcontext.__gregs[LARCH_REG_S0] = 0;
> +  ucp->uc_mcontext.__gregs[LARCH_REG_S1] = (long int) func;
> +  ucp->uc_mcontext.__gregs[LARCH_REG_S2] = (long int) ucp->uc_link;
> +  ucp->uc_mcontext.__gregs[LARCH_REG_SP] = sp;
> +  ucp->uc_mcontext.__pc = (long int) &__start_context;

Both __gregs and __pc are a unsigned long lont, I think it would be better 
to use uintptr_t here.

> +
> +  /* Put args in a0-a7, then put any remaining args on the stack.  */
> +  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 0] = a0;
> +  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 1] = a1;
> +  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 2] = a2;
> +  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 3] = a3;
> +  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 4] = a4;
> +
> +  if (__glibc_unlikely (argc > 5))
> +    {
> +      va_list vl;
> +      va_start (vl, a4);
> +
> +      long reg_args = argc < LARCH_REG_NARGS ? argc : LARCH_REG_NARGS;

Use 'long int' here.

> +      for (i = 5; i < reg_args; i++)

Move the long int i to define within the loop definition.

> +	ucp->uc_mcontext.__gregs[LARCH_REG_A0 + i] = va_arg (vl, long);
> +
> +      long int stack_args = argc - reg_args;
> +      if (stack_args > 0)
> +	{
> +	  sp = (sp - stack_args * sizeof (long int)) & ALMASK;
> +	  ucp->uc_mcontext.__gregs[LARCH_REG_SP] = sp;
> +	  for (i = 0; i < stack_args; i++)
> +	    ((long int *) sp)[i] = va_arg (vl, long int);
> +	}
> +
> +      va_end (vl);
> +    }
> +}
> +
> +weak_alias (__makecontext, makecontext)
> diff --git a/sysdeps/unix/sysv/linux/loongarch/setcontext.S b/sysdeps/unix/sysv/linux/loongarch/setcontext.S
> new file mode 100644
> index 0000000000..7295900149
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/loongarch/setcontext.S
> @@ -0,0 +1,100 @@
> +/* Set current context.
> +   Copyright (C) 2022 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
> +   <https://www.gnu.org/licenses/>.  */
> +#include "sys/regdef.h"
> +#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)
> +
> +	addi.d		sp, sp, -16
> +	st.d		a0, sp, 0	/* Save ucp to stack */
> +
> +/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, NULL, _NSIG8) */
> +	li.d		a3, _NSIG8
> +	li.d		a2, 0
> +	li.d		a1, UCONTEXT_SIGMASK
> +	add.d		a1, a1, a0
> +	li.d		a0, SIG_SETMASK
> +
> +	li.d		a7, SYS_ify (rt_sigprocmask)
> +	syscall		0
> +
> +	blt		a0, $r0, 99f
> +
> +	ld.d		t0, sp, 0	/* Load ucp to t0 */
> +	cfi_def_cfa (12, 0)
> +
> +/* Note the contents of argument registers will be random
> +   unless makecontext() has been called.  */
> +	RESTORE_INT_REG(ra,   1, t0)
> +	RESTORE_INT_REG(sp,   3, t0)
> +	RESTORE_INT_REG(a0,   4, t0)
> +	RESTORE_INT_REG(a1,   5, t0)
> +	RESTORE_INT_REG(a2,   6, t0)
> +	RESTORE_INT_REG(a3,   7, t0)
> +	RESTORE_INT_REG(a4,   8, t0)
> +	RESTORE_INT_REG(a5,   9, t0)
> +	RESTORE_INT_REG(a6,  10, t0)
> +	RESTORE_INT_REG(a7,  11, t0)
> +	RESTORE_INT_REG(x,   21, t0)
> +	RESTORE_INT_REG(fp,  22, t0)
> +	RESTORE_INT_REG(s0,  23, t0)
> +	RESTORE_INT_REG(s1,  24, t0)
> +	RESTORE_INT_REG(s2,  25, t0)
> +	RESTORE_INT_REG(s3,  26, t0)
> +	RESTORE_INT_REG(s4,  27, t0)
> +	RESTORE_INT_REG(s5,  28, t0)
> +	RESTORE_INT_REG(s6,  29, t0)
> +	RESTORE_INT_REG(s7,  30, t0)
> +	RESTORE_INT_REG(s8,  31, t0)
> +
> +	ld.d		t1, t0, MCONTEXT_PC
> +	jirl		$r0,t1,0
> +
> +99:
> +	addi.d		sp, sp, 16
> +	b		__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 (1, 23)
> +
> +	/* Call the function passed to makecontext.  */
> +	jirl		$r1,s1,0
> +
> +	/* Invoke subsequent context if present, else exit(0).  */
> +	ori		a0, s2, 0
> +	beqz		s2, 1f
> +	bl		__setcontext
> +1:
> +	b		HIDDEN_JUMPTARGET(exit)
> +
> +PSEUDO_END (__start_context)
> diff --git a/sysdeps/unix/sysv/linux/loongarch/sigcontextinfo.h b/sysdeps/unix/sysv/linux/loongarch/sigcontextinfo.h
> new file mode 100644
> index 0000000000..5e202bc0b4
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/loongarch/sigcontextinfo.h
> @@ -0,0 +1,32 @@
> +/* LoongArch definitions for signal handling calling conventions.
> +   Copyright (C) 2022 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef _SIGCONTEXTINFO_H
> +#define _SIGCONTEXTINFO_H
> +
> +#include <stdint.h>
> +#include <sys/ucontext.h>
> +
> +static inline uintptr_t
> +sigcontext_get_pc (const ucontext_t *ctx)
> +{
> +  return ctx->uc_mcontext.__pc;
> +}
> +
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/loongarch/swapcontext.S b/sysdeps/unix/sysv/linux/loongarch/swapcontext.S
> new file mode 100644
> index 0000000000..bb22cd2f00
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/loongarch/swapcontext.S
> @@ -0,0 +1,95 @@
> +/* Save and set current context.
> +   Copyright (C) 2022 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include "ucontext-macros.h"
> +
> +/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */
> +
> +LEAF (__swapcontext)
> +	ori		a2, sp, 0		/* Save sp to a2 */
> +	addi.d		sp, sp, -16
> +	st.d		a1, sp, 0
> +	ori		t0, a1, 0
> +
> +	SAVE_INT_REG (ra,   1, a0)
> +	SAVE_INT_REG (a2,   3, a0)		/* Store sp */
> +	SAVE_INT_REG (zero, 4, a0)		/* return 0 by overwriting a0 */
> +	SAVE_INT_REG (x,   21, a0)
> +	SAVE_INT_REG (fp,  22, a0)
> +	SAVE_INT_REG (s0,  23, a0)
> +	SAVE_INT_REG (s1,  24, a0)
> +	SAVE_INT_REG (s2,  25, a0)
> +	SAVE_INT_REG (s3,  26, a0)
> +	SAVE_INT_REG (s4,  27, a0)
> +	SAVE_INT_REG (s5,  28, a0)
> +	SAVE_INT_REG (s6,  29, a0)
> +	SAVE_INT_REG (s7,  30, a0)
> +	SAVE_INT_REG (s8,  31, a0)
> +
> +	st.d		ra, a0, MCONTEXT_PC
> +
> +/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask, _NSIG8) */
> +	li.d		a3, _NSIG8
> +	li.d		a2, UCONTEXT_SIGMASK
> +	add.d		a2, a2, a0
> +	li.d		a1, UCONTEXT_SIGMASK
> +	add.d		a1, a1, t0
> +	li.d		a0, SIG_SETMASK
> +
> +	li.d		a7, SYS_ify (rt_sigprocmask)
> +	syscall		0
> +
> +	blt		a0, zero, 99f
> +
> +	ld.d		t0, sp, 0		/* Load a1 to t0 */
> +
> +/* Note the contents of argument registers will be random
> +   unless makecontext() has been called.  */
> +	RESTORE_INT_REG (ra,   1, t0)
> +	RESTORE_INT_REG (sp,   3, t0)
> +	RESTORE_INT_REG (a0,   4, t0)
> +	RESTORE_INT_REG (a1,   5, t0)
> +	RESTORE_INT_REG (a2,   6, t0)
> +	RESTORE_INT_REG (a3,   7, t0)
> +	RESTORE_INT_REG (a4,   8, t0)
> +	RESTORE_INT_REG (a5,   9, t0)
> +	RESTORE_INT_REG (a6,  10, t0)
> +	RESTORE_INT_REG (a7,  11, t0)
> +	RESTORE_INT_REG (x,   21, t0)
> +	RESTORE_INT_REG (fp,  22, t0)
> +	RESTORE_INT_REG (s0,  23, t0)
> +	RESTORE_INT_REG (s1,  24, t0)
> +	RESTORE_INT_REG (s2,  25, t0)
> +	RESTORE_INT_REG (s3,  26, t0)
> +	RESTORE_INT_REG (s4,  27, t0)
> +	RESTORE_INT_REG (s5,  28, t0)
> +	RESTORE_INT_REG (s6,  29, t0)
> +	RESTORE_INT_REG (s7,  30, t0)
> +	RESTORE_INT_REG (s8,  31, t0)
> +
> +	ld.d		t1, t0, MCONTEXT_PC
> +	jirl		$r0, t1, 0
> +
> +
> +99:
> +	addi.d		sp, sp, 16
> +	b		__syscall_error
> +
> +PSEUDO_END (__swapcontext)
> +
> +weak_alias (__swapcontext, swapcontext)
> diff --git a/sysdeps/unix/sysv/linux/loongarch/sys/ucontext.h b/sysdeps/unix/sysv/linux/loongarch/sys/ucontext.h
> new file mode 100644
> index 0000000000..e334a45a44
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/loongarch/sys/ucontext.h
> @@ -0,0 +1,61 @@
> +/* struct ucontext definition.
> +   Copyright (C) 2022 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
> +   <https://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>
> +
> +#ifdef __USE_MISC
> +#define LARCH_NGREG 32
> +
> +#define LARCH_REG_RA 1
> +#define LARCH_REG_SP 3
> +#define LARCH_REG_S0 23
> +#define LARCH_REG_S1 24
> +#define LARCH_REG_A0 4
> +#define LARCH_REG_S2 25
> +#define LARCH_REG_NARGS 8
> +
> +#endif
> +
> +typedef struct mcontext_t
> +{
> +  unsigned long long __pc;
> +  unsigned long long __gregs[32];
> +  unsigned int __flags;
> +  unsigned long long __extcontext[0] __attribute__((__aligned__(16)));
> +} 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;
> +  mcontext_t uc_mcontext;
> +} ucontext_t;
> +
> +#endif /* sys/ucontext.h */
> diff --git a/sysdeps/unix/sysv/linux/loongarch/sys/user.h b/sysdeps/unix/sysv/linux/loongarch/sys/user.h
> new file mode 100644
> index 0000000000..55181de816
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/loongarch/sys/user.h
> @@ -0,0 +1,42 @@
> +/* struct user_regs_struct definition for LoongArch.
> +   Copyright (C) 2022 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef _SYS_USER_H
> +#define _SYS_USER_H 1
> +
> +#include <stdint.h>
> +
> +struct user_regs_struct
> +{
> +  /* Saved main processor registers. */
> +  uint64_t regs[32];
> +
> +  /* Saved special registers. */
> +  uint64_t orig_a0;
> +  uint64_t csr_era;
> +  uint64_t csr_badv;
> +  uint64_t reserved[10];
> +};
> +
> +struct user_fp_struct {
> +  uint64_t    fpr[32];
> +  uint64_t    fcc;
> +  uint32_t    fcsr;
> +};
> +
> +#endif /* _SYS_USER_H */
> diff --git a/sysdeps/unix/sysv/linux/loongarch/ucontext-macros.h b/sysdeps/unix/sysv/linux/loongarch/ucontext-macros.h
> new file mode 100644
> index 0000000000..859eba464b
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/loongarch/ucontext-macros.h
> @@ -0,0 +1,32 @@
> +/* Macros for ucontext routines.
> +   Copyright (C) 2022 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef _LINUX_LOONGARCH_UCONTEXT_MACROS_H
> +#define _LINUX_LOONGARCH_UCONTEXT_MACROS_H
> +
> +#include <sysdep.h>
> +#include <sys/asm.h>
> +#include "ucontext_i.h"
> +
> +#define SAVE_INT_REG(name, num, base) \
> +  REG_S name, base, ((num) *SZREG + MCONTEXT_GREGS)
> +
> +#define RESTORE_INT_REG(name, num, base) \
> +  REG_L name, base, ((num) *SZREG + MCONTEXT_GREGS)
> +
> +#endif /* _LINUX_LOONGARCH_UCONTEXT_MACROS_H */
> diff --git a/sysdeps/unix/sysv/linux/loongarch/ucontext_i.sym b/sysdeps/unix/sysv/linux/loongarch/ucontext_i.sym
> new file mode 100644
> index 0000000000..f27afad56f
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/loongarch/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_PC			mcontext (__pc)
> +MCONTEXT_GREGS			mcontext (__gregs)
> +
> +UCONTEXT_SIZE			sizeof (ucontext_t)
caiyinyu July 15, 2022, 1:48 a.m. UTC | #2
+#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;

The __gregs is unsigned, why are you using signed variable for the stack?

> +
> +  _Static_assert(LARCH_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[LARCH_REG_RA] = 0;
> +  ucp->uc_mcontext.__gregs[LARCH_REG_S0] = 0;
> +  ucp->uc_mcontext.__gregs[LARCH_REG_S1] = (long int) func;
> +  ucp->uc_mcontext.__gregs[LARCH_REG_S2] = (long int) ucp->uc_link;
> +  ucp->uc_mcontext.__gregs[LARCH_REG_SP] = sp;
> +  ucp->uc_mcontext.__pc = (long int) &__start_context;

Both __gregs and __pc are a unsigned long lont, I think it would be better
to use uintptr_t here.

> +
> +  /* Put args in a0-a7, then put any remaining args on the stack.  */
> +  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 0] = a0;
> +  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 1] = a1;
> +  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 2] = a2;
> +  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 3] = a3;
> +  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 4] = a4;
> +
> +  if (__glibc_unlikely (argc > 5))
> +    {
> +      va_list vl;
> +      va_start (vl, a4);
> +
> +      long reg_args = argc < LARCH_REG_NARGS ? argc : LARCH_REG_NARGS;

Use 'long int' here.

> +      for (i = 5; i < reg_args; i++)

Move the long int i to define within the loop definition.

> +	ucp->uc_mcontext.__gregs[LARCH_REG_A0 + i] = va_arg (vl, long);
> +
> +      long int stack_args = argc - reg_args;
> +      if (stack_args > 0)
> +	{
> +	  sp = (sp - stack_args * sizeof (long int)) & ALMASK;
> +	  ucp->uc_mcontext.__gregs[LARCH_REG_SP] = sp;
> +	  for (i = 0; i < stack_args; i++)
> +	    ((long int *) sp)[i] = va_arg (vl, long int);
> +	}
> +
> +      va_end (vl);
> +    }
> +}


*Fixed.
*

*Reference: or1k
*

*Thanks.*

**

*>>>>>>>*

**

*diff --git a/sysdeps/unix/sysv/linux/loongarch/makecontext.c 
b/sysdeps/unix/sysv/linux/loongarch/makecontext.c
index d29c8056cb..94a45bf4ad 100644
--- a/sysdeps/unix/sysv/linux/loongarch/makecontext.c
+++ b/sysdeps/unix/sysv/linux/loongarch/makecontext.c
@@ -28,48 +28,50 @@ __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;
+  unsigned long int *sp;

    _Static_assert(LARCH_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;
+  sp = (unsigned long int *)
+       (((uintptr_t) 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[LARCH_REG_RA] = 0;
-  ucp->uc_mcontext.__gregs[LARCH_REG_S0] = 0;
-  ucp->uc_mcontext.__gregs[LARCH_REG_S1] = (long int) func;
-  ucp->uc_mcontext.__gregs[LARCH_REG_S2] = (long int) ucp->uc_link;
-  ucp->uc_mcontext.__gregs[LARCH_REG_SP] = sp;
-  ucp->uc_mcontext.__pc = (long int) &__start_context;
+  ucp->uc_mcontext.__gregs[LARCH_REG_RA] = (uintptr_t) 0;
+  ucp->uc_mcontext.__gregs[LARCH_REG_S0] = (uintptr_t) 0;
+  ucp->uc_mcontext.__gregs[LARCH_REG_S1] = (uintptr_t) func;
+  ucp->uc_mcontext.__gregs[LARCH_REG_S2] = (uintptr_t) ucp->uc_link;
+  ucp->uc_mcontext.__gregs[LARCH_REG_SP] = (uintptr_t) sp;
+  ucp->uc_mcontext.__pc = (uintptr_t) &__start_context;

    /* Put args in a0-a7, then put any remaining args on the stack.  */
-  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 0] = a0;
-  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 1] = a1;
-  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 2] = a2;
-  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 3] = a3;
-  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 4] = a4;
+  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 0] = (uintptr_t) a0;
+  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 1] = (uintptr_t) a1;
+  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 2] = (uintptr_t) a2;
+  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 3] = (uintptr_t) a3;
+  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 4] = (uintptr_t) a4;

    if (__glibc_unlikely (argc > 5))
      {
        va_list vl;
        va_start (vl, a4);

-      long reg_args = argc < LARCH_REG_NARGS ? argc : LARCH_REG_NARGS;
-      for (i = 5; i < reg_args; i++)
-    ucp->uc_mcontext.__gregs[LARCH_REG_A0 + i] = va_arg (vl, long);
+      long int reg_args = argc < LARCH_REG_NARGS ? argc : LARCH_REG_NARGS;
+      for (long int i = 5; i < reg_args; i++)
+    ucp->uc_mcontext.__gregs[LARCH_REG_A0 + i] = va_arg (vl, unsigned 
long int);

        long int stack_args = argc - reg_args;
        if (stack_args > 0)
      {
-      sp = (sp - stack_args * sizeof (long int)) & ALMASK;
-      ucp->uc_mcontext.__gregs[LARCH_REG_SP] = sp;
-      for (i = 0; i < stack_args; i++)
-        ((long int *) sp)[i] = va_arg (vl, long int);
+      sp = (unsigned long int *)
+           (((uintptr_t) sp - stack_args * sizeof (long int)) & ALMASK);
+      ucp->uc_mcontext.__gregs[LARCH_REG_SP] = (uintptr_t) sp;
+      for (long int i = 0; i < stack_args; i++)
+        sp[i] = va_arg (vl, unsigned long int);
      }

        va_end (vl);
*

**

*<<<<<<<<<<<*





在 2022/7/14 上午12:35, Adhemerval Zanella Netto 写道:
> Looks ok, some comments below.
>
> On 08/07/22 03:52, caiyinyu wrote:
>> ---
>>   sysdeps/loongarch/dl-irel.h                   |  54 ++++++++++
>>   sysdeps/loongarch/nptl/pthreaddef.h           |  32 ++++++
>>   sysdeps/loongarch/sys/ifunc.h                 |  30 ++++++
>>   .../unix/sysv/linux/loongarch/bits/fcntl.h    |  61 +++++++++++
>>   .../unix/sysv/linux/loongarch/bits/procfs.h   |  52 +++++++++
>>   .../linux/loongarch/bits/pthread_stack_min.h  |  20 ++++
>>   .../unix/sysv/linux/loongarch/bits/sigstack.h |  32 ++++++
>>   .../unix/sysv/linux/loongarch/getcontext.S    |  59 +++++++++++
>>   .../unix/sysv/linux/loongarch/localplt.data   |  12 +++
>>   .../unix/sysv/linux/loongarch/makecontext.c   |  79 ++++++++++++++
>>   .../unix/sysv/linux/loongarch/setcontext.S    | 100 ++++++++++++++++++
>>   .../sysv/linux/loongarch/sigcontextinfo.h     |  32 ++++++
>>   .../unix/sysv/linux/loongarch/swapcontext.S   |  95 +++++++++++++++++
>>   .../unix/sysv/linux/loongarch/sys/ucontext.h  |  61 +++++++++++
>>   sysdeps/unix/sysv/linux/loongarch/sys/user.h  |  42 ++++++++
>>   .../sysv/linux/loongarch/ucontext-macros.h    |  32 ++++++
>>   .../unix/sysv/linux/loongarch/ucontext_i.sym  |  31 ++++++
>>   17 files changed, 824 insertions(+)
>>   create mode 100644 sysdeps/loongarch/dl-irel.h
>>   create mode 100644 sysdeps/loongarch/nptl/pthreaddef.h
>>   create mode 100644 sysdeps/loongarch/sys/ifunc.h
>>   create mode 100644 sysdeps/unix/sysv/linux/loongarch/bits/fcntl.h
>>   create mode 100644 sysdeps/unix/sysv/linux/loongarch/bits/procfs.h
>>   create mode 100644 sysdeps/unix/sysv/linux/loongarch/bits/pthread_stack_min.h
>>   create mode 100644 sysdeps/unix/sysv/linux/loongarch/bits/sigstack.h
>>   create mode 100644 sysdeps/unix/sysv/linux/loongarch/getcontext.S
>>   create mode 100644 sysdeps/unix/sysv/linux/loongarch/localplt.data
>>   create mode 100644 sysdeps/unix/sysv/linux/loongarch/makecontext.c
>>   create mode 100644 sysdeps/unix/sysv/linux/loongarch/setcontext.S
>>   create mode 100644 sysdeps/unix/sysv/linux/loongarch/sigcontextinfo.h
>>   create mode 100644 sysdeps/unix/sysv/linux/loongarch/swapcontext.S
>>   create mode 100644 sysdeps/unix/sysv/linux/loongarch/sys/ucontext.h
>>   create mode 100644 sysdeps/unix/sysv/linux/loongarch/sys/user.h
>>   create mode 100644 sysdeps/unix/sysv/linux/loongarch/ucontext-macros.h
>>   create mode 100644 sysdeps/unix/sysv/linux/loongarch/ucontext_i.sym
>>
>> diff --git a/sysdeps/loongarch/dl-irel.h b/sysdeps/loongarch/dl-irel.h
>> new file mode 100644
>> index 0000000000..4440453f06
>> --- /dev/null
>> +++ b/sysdeps/loongarch/dl-irel.h
>> @@ -0,0 +1,54 @@
>> +/* Machine-dependent ELF indirect relocation inline functions.
>> +   Copyright (C) 2022 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
>> +<https://www.gnu.org/licenses/>.  */
>> +
>> +#ifndef _DL_IREL_H
>> +#define _DL_IREL_H
>> +
>> +#include <stdio.h>
>> +#include <unistd.h>
>> +#include <sys/ifunc.h>
>> +
>> +#define ELF_MACHINE_IRELA 1
>> +
>> +static inline ElfW (Addr) __attribute ((always_inline))
>> +elf_ifunc_invoke (ElfW (Addr) addr)
>> +{
>> +  __ifunc_arg_t arg =
>> +  {
>> +    ._size = sizeof (__ifunc_arg_t),
>> +    ._hwcap = GLRO(dl_hwcap),
>> +  };
>> +  return ((ElfW(Addr) (*) (const __ifunc_arg_t *)) (addr)) (&arg);
>> +}
>> +
>> +static inline void __attribute ((always_inline))
>> +elf_irela (const ElfW (Rela) *reloc)
>> +{
>> +  ElfW (Addr) *const reloc_addr = (void *) reloc->r_offset;
>> +  const unsigned long int r_type = ELFW (R_TYPE) (reloc->r_info);
>> +
>> +  if (__glibc_likely (r_type == R_LARCH_IRELATIVE))
>> +    {
>> +      ElfW (Addr) value = elf_ifunc_invoke (reloc->r_addend);
>> +      *reloc_addr = value;
>> +    }
>> +  else
>> +    __libc_fatal ("Unexpected reloc type in static binary.\n");
>> +}
>> +
>> +#endif /* dl-irel.h */
> Ok.
>
>> diff --git a/sysdeps/loongarch/nptl/pthreaddef.h b/sysdeps/loongarch/nptl/pthreaddef.h
>> new file mode 100644
>> index 0000000000..955566cddc
>> --- /dev/null
>> +++ b/sysdeps/loongarch/nptl/pthreaddef.h
>> @@ -0,0 +1,32 @@
>> +/* pthread machine parameter definitions.
>> +   Copyright (C) 2022 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
>> +<https://www.gnu.org/licenses/>.  */
>> +
>> +/* Default stack size.  */
>> +#define ARCH_STACK_DEFAULT_SIZE (2 * 1024 * 1024)
>> +
>> +/* Minimum guard size.  */
>> +#define ARCH_MIN_GUARD_SIZE 0
>> +
>> +/* 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
>> +
>> +/* Location of current stack frame.  */
>> +#define CURRENT_STACK_FRAME __builtin_frame_address (0)
>> diff --git a/sysdeps/loongarch/sys/ifunc.h b/sysdeps/loongarch/sys/ifunc.h
>> new file mode 100644
>> index 0000000000..461df20c96
>> --- /dev/null
>> +++ b/sysdeps/loongarch/sys/ifunc.h
>> @@ -0,0 +1,30 @@
>> +/* Definitions used by LoongArch indirect function resolvers.
>> +   Copyright (C) 2022 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
>> +<https://www.gnu.org/licenses/>.  */
>> +
>> +#ifndef _SYS_IFUNC_H
>> +#define _SYS_IFUNC_H
>> +
>> +struct __ifunc_arg_t
>> +{
>> +  unsigned long _size; /* Size of the struct, so it can grow.  */
>> +  unsigned long _hwcap;
>> +};
>> +
>> +typedef struct __ifunc_arg_t __ifunc_arg_t;
>> +
>> +#endif
> Ok.
>
>> diff --git a/sysdeps/unix/sysv/linux/loongarch/bits/fcntl.h b/sysdeps/unix/sysv/linux/loongarch/bits/fcntl.h
>> new file mode 100644
>> index 0000000000..bf1e254234
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/loongarch/bits/fcntl.h
>> @@ -0,0 +1,61 @@
>> +/* O_*, F_*, FD_* bit values for the generic Linux/LoongArch ABI.
>> +   Copyright (C) 2022 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
>> +<https://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').  */
>> +#ifndef __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>
> Ok.
>
>> diff --git a/sysdeps/unix/sysv/linux/loongarch/bits/procfs.h b/sysdeps/unix/sysv/linux/loongarch/bits/procfs.h
>> new file mode 100644
>> index 0000000000..2db777b38c
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/loongarch/bits/procfs.h
>> @@ -0,0 +1,52 @@
>> +/* Types for registers for sys/procfs.h.
>> +   Copyright (C) 2022 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
>> +<https://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 __uint64_t elf_greg_t;
>> +
>> +/* And the whole bunch of them.  We could have used `struct
>> +   pt_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_struct) / sizeof (elf_greg_t))
>> +typedef elf_greg_t elf_gregset_t[ELF_NGREG];
>> +
>> +#define ELF_NFPREG 34 /* 32 FPRs + 8-byte byte-vec for fcc + 4-byte FCR */
>> +typedef union
>> +{
>> +  double d;
>> +  float f;
>> +} elf_fpreg_t;
>> +typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
>> +
>> +typedef union
>> +{
>> +  double d[2];
>> +  float f[4];
>> +} __attribute__ ((__aligned__ (16))) elf_lsxregset_t[32];
>> +
>> +typedef union
>> +{
>> +  double d[4];
>> +  float f[8];
>> +} __attribute__ ((__aligned__ (32))) elf_lasxregset_t[32];
> Ok.
>
>> diff --git a/sysdeps/unix/sysv/linux/loongarch/bits/pthread_stack_min.h b/sysdeps/unix/sysv/linux/loongarch/bits/pthread_stack_min.h
>> new file mode 100644
>> index 0000000000..072c2ade42
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/loongarch/bits/pthread_stack_min.h
>> @@ -0,0 +1,20 @@
>> +/* Definition of PTHREAD_STACK_MIN.  LoongArch Linux version.
>> +   Copyright (C) 2022 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
>> +<https://www.gnu.org/licenses/>.  */
>> +
>> +/* Minimum size for a thread.  At least two pages with 64k pages.  */
>> +#define PTHREAD_STACK_MIN	131072
> Ok.
>
>> diff --git a/sysdeps/unix/sysv/linux/loongarch/bits/sigstack.h b/sysdeps/unix/sysv/linux/loongarch/bits/sigstack.h
>> new file mode 100644
>> index 0000000000..238c1a98e6
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/loongarch/bits/sigstack.h
>> @@ -0,0 +1,32 @@
>> +/* sigstack, sigaltstack definitions.
>> +   Copyright (C) 2022 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
>> +<https://www.gnu.org/licenses/>.  */
>> +
>> +#ifndef _BITS_SIGSTACK_H
>> +#define _BITS_SIGSTACK_H 1
>> +
>> +#if !defined _SIGNAL_H && !defined _SYS_UCONTEXT_H
>> +# error "Never include this file directly.  Use <signal.h> instead"
>> +#endif
>> +
>> +/* Minimum stack size for a signal handler.  */
>> +#define MINSIGSTKSZ	4096
>> +
>> +/* System default stack size.  */
>> +#define SIGSTKSZ	16384
>> +
>> +#endif /* bits/sigstack.h */
> Ok.
>
>> diff --git a/sysdeps/unix/sysv/linux/loongarch/getcontext.S b/sysdeps/unix/sysv/linux/loongarch/getcontext.S
>> new file mode 100644
>> index 0000000000..43b95e9715
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/loongarch/getcontext.S
>> @@ -0,0 +1,59 @@
>> +/* Save current context.
>> +   Copyright (C) 2022 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
>> +<https://www.gnu.org/licenses/>.  */
>> +
>> +#include "ucontext-macros.h"
>> +
>> +/* int getcontext (ucontext_t *ucp) */
>> +
>> +	.text
>> +LEAF (__getcontext)
>> +	SAVE_INT_REG (ra,   1, a0)
>> +	SAVE_INT_REG (sp,   3, a0)
>> +	SAVE_INT_REG (zero, 4, a0) /* return 0 by overwriting a0.  */
>> +	SAVE_INT_REG (x,   21, a0)
>> +	SAVE_INT_REG (fp,  22, a0)
>> +	SAVE_INT_REG (s0,  23, a0)
>> +	SAVE_INT_REG (s1,  24, a0)
>> +	SAVE_INT_REG (s2,  25, a0)
>> +	SAVE_INT_REG (s3,  26, a0)
>> +	SAVE_INT_REG (s4,  27, a0)
>> +	SAVE_INT_REG (s5,  28, a0)
>> +	SAVE_INT_REG (s6,  29, a0)
>> +	SAVE_INT_REG (s7,  30, a0)
>> +	SAVE_INT_REG (s8,  31, a0)
>> +	st.d		ra, a0, MCONTEXT_PC
>> +
>> +/* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */
>> +	li.d		a3, _NSIG8
>> +	li.d		a2, UCONTEXT_SIGMASK
>> +	add.d		a2, a2, a0
>> +	ori		a1, zero,0
>> +	li.d		a0, SIG_BLOCK
>> +
>> +	li.d		a7, SYS_ify (rt_sigprocmask)
>> +	syscall		0
>> +	blt		a0, zero, 99f
>> +
>> +	jirl		$r0, $r1, 0
>> +
>> +99:
>> +	b		__syscall_error
>> +
>> +PSEUDO_END (__getcontext)
>> +
>> +weak_alias (__getcontext, getcontext)
> Ok.
>
>> diff --git a/sysdeps/unix/sysv/linux/loongarch/localplt.data b/sysdeps/unix/sysv/linux/loongarch/localplt.data
>> new file mode 100644
>> index 0000000000..817ab2659a
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/loongarch/localplt.data
>> @@ -0,0 +1,12 @@
>> +# 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: realloc
>> +# 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
> Ok.
>
>> diff --git a/sysdeps/unix/sysv/linux/loongarch/makecontext.c b/sysdeps/unix/sysv/linux/loongarch/makecontext.c
>> new file mode 100644
>> index 0000000000..d29c8056cb
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/loongarch/makecontext.c
>> @@ -0,0 +1,79 @@
>> +/* Create new context.
>> +   Copyright (C) 2022 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
>> +<https://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;
> The __gregs is unsigned, why are you using signed variable for the stack?
>
>> +
>> +  _Static_assert(LARCH_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[LARCH_REG_RA] = 0;
>> +  ucp->uc_mcontext.__gregs[LARCH_REG_S0] = 0;
>> +  ucp->uc_mcontext.__gregs[LARCH_REG_S1] = (long int) func;
>> +  ucp->uc_mcontext.__gregs[LARCH_REG_S2] = (long int) ucp->uc_link;
>> +  ucp->uc_mcontext.__gregs[LARCH_REG_SP] = sp;
>> +  ucp->uc_mcontext.__pc = (long int) &__start_context;
> Both __gregs and __pc are a unsigned long lont, I think it would be better
> to use uintptr_t here.
>
>> +
>> +  /* Put args in a0-a7, then put any remaining args on the stack.  */
>> +  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 0] = a0;
>> +  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 1] = a1;
>> +  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 2] = a2;
>> +  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 3] = a3;
>> +  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 4] = a4;
>> +
>> +  if (__glibc_unlikely (argc > 5))
>> +    {
>> +      va_list vl;
>> +      va_start (vl, a4);
>> +
>> +      long reg_args = argc < LARCH_REG_NARGS ? argc : LARCH_REG_NARGS;
> Use 'long int' here.
>
>> +      for (i = 5; i < reg_args; i++)
> Move the long int i to define within the loop definition.
>
>> +	ucp->uc_mcontext.__gregs[LARCH_REG_A0 + i] = va_arg (vl, long);
>> +
>> +      long int stack_args = argc - reg_args;
>> +      if (stack_args > 0)
>> +	{
>> +	  sp = (sp - stack_args * sizeof (long int)) & ALMASK;
>> +	  ucp->uc_mcontext.__gregs[LARCH_REG_SP] = sp;
>> +	  for (i = 0; i < stack_args; i++)
>> +	    ((long int *) sp)[i] = va_arg (vl, long int);
>> +	}
>> +
>> +      va_end (vl);
>> +    }
>> +}
>> +
>> +weak_alias (__makecontext, makecontext)
>> diff --git a/sysdeps/unix/sysv/linux/loongarch/setcontext.S b/sysdeps/unix/sysv/linux/loongarch/setcontext.S
>> new file mode 100644
>> index 0000000000..7295900149
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/loongarch/setcontext.S
>> @@ -0,0 +1,100 @@
>> +/* Set current context.
>> +   Copyright (C) 2022 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
>> +<https://www.gnu.org/licenses/>.  */
>> +#include "sys/regdef.h"
>> +#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)
>> +
>> +	addi.d		sp, sp, -16
>> +	st.d		a0, sp, 0	/* Save ucp to stack */
>> +
>> +/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, NULL, _NSIG8) */
>> +	li.d		a3, _NSIG8
>> +	li.d		a2, 0
>> +	li.d		a1, UCONTEXT_SIGMASK
>> +	add.d		a1, a1, a0
>> +	li.d		a0, SIG_SETMASK
>> +
>> +	li.d		a7, SYS_ify (rt_sigprocmask)
>> +	syscall		0
>> +
>> +	blt		a0, $r0, 99f
>> +
>> +	ld.d		t0, sp, 0	/* Load ucp to t0 */
>> +	cfi_def_cfa (12, 0)
>> +
>> +/* Note the contents of argument registers will be random
>> +   unless makecontext() has been called.  */
>> +	RESTORE_INT_REG(ra,   1, t0)
>> +	RESTORE_INT_REG(sp,   3, t0)
>> +	RESTORE_INT_REG(a0,   4, t0)
>> +	RESTORE_INT_REG(a1,   5, t0)
>> +	RESTORE_INT_REG(a2,   6, t0)
>> +	RESTORE_INT_REG(a3,   7, t0)
>> +	RESTORE_INT_REG(a4,   8, t0)
>> +	RESTORE_INT_REG(a5,   9, t0)
>> +	RESTORE_INT_REG(a6,  10, t0)
>> +	RESTORE_INT_REG(a7,  11, t0)
>> +	RESTORE_INT_REG(x,   21, t0)
>> +	RESTORE_INT_REG(fp,  22, t0)
>> +	RESTORE_INT_REG(s0,  23, t0)
>> +	RESTORE_INT_REG(s1,  24, t0)
>> +	RESTORE_INT_REG(s2,  25, t0)
>> +	RESTORE_INT_REG(s3,  26, t0)
>> +	RESTORE_INT_REG(s4,  27, t0)
>> +	RESTORE_INT_REG(s5,  28, t0)
>> +	RESTORE_INT_REG(s6,  29, t0)
>> +	RESTORE_INT_REG(s7,  30, t0)
>> +	RESTORE_INT_REG(s8,  31, t0)
>> +
>> +	ld.d		t1, t0, MCONTEXT_PC
>> +	jirl		$r0,t1,0
>> +
>> +99:
>> +	addi.d		sp, sp, 16
>> +	b		__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 (1, 23)
>> +
>> +	/* Call the function passed to makecontext.  */
>> +	jirl		$r1,s1,0
>> +
>> +	/* Invoke subsequent context if present, else exit(0).  */
>> +	ori		a0, s2, 0
>> +	beqz		s2, 1f
>> +	bl		__setcontext
>> +1:
>> +	b		HIDDEN_JUMPTARGET(exit)
>> +
>> +PSEUDO_END (__start_context)
>> diff --git a/sysdeps/unix/sysv/linux/loongarch/sigcontextinfo.h b/sysdeps/unix/sysv/linux/loongarch/sigcontextinfo.h
>> new file mode 100644
>> index 0000000000..5e202bc0b4
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/loongarch/sigcontextinfo.h
>> @@ -0,0 +1,32 @@
>> +/* LoongArch definitions for signal handling calling conventions.
>> +   Copyright (C) 2022 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
>> +<https://www.gnu.org/licenses/>.  */
>> +
>> +#ifndef _SIGCONTEXTINFO_H
>> +#define _SIGCONTEXTINFO_H
>> +
>> +#include <stdint.h>
>> +#include <sys/ucontext.h>
>> +
>> +static inline uintptr_t
>> +sigcontext_get_pc (const ucontext_t *ctx)
>> +{
>> +  return ctx->uc_mcontext.__pc;
>> +}
>> +
>> +#endif
>> diff --git a/sysdeps/unix/sysv/linux/loongarch/swapcontext.S b/sysdeps/unix/sysv/linux/loongarch/swapcontext.S
>> new file mode 100644
>> index 0000000000..bb22cd2f00
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/loongarch/swapcontext.S
>> @@ -0,0 +1,95 @@
>> +/* Save and set current context.
>> +   Copyright (C) 2022 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
>> +<https://www.gnu.org/licenses/>.  */
>> +
>> +#include "ucontext-macros.h"
>> +
>> +/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */
>> +
>> +LEAF (__swapcontext)
>> +	ori		a2, sp, 0		/* Save sp to a2 */
>> +	addi.d		sp, sp, -16
>> +	st.d		a1, sp, 0
>> +	ori		t0, a1, 0
>> +
>> +	SAVE_INT_REG (ra,   1, a0)
>> +	SAVE_INT_REG (a2,   3, a0)		/* Store sp */
>> +	SAVE_INT_REG (zero, 4, a0)		/* return 0 by overwriting a0 */
>> +	SAVE_INT_REG (x,   21, a0)
>> +	SAVE_INT_REG (fp,  22, a0)
>> +	SAVE_INT_REG (s0,  23, a0)
>> +	SAVE_INT_REG (s1,  24, a0)
>> +	SAVE_INT_REG (s2,  25, a0)
>> +	SAVE_INT_REG (s3,  26, a0)
>> +	SAVE_INT_REG (s4,  27, a0)
>> +	SAVE_INT_REG (s5,  28, a0)
>> +	SAVE_INT_REG (s6,  29, a0)
>> +	SAVE_INT_REG (s7,  30, a0)
>> +	SAVE_INT_REG (s8,  31, a0)
>> +
>> +	st.d		ra, a0, MCONTEXT_PC
>> +
>> +/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask, _NSIG8) */
>> +	li.d		a3, _NSIG8
>> +	li.d		a2, UCONTEXT_SIGMASK
>> +	add.d		a2, a2, a0
>> +	li.d		a1, UCONTEXT_SIGMASK
>> +	add.d		a1, a1, t0
>> +	li.d		a0, SIG_SETMASK
>> +
>> +	li.d		a7, SYS_ify (rt_sigprocmask)
>> +	syscall		0
>> +
>> +	blt		a0, zero, 99f
>> +
>> +	ld.d		t0, sp, 0		/* Load a1 to t0 */
>> +
>> +/* Note the contents of argument registers will be random
>> +   unless makecontext() has been called.  */
>> +	RESTORE_INT_REG (ra,   1, t0)
>> +	RESTORE_INT_REG (sp,   3, t0)
>> +	RESTORE_INT_REG (a0,   4, t0)
>> +	RESTORE_INT_REG (a1,   5, t0)
>> +	RESTORE_INT_REG (a2,   6, t0)
>> +	RESTORE_INT_REG (a3,   7, t0)
>> +	RESTORE_INT_REG (a4,   8, t0)
>> +	RESTORE_INT_REG (a5,   9, t0)
>> +	RESTORE_INT_REG (a6,  10, t0)
>> +	RESTORE_INT_REG (a7,  11, t0)
>> +	RESTORE_INT_REG (x,   21, t0)
>> +	RESTORE_INT_REG (fp,  22, t0)
>> +	RESTORE_INT_REG (s0,  23, t0)
>> +	RESTORE_INT_REG (s1,  24, t0)
>> +	RESTORE_INT_REG (s2,  25, t0)
>> +	RESTORE_INT_REG (s3,  26, t0)
>> +	RESTORE_INT_REG (s4,  27, t0)
>> +	RESTORE_INT_REG (s5,  28, t0)
>> +	RESTORE_INT_REG (s6,  29, t0)
>> +	RESTORE_INT_REG (s7,  30, t0)
>> +	RESTORE_INT_REG (s8,  31, t0)
>> +
>> +	ld.d		t1, t0, MCONTEXT_PC
>> +	jirl		$r0, t1, 0
>> +
>> +
>> +99:
>> +	addi.d		sp, sp, 16
>> +	b		__syscall_error
>> +
>> +PSEUDO_END (__swapcontext)
>> +
>> +weak_alias (__swapcontext, swapcontext)
>> diff --git a/sysdeps/unix/sysv/linux/loongarch/sys/ucontext.h b/sysdeps/unix/sysv/linux/loongarch/sys/ucontext.h
>> new file mode 100644
>> index 0000000000..e334a45a44
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/loongarch/sys/ucontext.h
>> @@ -0,0 +1,61 @@
>> +/* struct ucontext definition.
>> +   Copyright (C) 2022 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
>> +<https://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>
>> +
>> +#ifdef __USE_MISC
>> +#define LARCH_NGREG 32
>> +
>> +#define LARCH_REG_RA 1
>> +#define LARCH_REG_SP 3
>> +#define LARCH_REG_S0 23
>> +#define LARCH_REG_S1 24
>> +#define LARCH_REG_A0 4
>> +#define LARCH_REG_S2 25
>> +#define LARCH_REG_NARGS 8
>> +
>> +#endif
>> +
>> +typedef struct mcontext_t
>> +{
>> +  unsigned long long __pc;
>> +  unsigned long long __gregs[32];
>> +  unsigned int __flags;
>> +  unsigned long long __extcontext[0] __attribute__((__aligned__(16)));
>> +} 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;
>> +  mcontext_t uc_mcontext;
>> +} ucontext_t;
>> +
>> +#endif /* sys/ucontext.h */
>> diff --git a/sysdeps/unix/sysv/linux/loongarch/sys/user.h b/sysdeps/unix/sysv/linux/loongarch/sys/user.h
>> new file mode 100644
>> index 0000000000..55181de816
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/loongarch/sys/user.h
>> @@ -0,0 +1,42 @@
>> +/* struct user_regs_struct definition for LoongArch.
>> +   Copyright (C) 2022 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
>> +<https://www.gnu.org/licenses/>.  */
>> +
>> +#ifndef _SYS_USER_H
>> +#define _SYS_USER_H 1
>> +
>> +#include <stdint.h>
>> +
>> +struct user_regs_struct
>> +{
>> +  /* Saved main processor registers. */
>> +  uint64_t regs[32];
>> +
>> +  /* Saved special registers. */
>> +  uint64_t orig_a0;
>> +  uint64_t csr_era;
>> +  uint64_t csr_badv;
>> +  uint64_t reserved[10];
>> +};
>> +
>> +struct user_fp_struct {
>> +  uint64_t    fpr[32];
>> +  uint64_t    fcc;
>> +  uint32_t    fcsr;
>> +};
>> +
>> +#endif /* _SYS_USER_H */
>> diff --git a/sysdeps/unix/sysv/linux/loongarch/ucontext-macros.h b/sysdeps/unix/sysv/linux/loongarch/ucontext-macros.h
>> new file mode 100644
>> index 0000000000..859eba464b
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/loongarch/ucontext-macros.h
>> @@ -0,0 +1,32 @@
>> +/* Macros for ucontext routines.
>> +   Copyright (C) 2022 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
>> +<https://www.gnu.org/licenses/>.  */
>> +
>> +#ifndef _LINUX_LOONGARCH_UCONTEXT_MACROS_H
>> +#define _LINUX_LOONGARCH_UCONTEXT_MACROS_H
>> +
>> +#include <sysdep.h>
>> +#include <sys/asm.h>
>> +#include "ucontext_i.h"
>> +
>> +#define SAVE_INT_REG(name, num, base) \
>> +  REG_S name, base, ((num) *SZREG + MCONTEXT_GREGS)
>> +
>> +#define RESTORE_INT_REG(name, num, base) \
>> +  REG_L name, base, ((num) *SZREG + MCONTEXT_GREGS)
>> +
>> +#endif /* _LINUX_LOONGARCH_UCONTEXT_MACROS_H */
>> diff --git a/sysdeps/unix/sysv/linux/loongarch/ucontext_i.sym b/sysdeps/unix/sysv/linux/loongarch/ucontext_i.sym
>> new file mode 100644
>> index 0000000000..f27afad56f
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/loongarch/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_PC			mcontext (__pc)
>> +MCONTEXT_GREGS			mcontext (__gregs)
>> +
>> +UCONTEXT_SIZE			sizeof (ucontext_t)
diff mbox series

Patch

diff --git a/sysdeps/loongarch/dl-irel.h b/sysdeps/loongarch/dl-irel.h
new file mode 100644
index 0000000000..4440453f06
--- /dev/null
+++ b/sysdeps/loongarch/dl-irel.h
@@ -0,0 +1,54 @@ 
+/* Machine-dependent ELF indirect relocation inline functions.
+   Copyright (C) 2022 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
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _DL_IREL_H
+#define _DL_IREL_H
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/ifunc.h>
+
+#define ELF_MACHINE_IRELA 1
+
+static inline ElfW (Addr) __attribute ((always_inline))
+elf_ifunc_invoke (ElfW (Addr) addr)
+{
+  __ifunc_arg_t arg =
+  {
+    ._size = sizeof (__ifunc_arg_t),
+    ._hwcap = GLRO(dl_hwcap),
+  };
+  return ((ElfW(Addr) (*) (const __ifunc_arg_t *)) (addr)) (&arg);
+}
+
+static inline void __attribute ((always_inline))
+elf_irela (const ElfW (Rela) *reloc)
+{
+  ElfW (Addr) *const reloc_addr = (void *) reloc->r_offset;
+  const unsigned long int r_type = ELFW (R_TYPE) (reloc->r_info);
+
+  if (__glibc_likely (r_type == R_LARCH_IRELATIVE))
+    {
+      ElfW (Addr) value = elf_ifunc_invoke (reloc->r_addend);
+      *reloc_addr = value;
+    }
+  else
+    __libc_fatal ("Unexpected reloc type in static binary.\n");
+}
+
+#endif /* dl-irel.h */
diff --git a/sysdeps/loongarch/nptl/pthreaddef.h b/sysdeps/loongarch/nptl/pthreaddef.h
new file mode 100644
index 0000000000..955566cddc
--- /dev/null
+++ b/sysdeps/loongarch/nptl/pthreaddef.h
@@ -0,0 +1,32 @@ 
+/* pthread machine parameter definitions.
+   Copyright (C) 2022 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
+   <https://www.gnu.org/licenses/>.  */
+
+/* Default stack size.  */
+#define ARCH_STACK_DEFAULT_SIZE (2 * 1024 * 1024)
+
+/* Minimum guard size.  */
+#define ARCH_MIN_GUARD_SIZE 0
+
+/* 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
+
+/* Location of current stack frame.  */
+#define CURRENT_STACK_FRAME __builtin_frame_address (0)
diff --git a/sysdeps/loongarch/sys/ifunc.h b/sysdeps/loongarch/sys/ifunc.h
new file mode 100644
index 0000000000..461df20c96
--- /dev/null
+++ b/sysdeps/loongarch/sys/ifunc.h
@@ -0,0 +1,30 @@ 
+/* Definitions used by LoongArch indirect function resolvers.
+   Copyright (C) 2022 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
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_IFUNC_H
+#define _SYS_IFUNC_H
+
+struct __ifunc_arg_t
+{
+  unsigned long _size; /* Size of the struct, so it can grow.  */
+  unsigned long _hwcap;
+};
+
+typedef struct __ifunc_arg_t __ifunc_arg_t;
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/loongarch/bits/fcntl.h b/sysdeps/unix/sysv/linux/loongarch/bits/fcntl.h
new file mode 100644
index 0000000000..bf1e254234
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/loongarch/bits/fcntl.h
@@ -0,0 +1,61 @@ 
+/* O_*, F_*, FD_* bit values for the generic Linux/LoongArch ABI.
+   Copyright (C) 2022 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
+   <https://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').  */
+#ifndef __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/loongarch/bits/procfs.h b/sysdeps/unix/sysv/linux/loongarch/bits/procfs.h
new file mode 100644
index 0000000000..2db777b38c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/loongarch/bits/procfs.h
@@ -0,0 +1,52 @@ 
+/* Types for registers for sys/procfs.h.
+   Copyright (C) 2022 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
+   <https://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 __uint64_t elf_greg_t;
+
+/* And the whole bunch of them.  We could have used `struct
+   pt_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_struct) / sizeof (elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+#define ELF_NFPREG 34 /* 32 FPRs + 8-byte byte-vec for fcc + 4-byte FCR */
+typedef union
+{
+  double d;
+  float f;
+} elf_fpreg_t;
+typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+
+typedef union
+{
+  double d[2];
+  float f[4];
+} __attribute__ ((__aligned__ (16))) elf_lsxregset_t[32];
+
+typedef union
+{
+  double d[4];
+  float f[8];
+} __attribute__ ((__aligned__ (32))) elf_lasxregset_t[32];
diff --git a/sysdeps/unix/sysv/linux/loongarch/bits/pthread_stack_min.h b/sysdeps/unix/sysv/linux/loongarch/bits/pthread_stack_min.h
new file mode 100644
index 0000000000..072c2ade42
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/loongarch/bits/pthread_stack_min.h
@@ -0,0 +1,20 @@ 
+/* Definition of PTHREAD_STACK_MIN.  LoongArch Linux version.
+   Copyright (C) 2022 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
+   <https://www.gnu.org/licenses/>.  */
+
+/* Minimum size for a thread.  At least two pages with 64k pages.  */
+#define PTHREAD_STACK_MIN	131072
diff --git a/sysdeps/unix/sysv/linux/loongarch/bits/sigstack.h b/sysdeps/unix/sysv/linux/loongarch/bits/sigstack.h
new file mode 100644
index 0000000000..238c1a98e6
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/loongarch/bits/sigstack.h
@@ -0,0 +1,32 @@ 
+/* sigstack, sigaltstack definitions.
+   Copyright (C) 2022 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
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_SIGSTACK_H
+#define _BITS_SIGSTACK_H 1
+
+#if !defined _SIGNAL_H && !defined _SYS_UCONTEXT_H
+# error "Never include this file directly.  Use <signal.h> instead"
+#endif
+
+/* Minimum stack size for a signal handler.  */
+#define MINSIGSTKSZ	4096
+
+/* System default stack size.  */
+#define SIGSTKSZ	16384
+
+#endif /* bits/sigstack.h */
diff --git a/sysdeps/unix/sysv/linux/loongarch/getcontext.S b/sysdeps/unix/sysv/linux/loongarch/getcontext.S
new file mode 100644
index 0000000000..43b95e9715
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/loongarch/getcontext.S
@@ -0,0 +1,59 @@ 
+/* Save current context.
+   Copyright (C) 2022 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
+   <https://www.gnu.org/licenses/>.  */
+
+#include "ucontext-macros.h"
+
+/* int getcontext (ucontext_t *ucp) */
+
+	.text
+LEAF (__getcontext)
+	SAVE_INT_REG (ra,   1, a0)
+	SAVE_INT_REG (sp,   3, a0)
+	SAVE_INT_REG (zero, 4, a0) /* return 0 by overwriting a0.  */
+	SAVE_INT_REG (x,   21, a0)
+	SAVE_INT_REG (fp,  22, a0)
+	SAVE_INT_REG (s0,  23, a0)
+	SAVE_INT_REG (s1,  24, a0)
+	SAVE_INT_REG (s2,  25, a0)
+	SAVE_INT_REG (s3,  26, a0)
+	SAVE_INT_REG (s4,  27, a0)
+	SAVE_INT_REG (s5,  28, a0)
+	SAVE_INT_REG (s6,  29, a0)
+	SAVE_INT_REG (s7,  30, a0)
+	SAVE_INT_REG (s8,  31, a0)
+	st.d		ra, a0, MCONTEXT_PC
+
+/* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */
+	li.d		a3, _NSIG8
+	li.d		a2, UCONTEXT_SIGMASK
+	add.d		a2, a2, a0
+	ori		a1, zero,0
+	li.d		a0, SIG_BLOCK
+
+	li.d		a7, SYS_ify (rt_sigprocmask)
+	syscall		0
+	blt		a0, zero, 99f
+
+	jirl		$r0, $r1, 0
+
+99:
+	b		__syscall_error
+
+PSEUDO_END (__getcontext)
+
+weak_alias (__getcontext, getcontext)
diff --git a/sysdeps/unix/sysv/linux/loongarch/localplt.data b/sysdeps/unix/sysv/linux/loongarch/localplt.data
new file mode 100644
index 0000000000..817ab2659a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/loongarch/localplt.data
@@ -0,0 +1,12 @@ 
+# 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: realloc
+# 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/loongarch/makecontext.c b/sysdeps/unix/sysv/linux/loongarch/makecontext.c
new file mode 100644
index 0000000000..d29c8056cb
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/loongarch/makecontext.c
@@ -0,0 +1,79 @@ 
+/* Create new context.
+   Copyright (C) 2022 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
+   <https://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(LARCH_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[LARCH_REG_RA] = 0;
+  ucp->uc_mcontext.__gregs[LARCH_REG_S0] = 0;
+  ucp->uc_mcontext.__gregs[LARCH_REG_S1] = (long int) func;
+  ucp->uc_mcontext.__gregs[LARCH_REG_S2] = (long int) ucp->uc_link;
+  ucp->uc_mcontext.__gregs[LARCH_REG_SP] = sp;
+  ucp->uc_mcontext.__pc = (long int) &__start_context;
+
+  /* Put args in a0-a7, then put any remaining args on the stack.  */
+  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 0] = a0;
+  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 1] = a1;
+  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 2] = a2;
+  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 3] = a3;
+  ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 4] = a4;
+
+  if (__glibc_unlikely (argc > 5))
+    {
+      va_list vl;
+      va_start (vl, a4);
+
+      long reg_args = argc < LARCH_REG_NARGS ? argc : LARCH_REG_NARGS;
+      for (i = 5; i < reg_args; i++)
+	ucp->uc_mcontext.__gregs[LARCH_REG_A0 + i] = va_arg (vl, long);
+
+      long int stack_args = argc - reg_args;
+      if (stack_args > 0)
+	{
+	  sp = (sp - stack_args * sizeof (long int)) & ALMASK;
+	  ucp->uc_mcontext.__gregs[LARCH_REG_SP] = sp;
+	  for (i = 0; i < stack_args; i++)
+	    ((long int *) sp)[i] = va_arg (vl, long int);
+	}
+
+      va_end (vl);
+    }
+}
+
+weak_alias (__makecontext, makecontext)
diff --git a/sysdeps/unix/sysv/linux/loongarch/setcontext.S b/sysdeps/unix/sysv/linux/loongarch/setcontext.S
new file mode 100644
index 0000000000..7295900149
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/loongarch/setcontext.S
@@ -0,0 +1,100 @@ 
+/* Set current context.
+   Copyright (C) 2022 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
+   <https://www.gnu.org/licenses/>.  */
+#include "sys/regdef.h"
+#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)
+
+	addi.d		sp, sp, -16
+	st.d		a0, sp, 0	/* Save ucp to stack */
+
+/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, NULL, _NSIG8) */
+	li.d		a3, _NSIG8
+	li.d		a2, 0
+	li.d		a1, UCONTEXT_SIGMASK
+	add.d		a1, a1, a0
+	li.d		a0, SIG_SETMASK
+
+	li.d		a7, SYS_ify (rt_sigprocmask)
+	syscall		0
+
+	blt		a0, $r0, 99f
+
+	ld.d		t0, sp, 0	/* Load ucp to t0 */
+	cfi_def_cfa (12, 0)
+
+/* Note the contents of argument registers will be random
+   unless makecontext() has been called.  */
+	RESTORE_INT_REG(ra,   1, t0)
+	RESTORE_INT_REG(sp,   3, t0)
+	RESTORE_INT_REG(a0,   4, t0)
+	RESTORE_INT_REG(a1,   5, t0)
+	RESTORE_INT_REG(a2,   6, t0)
+	RESTORE_INT_REG(a3,   7, t0)
+	RESTORE_INT_REG(a4,   8, t0)
+	RESTORE_INT_REG(a5,   9, t0)
+	RESTORE_INT_REG(a6,  10, t0)
+	RESTORE_INT_REG(a7,  11, t0)
+	RESTORE_INT_REG(x,   21, t0)
+	RESTORE_INT_REG(fp,  22, t0)
+	RESTORE_INT_REG(s0,  23, t0)
+	RESTORE_INT_REG(s1,  24, t0)
+	RESTORE_INT_REG(s2,  25, t0)
+	RESTORE_INT_REG(s3,  26, t0)
+	RESTORE_INT_REG(s4,  27, t0)
+	RESTORE_INT_REG(s5,  28, t0)
+	RESTORE_INT_REG(s6,  29, t0)
+	RESTORE_INT_REG(s7,  30, t0)
+	RESTORE_INT_REG(s8,  31, t0)
+
+	ld.d		t1, t0, MCONTEXT_PC
+	jirl		$r0,t1,0
+
+99:
+	addi.d		sp, sp, 16
+	b		__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 (1, 23)
+
+	/* Call the function passed to makecontext.  */
+	jirl		$r1,s1,0
+
+	/* Invoke subsequent context if present, else exit(0).  */
+	ori		a0, s2, 0
+	beqz		s2, 1f
+	bl		__setcontext
+1:
+	b		HIDDEN_JUMPTARGET(exit)
+
+PSEUDO_END (__start_context)
diff --git a/sysdeps/unix/sysv/linux/loongarch/sigcontextinfo.h b/sysdeps/unix/sysv/linux/loongarch/sigcontextinfo.h
new file mode 100644
index 0000000000..5e202bc0b4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/loongarch/sigcontextinfo.h
@@ -0,0 +1,32 @@ 
+/* LoongArch definitions for signal handling calling conventions.
+   Copyright (C) 2022 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
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _SIGCONTEXTINFO_H
+#define _SIGCONTEXTINFO_H
+
+#include <stdint.h>
+#include <sys/ucontext.h>
+
+static inline uintptr_t
+sigcontext_get_pc (const ucontext_t *ctx)
+{
+  return ctx->uc_mcontext.__pc;
+}
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/loongarch/swapcontext.S b/sysdeps/unix/sysv/linux/loongarch/swapcontext.S
new file mode 100644
index 0000000000..bb22cd2f00
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/loongarch/swapcontext.S
@@ -0,0 +1,95 @@ 
+/* Save and set current context.
+   Copyright (C) 2022 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
+   <https://www.gnu.org/licenses/>.  */
+
+#include "ucontext-macros.h"
+
+/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */
+
+LEAF (__swapcontext)
+	ori		a2, sp, 0		/* Save sp to a2 */
+	addi.d		sp, sp, -16
+	st.d		a1, sp, 0
+	ori		t0, a1, 0
+
+	SAVE_INT_REG (ra,   1, a0)
+	SAVE_INT_REG (a2,   3, a0)		/* Store sp */
+	SAVE_INT_REG (zero, 4, a0)		/* return 0 by overwriting a0 */
+	SAVE_INT_REG (x,   21, a0)
+	SAVE_INT_REG (fp,  22, a0)
+	SAVE_INT_REG (s0,  23, a0)
+	SAVE_INT_REG (s1,  24, a0)
+	SAVE_INT_REG (s2,  25, a0)
+	SAVE_INT_REG (s3,  26, a0)
+	SAVE_INT_REG (s4,  27, a0)
+	SAVE_INT_REG (s5,  28, a0)
+	SAVE_INT_REG (s6,  29, a0)
+	SAVE_INT_REG (s7,  30, a0)
+	SAVE_INT_REG (s8,  31, a0)
+
+	st.d		ra, a0, MCONTEXT_PC
+
+/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask, _NSIG8) */
+	li.d		a3, _NSIG8
+	li.d		a2, UCONTEXT_SIGMASK
+	add.d		a2, a2, a0
+	li.d		a1, UCONTEXT_SIGMASK
+	add.d		a1, a1, t0
+	li.d		a0, SIG_SETMASK
+
+	li.d		a7, SYS_ify (rt_sigprocmask)
+	syscall		0
+
+	blt		a0, zero, 99f
+
+	ld.d		t0, sp, 0		/* Load a1 to t0 */
+
+/* Note the contents of argument registers will be random
+   unless makecontext() has been called.  */
+	RESTORE_INT_REG (ra,   1, t0)
+	RESTORE_INT_REG (sp,   3, t0)
+	RESTORE_INT_REG (a0,   4, t0)
+	RESTORE_INT_REG (a1,   5, t0)
+	RESTORE_INT_REG (a2,   6, t0)
+	RESTORE_INT_REG (a3,   7, t0)
+	RESTORE_INT_REG (a4,   8, t0)
+	RESTORE_INT_REG (a5,   9, t0)
+	RESTORE_INT_REG (a6,  10, t0)
+	RESTORE_INT_REG (a7,  11, t0)
+	RESTORE_INT_REG (x,   21, t0)
+	RESTORE_INT_REG (fp,  22, t0)
+	RESTORE_INT_REG (s0,  23, t0)
+	RESTORE_INT_REG (s1,  24, t0)
+	RESTORE_INT_REG (s2,  25, t0)
+	RESTORE_INT_REG (s3,  26, t0)
+	RESTORE_INT_REG (s4,  27, t0)
+	RESTORE_INT_REG (s5,  28, t0)
+	RESTORE_INT_REG (s6,  29, t0)
+	RESTORE_INT_REG (s7,  30, t0)
+	RESTORE_INT_REG (s8,  31, t0)
+
+	ld.d		t1, t0, MCONTEXT_PC
+	jirl		$r0, t1, 0
+
+
+99:
+	addi.d		sp, sp, 16
+	b		__syscall_error
+
+PSEUDO_END (__swapcontext)
+
+weak_alias (__swapcontext, swapcontext)
diff --git a/sysdeps/unix/sysv/linux/loongarch/sys/ucontext.h b/sysdeps/unix/sysv/linux/loongarch/sys/ucontext.h
new file mode 100644
index 0000000000..e334a45a44
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/loongarch/sys/ucontext.h
@@ -0,0 +1,61 @@ 
+/* struct ucontext definition.
+   Copyright (C) 2022 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
+   <https://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>
+
+#ifdef __USE_MISC
+#define LARCH_NGREG 32
+
+#define LARCH_REG_RA 1
+#define LARCH_REG_SP 3
+#define LARCH_REG_S0 23
+#define LARCH_REG_S1 24
+#define LARCH_REG_A0 4
+#define LARCH_REG_S2 25
+#define LARCH_REG_NARGS 8
+
+#endif
+
+typedef struct mcontext_t
+{
+  unsigned long long __pc;
+  unsigned long long __gregs[32];
+  unsigned int __flags;
+  unsigned long long __extcontext[0] __attribute__((__aligned__(16)));
+} 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;
+  mcontext_t uc_mcontext;
+} ucontext_t;
+
+#endif /* sys/ucontext.h */
diff --git a/sysdeps/unix/sysv/linux/loongarch/sys/user.h b/sysdeps/unix/sysv/linux/loongarch/sys/user.h
new file mode 100644
index 0000000000..55181de816
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/loongarch/sys/user.h
@@ -0,0 +1,42 @@ 
+/* struct user_regs_struct definition for LoongArch.
+   Copyright (C) 2022 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
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_USER_H
+#define _SYS_USER_H 1
+
+#include <stdint.h>
+
+struct user_regs_struct
+{
+  /* Saved main processor registers. */
+  uint64_t regs[32];
+
+  /* Saved special registers. */
+  uint64_t orig_a0;
+  uint64_t csr_era;
+  uint64_t csr_badv;
+  uint64_t reserved[10];
+};
+
+struct user_fp_struct {
+  uint64_t    fpr[32];
+  uint64_t    fcc;
+  uint32_t    fcsr;
+};
+
+#endif /* _SYS_USER_H */
diff --git a/sysdeps/unix/sysv/linux/loongarch/ucontext-macros.h b/sysdeps/unix/sysv/linux/loongarch/ucontext-macros.h
new file mode 100644
index 0000000000..859eba464b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/loongarch/ucontext-macros.h
@@ -0,0 +1,32 @@ 
+/* Macros for ucontext routines.
+   Copyright (C) 2022 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
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _LINUX_LOONGARCH_UCONTEXT_MACROS_H
+#define _LINUX_LOONGARCH_UCONTEXT_MACROS_H
+
+#include <sysdep.h>
+#include <sys/asm.h>
+#include "ucontext_i.h"
+
+#define SAVE_INT_REG(name, num, base) \
+  REG_S name, base, ((num) *SZREG + MCONTEXT_GREGS)
+
+#define RESTORE_INT_REG(name, num, base) \
+  REG_L name, base, ((num) *SZREG + MCONTEXT_GREGS)
+
+#endif /* _LINUX_LOONGARCH_UCONTEXT_MACROS_H */
diff --git a/sysdeps/unix/sysv/linux/loongarch/ucontext_i.sym b/sysdeps/unix/sysv/linux/loongarch/ucontext_i.sym
new file mode 100644
index 0000000000..f27afad56f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/loongarch/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_PC			mcontext (__pc)
+MCONTEXT_GREGS			mcontext (__gregs)
+
+UCONTEXT_SIZE			sizeof (ucontext_t)