(root)/
gcc-13.2.0/
libgcc/
config/
bfin/
linux-unwind.h
       1  /* DWARF2 EH unwinding support for Blackfin.
       2     Copyright (C) 2007-2023 Free Software Foundation, Inc.
       3  
       4  This file is part of GCC.
       5  
       6  GCC is free software; you can redistribute it and/or modify
       7  it under the terms of the GNU General Public License as published by
       8  the Free Software Foundation; either version 3, or (at your option)
       9  any later version.
      10  
      11  GCC is distributed in the hope that it will be useful,
      12  but WITHOUT ANY WARRANTY; without even the implied warranty of
      13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14  GNU General Public License for more details.
      15  
      16  Under Section 7 of GPL version 3, you are granted additional
      17  permissions described in the GCC Runtime Library Exception, version
      18  3.1, as published by the Free Software Foundation.
      19  
      20  You should have received a copy of the GNU General Public License and
      21  a copy of the GCC Runtime Library Exception along with this program;
      22  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      23  <http://www.gnu.org/licenses/>.  */
      24  
      25  /* Do code reading to identify a signal frame, and set the frame
      26     state data appropriately.  See unwind-dw2.c for the structs.
      27     Don't use this at all if inhibit_libc is used.  */
      28  
      29  #ifndef inhibit_libc
      30  
      31  #include <signal.h>
      32  #include <sys/ucontext.h>
      33  
      34  #define MD_FALLBACK_FRAME_STATE_FOR bfin_fallback_frame_state
      35  
      36  static _Unwind_Reason_Code
      37  bfin_fallback_frame_state (struct _Unwind_Context *context,
      38  			   _Unwind_FrameState *fs)
      39  {
      40    unsigned char *pc = context->ra;
      41    struct sigcontext *sc;
      42    long new_cfa;
      43  
      44    /* P0=__NR_rt_sigreturn (X); EXCPT  0x0; */
      45    if (*(unsigned short *)pc == 0xe128
      46        && *(unsigned short *)(pc + 2) == 0x00ad
      47        && *(unsigned short *)(pc + 4) == 0x00a0)
      48      {
      49        struct rt_sigframe {
      50  	int sig;
      51  	siginfo_t *pinfo;
      52  	void *puc;
      53  	char retcode[8];
      54  	siginfo_t info;
      55  	ucontext_t uc;
      56        } *rt_ = context->cfa;
      57  
      58        /* The void * cast is necessary to avoid an aliasing warning.
      59           The aliasing warning is correct, but should not be a problem
      60           because it does not alias anything.  */
      61        sc = (struct sigcontext *)(void *)&rt_->uc.uc_mcontext.gregs;
      62      }
      63    else
      64      return _URC_END_OF_STACK;
      65  
      66    new_cfa = sc->sc_usp;
      67    fs->regs.cfa_how = CFA_REG_OFFSET;
      68    fs->regs.cfa_reg = 14;
      69    fs->regs.cfa_offset = new_cfa - (long) context->cfa;
      70  
      71    fs->regs.how[0] = REG_SAVED_OFFSET;
      72    fs->regs.reg[0].loc.offset = (long)&sc->sc_r0 - new_cfa;
      73    fs->regs.how[1] = REG_SAVED_OFFSET;
      74    fs->regs.reg[1].loc.offset = (long)&sc->sc_r1 - new_cfa;
      75    fs->regs.how[2] = REG_SAVED_OFFSET;
      76    fs->regs.reg[2].loc.offset = (long)&sc->sc_r2 - new_cfa;
      77    fs->regs.how[3] = REG_SAVED_OFFSET;
      78    fs->regs.reg[3].loc.offset = (long)&sc->sc_r3 - new_cfa;
      79    fs->regs.how[4] = REG_SAVED_OFFSET;
      80    fs->regs.reg[4].loc.offset = (long)&sc->sc_r4 - new_cfa;
      81    fs->regs.how[5] = REG_SAVED_OFFSET;
      82    fs->regs.reg[5].loc.offset = (long)&sc->sc_r5 - new_cfa;
      83    fs->regs.how[6] = REG_SAVED_OFFSET;
      84    fs->regs.reg[6].loc.offset = (long)&sc->sc_r6 - new_cfa;
      85    fs->regs.how[7] = REG_SAVED_OFFSET;
      86    fs->regs.reg[7].loc.offset = (long)&sc->sc_r7 - new_cfa;
      87    fs->regs.how[8] = REG_SAVED_OFFSET;
      88    fs->regs.reg[8].loc.offset = (long)&sc->sc_p0 - new_cfa;
      89    fs->regs.how[9] = REG_SAVED_OFFSET;
      90    fs->regs.reg[9].loc.offset = (long)&sc->sc_p1 - new_cfa;
      91    fs->regs.how[10] = REG_SAVED_OFFSET;
      92    fs->regs.reg[10].loc.offset = (long)&sc->sc_p2 - new_cfa;
      93    fs->regs.how[11] = REG_SAVED_OFFSET;
      94    fs->regs.reg[11].loc.offset = (long)&sc->sc_p3 - new_cfa;
      95    fs->regs.how[12] = REG_SAVED_OFFSET;
      96    fs->regs.reg[12].loc.offset = (long)&sc->sc_p4 - new_cfa;
      97    fs->regs.how[13] = REG_SAVED_OFFSET;
      98    fs->regs.reg[13].loc.offset = (long)&sc->sc_p5 - new_cfa;
      99  
     100    fs->regs.how[15] = REG_SAVED_OFFSET;
     101    fs->regs.reg[15].loc.offset = (long)&sc->sc_fp - new_cfa;
     102    fs->regs.how[16] = REG_SAVED_OFFSET;
     103    fs->regs.reg[16].loc.offset = (long)&sc->sc_i0 - new_cfa;
     104    fs->regs.how[17] = REG_SAVED_OFFSET;
     105    fs->regs.reg[17].loc.offset = (long)&sc->sc_i1 - new_cfa;
     106    fs->regs.how[18] = REG_SAVED_OFFSET;
     107    fs->regs.reg[18].loc.offset = (long)&sc->sc_i2 - new_cfa;
     108    fs->regs.how[19] = REG_SAVED_OFFSET;
     109    fs->regs.reg[19].loc.offset = (long)&sc->sc_i3 - new_cfa;
     110    fs->regs.how[20] = REG_SAVED_OFFSET;
     111    fs->regs.reg[20].loc.offset = (long)&sc->sc_b0 - new_cfa;
     112    fs->regs.how[21] = REG_SAVED_OFFSET;
     113    fs->regs.reg[21].loc.offset = (long)&sc->sc_b1 - new_cfa;
     114    fs->regs.how[22] = REG_SAVED_OFFSET;
     115    fs->regs.reg[22].loc.offset = (long)&sc->sc_b2 - new_cfa;
     116    fs->regs.how[23] = REG_SAVED_OFFSET;
     117    fs->regs.reg[23].loc.offset = (long)&sc->sc_b3 - new_cfa;
     118    fs->regs.how[24] = REG_SAVED_OFFSET;
     119    fs->regs.reg[24].loc.offset = (long)&sc->sc_l0 - new_cfa;
     120    fs->regs.how[25] = REG_SAVED_OFFSET;
     121    fs->regs.reg[25].loc.offset = (long)&sc->sc_l1 - new_cfa;
     122    fs->regs.how[26] = REG_SAVED_OFFSET;
     123    fs->regs.reg[26].loc.offset = (long)&sc->sc_l2 - new_cfa;
     124    fs->regs.how[27] = REG_SAVED_OFFSET;
     125    fs->regs.reg[27].loc.offset = (long)&sc->sc_l3 - new_cfa;
     126    fs->regs.how[28] = REG_SAVED_OFFSET;
     127    fs->regs.reg[28].loc.offset = (long)&sc->sc_m0 - new_cfa;
     128    fs->regs.how[29] = REG_SAVED_OFFSET;
     129    fs->regs.reg[29].loc.offset = (long)&sc->sc_m1 - new_cfa;
     130    fs->regs.how[30] = REG_SAVED_OFFSET;
     131    fs->regs.reg[30].loc.offset = (long)&sc->sc_m2 - new_cfa;
     132    fs->regs.how[31] = REG_SAVED_OFFSET;
     133    fs->regs.reg[31].loc.offset = (long)&sc->sc_m3 - new_cfa;
     134    /* FIXME: Handle A0, A1, CC.  */
     135    fs->regs.how[35] = REG_SAVED_OFFSET;
     136    fs->regs.reg[35].loc.offset = (long)&sc->sc_rets - new_cfa;
     137    fs->regs.how[36] = REG_SAVED_OFFSET;
     138    fs->regs.reg[36].loc.offset = (long)&sc->sc_pc - new_cfa;
     139    fs->regs.how[37] = REG_SAVED_OFFSET;
     140    fs->regs.reg[37].loc.offset = (long)&sc->sc_retx - new_cfa;
     141  
     142    fs->regs.how[40] = REG_SAVED_OFFSET;
     143    fs->regs.reg[40].loc.offset = (long)&sc->sc_astat - new_cfa;
     144    fs->regs.how[41] = REG_SAVED_OFFSET;
     145    fs->regs.reg[41].loc.offset = (long)&sc->sc_seqstat - new_cfa;
     146  
     147    fs->regs.how[44] = REG_SAVED_OFFSET;
     148    fs->regs.reg[44].loc.offset = (long)&sc->sc_lt0 - new_cfa;
     149    fs->regs.how[45] = REG_SAVED_OFFSET;
     150    fs->regs.reg[45].loc.offset = (long)&sc->sc_lt1 - new_cfa;
     151    fs->regs.how[46] = REG_SAVED_OFFSET;
     152    fs->regs.reg[46].loc.offset = (long)&sc->sc_lc0 - new_cfa;
     153    fs->regs.how[47] = REG_SAVED_OFFSET;
     154    fs->regs.reg[47].loc.offset = (long)&sc->sc_lc1 - new_cfa;
     155    fs->regs.how[48] = REG_SAVED_OFFSET;
     156    fs->regs.reg[48].loc.offset = (long)&sc->sc_lb0 - new_cfa;
     157    fs->regs.how[49] = REG_SAVED_OFFSET;
     158    fs->regs.reg[49].loc.offset = (long)&sc->sc_lb1 - new_cfa;
     159    fs->retaddr_column = 35;
     160  
     161    return _URC_NO_REASON;
     162  }
     163  
     164  #endif /* ifdef inhibit_libc */