aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/unix/sysv/linux
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv/linux')
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/uw-sigframe.h78
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/bits/ioctls.h36
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/termios_arch.h17
-rw-r--r--sysdeps/unix/sysv/linux/termios_internals.h2
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/uw-sigframe.h76
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__ */