1 /*
2 * Copyright (c) 2017-2021 Dmitry V. Levin <ldv@strace.io>
3 * Copyright (c) 2021-2023 The strace developers.
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: LGPL-2.1-or-later
7 */
8
9 #include "rt_sigframe.h"
10
11 /* see further comments in GDB: gdb/hppa-linux-tdep.c */
12
13 #define SIGFRAME 64
14
15 FUNC_GET_RT_SIGFRAME_ADDR
16 {
17 unsigned long sp, ip;
18
19 if (!get_instruction_pointer(tcp, &ip) ||
20 !get_stack_pointer(tcp, &sp))
21 return 0;
22
23 sp &= -1UL;
24 /* check if ip is part of stack, running in tramp[] of rt_sigframe */
25 if ((sp - ip) < 1024) {
26 /* on executable stack: We execute in tramp[], so align down. */
27 return (ip & -SIGFRAME)
28 /* compensate for size difference old and new frame */
29 + sizeof(struct_rt_sigframe_old)
30 - sizeof(struct_rt_sigframe);
31 } else {
32 /* running in VDSO on kernel >= 5.18 */
33 static kernel_ulong_t context_offset;
34
35 /* read sigframe offset from kernel VDSO header */
36 if (!context_offset)
37 context_offset = ptrace(PTRACE_PEEKTEXT, (pid_t) tcp->pid,
38 (void *)(ip & -SIGFRAME), 0);
39 if (context_offset == (kernel_ulong_t) -1)
40 return 0;
41
42 /* context_offset is a negative value */
43 return sp + context_offset - offsetof(struct_rt_sigframe, uc.uc_mcontext);
44 }
45 }