diff options
Diffstat (limited to 'sysdeps/unix/sysv/linux')
-rw-r--r-- | sysdeps/unix/sysv/linux/aarch64/uw-sigframe.h | 78 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/bits/ioctls.h | 36 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/termios_arch.h | 17 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/termios_internals.h | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/x86_64/uw-sigframe.h | 76 |
5 files changed, 167 insertions, 42 deletions
diff --git a/sysdeps/unix/sysv/linux/aarch64/uw-sigframe.h b/sysdeps/unix/sysv/linux/aarch64/uw-sigframe.h new file mode 100644 index 0000000..9d5d345 --- /dev/null +++ b/sysdeps/unix/sysv/linux/aarch64/uw-sigframe.h @@ -0,0 +1,78 @@ +/* Signal frame backtracing support for SFrame on AARCH64. + Copyright (C) 2025 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/>. */ + +/* This code is inspired from libgcc's MD_FALLBACK_FRAME_STATE_FOR + implementation. See libgcc/config/aarch64/linux-unwind.h */ + +#include <signal.h> +#include <sys/ucontext.h> +#include <kernel_rt_sigframe.h> + +#ifdef __AARCH64EL__ +#define MOVZ_X8_8B 0xd2801168 +#define SVC_0 0xd4000001 +#else +#define MOVZ_X8_8B 0x681180d2 +#define SVC_0 0x010000d4 +#endif + +#define MD_DECODE_SIGNAL_FRAME aarch64_decode_signal_frame + +static _Unwind_Reason_Code +aarch64_decode_signal_frame (frame *frame) +{ + unsigned int *pc = (unsigned int *) frame->pc; + mcontext_t *mt; + struct kernel_rt_sigframe *rt_; + + if ((frame->pc & 3) != 0) + return _URC_END_OF_STACK; + + /* A signal frame will have a return address pointing to + __kernel_rt_sigreturn. This code is hardwired as: + + 0xd2801168 movz x8, #0x8b + 0xd4000001 svc 0x0 + */ + if (pc[0] != MOVZ_X8_8B || pc[1] != SVC_0) + return _URC_END_OF_STACK; + + rt_ = (struct kernel_rt_sigframe *) frame->sp; + mt = &rt_->uc.uc_mcontext; + + /* Frame pointer register number. */ +#define FP_REGNUM 30 + + frame->pc = (_Unwind_Ptr) mt->pc; + frame->sp = (_Unwind_Ptr) mt->sp; + frame->fp = (_Unwind_Ptr) mt->regs[FP_REGNUM]; + return _URC_NO_REASON; +} + +#define MD_DETECT_OUTERMOST_FRAME aarch64_detect_outermost_frame + +static _Unwind_Reason_Code +aarch64_detect_outermost_frame (frame *frame) +{ + /* Initial frame has LR and FP set to zero. We track only FP. */ + if (frame->fp == 0) + return _URC_END_OF_STACK; + + return _URC_NO_REASON; +} diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/ioctls.h b/sysdeps/unix/sysv/linux/powerpc/bits/ioctls.h deleted file mode 100644 index e1921df..0000000 --- a/sysdeps/unix/sysv/linux/powerpc/bits/ioctls.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (C) 1996-2025 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_IOCTL_H -# error "Never use <bits/ioctls.h> directly; include <sys/ioctl.h> instead." -#endif - -/* Use the definitions from the kernel header files. */ -#include <asm/ioctls.h> - -/* PowerPC quirk: on PowerPC only, ioctl() emulates the TCGETS/TCSETS* - ioctls with tcgetattr/tcsetattr using the glibc struct termios. - As struct termios2 is the same as the kernel struct termios on PowerPC, - simply consider the kernel ones as the termios2 interface, even - though the kernel doesn't call it that. */ - -#define TCGETS2 _IOR ('t', 19, struct termios2) -#define TCSETS2 _IOW ('t', 20, struct termios2) -#define TCSETSW2 _IOW ('t', 21, struct termios2) -#define TCSETSF2 _IOW ('t', 22, struct termios2) - -#include <linux/sockios.h> diff --git a/sysdeps/unix/sysv/linux/powerpc/termios_arch.h b/sysdeps/unix/sysv/linux/powerpc/termios_arch.h index 20025f2..919b437 100644 --- a/sysdeps/unix/sysv/linux/powerpc/termios_arch.h +++ b/sysdeps/unix/sysv/linux/powerpc/termios_arch.h @@ -1,4 +1,4 @@ -/* Architectural parameters for Linux termios - Alpha/PowerPC version +/* Architectural parameters for Linux termios - PowerPC version Copyright (C) 1997-2025 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -17,10 +17,17 @@ License along with the GNU C Library; if not, see <https://www.gnu.org/licenses/>. */ -#ifndef TERMIOS_INTERNALS_H -# error "<termios_arch.h> should only be included from <termios_internals.h>" -#endif - #define _TERMIOS2_NCCS 19 #define _HAVE_TERMIOS2_C_CC_BEFORE_C_LINE 1 #define _HAVE_STRUCT_OLD_TERMIOS 0 + +/* PowerPC quirk: on PowerPC only, ioctl() emulates the TCGETS/TCSETS* + ioctls with tcgetattr/tcsetattr using the glibc struct termios. + As struct termios2 is the same as the kernel struct termios on PowerPC, + simply consider the kernel ones as the termios2 interface, even + though the kernel doesn't call it that. */ + +#define TCGETS2 _IOR ('t', 19, struct termios2) +#define TCSETS2 _IOW ('t', 20, struct termios2) +#define TCSETSW2 _IOW ('t', 21, struct termios2) +#define TCSETSF2 _IOW ('t', 22, struct termios2) diff --git a/sysdeps/unix/sysv/linux/termios_internals.h b/sysdeps/unix/sysv/linux/termios_internals.h index 10b6732..e8dbfe7 100644 --- a/sysdeps/unix/sysv/linux/termios_internals.h +++ b/sysdeps/unix/sysv/linux/termios_internals.h @@ -59,7 +59,7 @@ struct termios2 format and function as TCGETS2. On all other platforms, the termios2 interface exists as far back as this version of glibc supports. - For TCGETS* it is more complicated; this is handled in tcsetattr.c. + For TCSETS* it is more complicated; this is handled in tcsetattr.c. Some other architectures only have the equivalent of the termios2 interface, in which case the old ioctl names are the only ones diff --git a/sysdeps/unix/sysv/linux/x86_64/uw-sigframe.h b/sysdeps/unix/sysv/linux/x86_64/uw-sigframe.h new file mode 100644 index 0000000..585ca01 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86_64/uw-sigframe.h @@ -0,0 +1,76 @@ +/* Signal frame backtracing support for SFrame on AMD, x86-64 and x86. + Copyright (C) 2025 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/>. */ + +/* This code is inspired from libgcc's MD_FALLBACK_FRAME_STATE_FOR + implementation. See libgcc/config/i386/linux-unwind.h */ + +#include <signal.h> +#include <sys/ucontext.h> + +#ifdef __x86_64__ + +/* SFrame is only supported by x86_64 targets. */ + +#define MD_DECODE_SIGNAL_FRAME x86_64_decode_signal_frame + +#ifdef __LP64__ +#define RT_SIGRETURN_SYSCALL 0x050f0000000fc0c7ULL +#else +#define RT_SIGRETURN_SYSCALL 0x050f40000201c0c7ULL +#endif + +static _Unwind_Reason_Code +x86_64_decode_signal_frame (frame *frame) +{ + unsigned char *pc = (unsigned char *) frame->pc; + mcontext_t *st; + + unsigned char pc0 = *(unsigned char *)(pc + 0); + unsigned long long pc1; + memcpy (&pc1, pc + 1, sizeof (unsigned long long)); + + /* movq $__NR_rt_sigreturn, %rax ; syscall. */ + if ( pc0 == 0x48 + && pc1 == RT_SIGRETURN_SYSCALL) + { + ucontext_t *uc_ = (ucontext_t *)frame->sp; + st = &uc_->uc_mcontext; + } + else + return _URC_END_OF_STACK; + + frame->pc = (_Unwind_Ptr) st->gregs[REG_RIP]; + frame->sp = (_Unwind_Ptr) st->gregs[REG_RSP]; + frame->fp = (_Unwind_Ptr) st->gregs[REG_RBP]; + return _URC_NO_REASON; +} + +#define MD_DETECT_OUTERMOST_FRAME x86_64_detect_outermost_frame + +static _Unwind_Reason_Code +x86_64_detect_outermost_frame (frame *frame) +{ + /* Outermost frame has the frame pointer cleared. */ + if (frame->fp == 0) + return _URC_END_OF_STACK; + + return _URC_NO_REASON; +} + +#endif /* ifdef __x86_64__ */ |