Message ID | 20220708065255.2316410-10-caiyinyu@loongson.cn |
---|---|
State | New |
Headers | show |
Series | GLIBC LoongArch PATCHES | expand |
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)
+#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 --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)