(root)/
strace-6.5/
src/
linux/
hppa/
arch_rt_sigframe.c
       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  }