Message ID | 20220719012056.1461897-9-caiyinyu@loongson.cn |
---|---|
State | New |
Headers | show |
Series | [v7,01/13] LoongArch: Add LoongArch entries to config.h.in | expand |
LGTM, thanks. Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> On 18/07/22 22:20, 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 | 81 ++++++++++++++ > .../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, 826 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) Ok. > 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 */ > diff --git a/sysdeps/unix/sysv/linux/l Ok. oongarch/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..94a45bf4ad > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/loongarch/makecontext.c > @@ -0,0 +1,81 @@ > +/* 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; > + unsigned long int *sp; > + > + _Static_assert(LARCH_REG_NARGS == 8, > + "__makecontext assumes 8 argument registers"); > + > + /* Set up the stack. */ > + 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] = (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] = (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 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 = (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); > + } > +} > + > +weak_alias (__makecontext, makecontext) Ok. > 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) Ok. > 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 Ok. > 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) Ok. > 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 */ Ok. > 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 */ I think it should be ok to use stdint.h types here, although it is not usual for other ports. AFAIK it is only mainly for GDB. > 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 */ OK. > 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 --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..94a45bf4ad --- /dev/null +++ b/sysdeps/unix/sysv/linux/loongarch/makecontext.c @@ -0,0 +1,81 @@ +/* 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; + unsigned long int *sp; + + _Static_assert(LARCH_REG_NARGS == 8, + "__makecontext assumes 8 argument registers"); + + /* Set up the stack. */ + 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] = (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] = (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 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 = (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); + } +} + +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)