linux-unwind.h revision 1.1.1.13 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