(root)/
glibc-2.38/
sysdeps/
microblaze/
backtrace_linux.c
       1  /* Copyright (C) 2005-2023 Free Software Foundation, Inc.
       2  
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public License as
       7     published by the Free Software Foundation; either version 2.1 of the
       8     License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <stddef.h>
      20  #include <asm/sigcontext.h>
      21  #include <linux/signal.h>
      22  #include <asm-generic/ucontext.h>
      23  #include <sys/syscall.h>
      24  
      25  int
      26  _identify_sighandler (unsigned long fp, unsigned long pc,
      27                        unsigned long *pprev_fp, unsigned long *pprev_pc,
      28                        unsigned long *retaddr)
      29  {
      30    unsigned long *tramp = 0;
      31    struct ucontext *uc;
      32  
      33    if (*retaddr == 0)
      34      {
      35        /* Kernel inserts the tramp between the signal handler frame and the
      36           caller frame in signal handling.  */
      37        tramp = (unsigned long *) pc;
      38        tramp += 2;
      39        if ((*tramp == (0x31800000 | __NR_rt_sigreturn))
      40            && (*(tramp+1) == 0xb9cc0008))
      41          {
      42            /* Signal handler function argument are:
      43               int sig_num, siginfo_t * info, void * ucontext
      44               therefore ucontext is the 3rd argument.  */
      45            unsigned long ucptr = ((unsigned long) tramp
      46                                   - sizeof (struct ucontext));
      47            uc = (struct ucontext *) ucptr;
      48            *pprev_pc = uc->uc_mcontext.regs.pc;
      49            /* Need to record the return address since the return address of the
      50               function which causes this signal may not be recorded in the
      51               stack.  */
      52            *pprev_fp = uc->uc_mcontext.regs.r1;
      53            *retaddr = uc->uc_mcontext.regs.r15;
      54            /* It is a signal handler.  */
      55            return 1;
      56          }
      57      }
      58    return 0;
      59  }