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