mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-26 06:50:07 +00:00
LoongArch: Linux ABI
This commit is contained in:
parent
45955fe618
commit
f2037efbb3
54
sysdeps/loongarch/dl-irel.h
Normal file
54
sysdeps/loongarch/dl-irel.h
Normal file
@ -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 */
|
32
sysdeps/loongarch/nptl/pthreaddef.h
Normal file
32
sysdeps/loongarch/nptl/pthreaddef.h
Normal file
@ -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)
|
30
sysdeps/loongarch/sys/ifunc.h
Normal file
30
sysdeps/loongarch/sys/ifunc.h
Normal file
@ -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
|
61
sysdeps/unix/sysv/linux/loongarch/bits/fcntl.h
Normal file
61
sysdeps/unix/sysv/linux/loongarch/bits/fcntl.h
Normal file
@ -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>
|
52
sysdeps/unix/sysv/linux/loongarch/bits/procfs.h
Normal file
52
sysdeps/unix/sysv/linux/loongarch/bits/procfs.h
Normal file
@ -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];
|
20
sysdeps/unix/sysv/linux/loongarch/bits/pthread_stack_min.h
Normal file
20
sysdeps/unix/sysv/linux/loongarch/bits/pthread_stack_min.h
Normal file
@ -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
|
32
sysdeps/unix/sysv/linux/loongarch/bits/sigstack.h
Normal file
32
sysdeps/unix/sysv/linux/loongarch/bits/sigstack.h
Normal file
@ -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 */
|
59
sysdeps/unix/sysv/linux/loongarch/getcontext.S
Normal file
59
sysdeps/unix/sysv/linux/loongarch/getcontext.S
Normal file
@ -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)
|
12
sysdeps/unix/sysv/linux/loongarch/localplt.data
Normal file
12
sysdeps/unix/sysv/linux/loongarch/localplt.data
Normal file
@ -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
|
81
sysdeps/unix/sysv/linux/loongarch/makecontext.c
Normal file
81
sysdeps/unix/sysv/linux/loongarch/makecontext.c
Normal file
@ -0,0 +1,81 @@
|
||||
/* Create new context.
|
||||
Copyright (C) 2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library. If not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <sys/asm.h>
|
||||
#include <sys/ucontext.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
|
||||
void
|
||||
__makecontext (ucontext_t *ucp, void (*func) (void), int argc, long int a0,
|
||||
long int a1, long int a2, long int a3, long int a4, ...)
|
||||
{
|
||||
extern void __start_context (void) attribute_hidden;
|
||||
unsigned long int *sp;
|
||||
|
||||
_Static_assert(LARCH_REG_NARGS == 8,
|
||||
"__makecontext assumes 8 argument registers");
|
||||
|
||||
/* Set up the stack. */
|
||||
sp = (unsigned long int *)
|
||||
(((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size) & ALMASK);
|
||||
|
||||
/* Set up the register context.
|
||||
ra = s0 = 0, terminating the stack for backtracing purposes.
|
||||
s1 = the function we must call.
|
||||
s2 = the subsequent context to run. */
|
||||
ucp->uc_mcontext.__gregs[LARCH_REG_RA] = (uintptr_t) 0;
|
||||
ucp->uc_mcontext.__gregs[LARCH_REG_S0] = (uintptr_t) 0;
|
||||
ucp->uc_mcontext.__gregs[LARCH_REG_S1] = (uintptr_t) func;
|
||||
ucp->uc_mcontext.__gregs[LARCH_REG_S2] = (uintptr_t) ucp->uc_link;
|
||||
ucp->uc_mcontext.__gregs[LARCH_REG_SP] = (uintptr_t) sp;
|
||||
ucp->uc_mcontext.__pc = (uintptr_t) &__start_context;
|
||||
|
||||
/* Put args in a0-a7, then put any remaining args on the stack. */
|
||||
ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 0] = (uintptr_t) a0;
|
||||
ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 1] = (uintptr_t) a1;
|
||||
ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 2] = (uintptr_t) a2;
|
||||
ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 3] = (uintptr_t) a3;
|
||||
ucp->uc_mcontext.__gregs[LARCH_REG_A0 + 4] = (uintptr_t) a4;
|
||||
|
||||
if (__glibc_unlikely (argc > 5))
|
||||
{
|
||||
va_list vl;
|
||||
va_start (vl, a4);
|
||||
|
||||
long int reg_args = argc < LARCH_REG_NARGS ? argc : LARCH_REG_NARGS;
|
||||
for (long int i = 5; i < reg_args; i++)
|
||||
ucp->uc_mcontext.__gregs[LARCH_REG_A0 + i] = va_arg (vl, unsigned long int);
|
||||
|
||||
long int stack_args = argc - reg_args;
|
||||
if (stack_args > 0)
|
||||
{
|
||||
sp = (unsigned long int *)
|
||||
(((uintptr_t) sp - stack_args * sizeof (long int)) & ALMASK);
|
||||
ucp->uc_mcontext.__gregs[LARCH_REG_SP] = (uintptr_t) sp;
|
||||
for (long int i = 0; i < stack_args; i++)
|
||||
sp[i] = va_arg (vl, unsigned long int);
|
||||
}
|
||||
|
||||
va_end (vl);
|
||||
}
|
||||
}
|
||||
|
||||
weak_alias (__makecontext, makecontext)
|
100
sysdeps/unix/sysv/linux/loongarch/setcontext.S
Normal file
100
sysdeps/unix/sysv/linux/loongarch/setcontext.S
Normal file
@ -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)
|
32
sysdeps/unix/sysv/linux/loongarch/sigcontextinfo.h
Normal file
32
sysdeps/unix/sysv/linux/loongarch/sigcontextinfo.h
Normal file
@ -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
|
95
sysdeps/unix/sysv/linux/loongarch/swapcontext.S
Normal file
95
sysdeps/unix/sysv/linux/loongarch/swapcontext.S
Normal file
@ -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)
|
61
sysdeps/unix/sysv/linux/loongarch/sys/ucontext.h
Normal file
61
sysdeps/unix/sysv/linux/loongarch/sys/ucontext.h
Normal file
@ -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 */
|
42
sysdeps/unix/sysv/linux/loongarch/sys/user.h
Normal file
42
sysdeps/unix/sysv/linux/loongarch/sys/user.h
Normal file
@ -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 */
|
32
sysdeps/unix/sysv/linux/loongarch/ucontext-macros.h
Normal file
32
sysdeps/unix/sysv/linux/loongarch/ucontext-macros.h
Normal file
@ -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 */
|
31
sysdeps/unix/sysv/linux/loongarch/ucontext_i.sym
Normal file
31
sysdeps/unix/sysv/linux/loongarch/ucontext_i.sym
Normal file
@ -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)
|
Loading…
Reference in New Issue
Block a user