1 /* ARM EABI compliant unwinding routines.
2 Copyright (C) 2004-2023 Free Software Foundation, Inc.
3 Contributed by Paul Brook
4
5 This file is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 3, or (at your option) any
8 later version.
9
10 This file is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 Under Section 7 of GPL version 3, you are granted additional
16 permissions described in the GCC Runtime Library Exception, version
17 3.1, as published by the Free Software Foundation.
18
19 You should have received a copy of the GNU General Public License and
20 a copy of the GCC Runtime Library Exception along with this program;
21 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
22 <http://www.gnu.org/licenses/>. */
23
24 #pragma GCC target ("general-regs-only")
25 #include "unwind.h"
26
27 /* Misc constants. */
28 #define R_IP 12
29 #define R_SP 13
30 #define R_LR 14
31 #define R_PC 15
32
33 #define VRS_PC(vrs) ((vrs)->core.r[R_PC])
34 #define VRS_SP(vrs) ((vrs)->core.r[R_SP])
35 #define VRS_RETURN(vrs) ((vrs)->core.r[R_LR])
36
37 struct core_regs
38 {
39 _uw r[16];
40 };
41
42 /* We use normal integer types here to avoid the compiler generating
43 coprocessor instructions. */
44 struct vfp_regs
45 {
46 _uw64 d[16];
47 _uw pad;
48 };
49
50 struct vfpv3_regs
51 {
52 /* Always populated via VSTM, so no need for the "pad" field from
53 vfp_regs (which is used to store the format word for FSTMX). */
54 _uw64 d[16];
55 };
56
57 struct wmmxd_regs
58 {
59 _uw64 wd[16];
60 };
61
62 struct wmmxc_regs
63 {
64 _uw wc[4];
65 };
66
67 /* Holds value of pseudo registers eg. PAC. */
68 struct pseudo_regs
69 {
70 _uw pac;
71 };
72
73 /* The ABI specifies that the unwind routines may only use core registers,
74 except when actually manipulating coprocessor state. This allows
75 us to write one implementation that works on all platforms by
76 demand-saving coprocessor registers.
77
78 During unwinding we hold the coprocessor state in the actual hardware
79 registers and allocate demand-save areas for use during phase1
80 unwinding. */
81
82 typedef struct
83 {
84 /* The first fields must be the same as a phase2_vrs. */
85 _uw demand_save_flags;
86 struct core_regs core;
87 /* Armv8.1-M Mainline PAC/AUTH values. This field should be in the same field
88 order as phase2_vrs. */
89 struct pseudo_regs pseudo;
90 _uw prev_sp; /* Only valid during forced unwinding. */
91 struct vfp_regs vfp;
92 struct vfpv3_regs vfp_regs_16_to_31;
93 struct wmmxd_regs wmmxd;
94 struct wmmxc_regs wmmxc;
95 } phase1_vrs;
96
97 #define DEMAND_SAVE_VFP 1 /* VFP state has been saved if not set */
98 #define DEMAND_SAVE_VFP_D 2 /* VFP state is for FLDMD/FSTMD if set */
99 #define DEMAND_SAVE_VFP_V3 4 /* VFPv3 state for regs 16 .. 31 has
100 been saved if not set */
101 #define DEMAND_SAVE_WMMXD 8 /* iWMMXt data registers have been
102 saved if not set. */
103 #define DEMAND_SAVE_WMMXC 16 /* iWMMXt control registers have been
104 saved if not set. */
105
106 /* This must match the structure created by the assembly wrappers. */
107 typedef struct
108 {
109 _uw demand_save_flags;
110 struct core_regs core;
111 struct pseudo_regs pac;
112 } phase2_vrs;
113
114 /* Coprocessor register state manipulation functions. */
115
116 /* Routines for FLDMX/FSTMX format... */
117 void __gnu_Unwind_Save_VFP (struct vfp_regs * p);
118 void __gnu_Unwind_Restore_VFP (struct vfp_regs * p);
119 void __gnu_Unwind_Save_WMMXD (struct wmmxd_regs * p);
120 void __gnu_Unwind_Restore_WMMXD (struct wmmxd_regs * p);
121 void __gnu_Unwind_Save_WMMXC (struct wmmxc_regs * p);
122 void __gnu_Unwind_Restore_WMMXC (struct wmmxc_regs * p);
123
124 /* ...and those for FLDMD/FSTMD format... */
125 void __gnu_Unwind_Save_VFP_D (struct vfp_regs * p);
126 void __gnu_Unwind_Restore_VFP_D (struct vfp_regs * p);
127
128 /* ...and those for VLDM/VSTM format, saving/restoring only registers
129 16 through 31. */
130 void __gnu_Unwind_Save_VFP_D_16_to_31 (struct vfpv3_regs * p);
131 void __gnu_Unwind_Restore_VFP_D_16_to_31 (struct vfpv3_regs * p);
132
133 /* Restore coprocessor state after phase1 unwinding. */
134 static void
135 restore_non_core_regs (phase1_vrs * vrs)
136 {
137 if ((vrs->demand_save_flags & DEMAND_SAVE_VFP) == 0)
138 {
139 if (vrs->demand_save_flags & DEMAND_SAVE_VFP_D)
140 __gnu_Unwind_Restore_VFP_D (&vrs->vfp);
141 else
142 __gnu_Unwind_Restore_VFP (&vrs->vfp);
143 }
144
145 if ((vrs->demand_save_flags & DEMAND_SAVE_VFP_V3) == 0)
146 __gnu_Unwind_Restore_VFP_D_16_to_31 (&vrs->vfp_regs_16_to_31);
147
148 if ((vrs->demand_save_flags & DEMAND_SAVE_WMMXD) == 0)
149 __gnu_Unwind_Restore_WMMXD (&vrs->wmmxd);
150 if ((vrs->demand_save_flags & DEMAND_SAVE_WMMXC) == 0)
151 __gnu_Unwind_Restore_WMMXC (&vrs->wmmxc);
152 }
153
154 #include "unwind-arm-common.inc"
155
156 /* ABI defined personality routines. */
157 extern _Unwind_Reason_Code __aeabi_unwind_cpp_pr0 (_Unwind_State,
158 _Unwind_Control_Block *, _Unwind_Context *);// __attribute__((weak));
159 extern _Unwind_Reason_Code __aeabi_unwind_cpp_pr1 (_Unwind_State,
160 _Unwind_Control_Block *, _Unwind_Context *) __attribute__((weak));
161 extern _Unwind_Reason_Code __aeabi_unwind_cpp_pr2 (_Unwind_State,
162 _Unwind_Control_Block *, _Unwind_Context *) __attribute__((weak));
163
164 /* ABI defined routine to store a virtual register to memory. */
165
166 _Unwind_VRS_Result _Unwind_VRS_Get (_Unwind_Context *context,
167 _Unwind_VRS_RegClass regclass,
168 _uw regno,
169 _Unwind_VRS_DataRepresentation representation,
170 void *valuep)
171 {
172 phase1_vrs *vrs = (phase1_vrs *) context;
173
174 switch (regclass)
175 {
176 case _UVRSC_CORE:
177 if (representation != _UVRSD_UINT32
178 || regno > 15)
179 return _UVRSR_FAILED;
180 *(_uw *) valuep = vrs->core.r[regno];
181 return _UVRSR_OK;
182
183 case _UVRSC_VFP:
184 case _UVRSC_WMMXD:
185 case _UVRSC_WMMXC:
186 return _UVRSR_NOT_IMPLEMENTED;
187
188 case _UVRSC_PAC:
189 *(_uw *) valuep = vrs->pseudo.pac;
190 return _UVRSR_OK;
191
192 default:
193 return _UVRSR_FAILED;
194 }
195 }
196
197
198 /* ABI defined function to load a virtual register from memory. */
199
200 _Unwind_VRS_Result _Unwind_VRS_Set (_Unwind_Context *context,
201 _Unwind_VRS_RegClass regclass,
202 _uw regno,
203 _Unwind_VRS_DataRepresentation representation,
204 void *valuep)
205 {
206 phase1_vrs *vrs = (phase1_vrs *) context;
207
208 switch (regclass)
209 {
210 case _UVRSC_CORE:
211 if (representation != _UVRSD_UINT32
212 || regno > 15)
213 return _UVRSR_FAILED;
214
215 vrs->core.r[regno] = *(_uw *) valuep;
216 return _UVRSR_OK;
217
218 case _UVRSC_VFP:
219 case _UVRSC_WMMXD:
220 case _UVRSC_WMMXC:
221 return _UVRSR_NOT_IMPLEMENTED;
222
223 case _UVRSC_PAC:
224 vrs->pseudo.pac = *(_uw *) valuep;
225 return _UVRSR_OK;
226
227 default:
228 return _UVRSR_FAILED;
229 }
230 }
231
232
233 /* ABI defined function to pop registers off the stack. */
234
235 _Unwind_VRS_Result _Unwind_VRS_Pop (_Unwind_Context *context,
236 _Unwind_VRS_RegClass regclass,
237 _uw discriminator,
238 _Unwind_VRS_DataRepresentation representation)
239 {
240 phase1_vrs *vrs = (phase1_vrs *) context;
241
242 switch (regclass)
243 {
244 case _UVRSC_CORE:
245 {
246 _uw *ptr;
247 _uw mask;
248 int i;
249
250 if (representation != _UVRSD_UINT32)
251 return _UVRSR_FAILED;
252
253 mask = discriminator & 0xffff;
254 ptr = (_uw *) vrs->core.r[R_SP];
255 /* Pop the requested registers. */
256 for (i = 0; i < 16; i++)
257 {
258 if (mask & (1 << i))
259 vrs->core.r[i] = *(ptr++);
260 }
261 /* Writeback the stack pointer value if it wasn't restored. */
262 if ((mask & (1 << R_SP)) == 0)
263 vrs->core.r[R_SP] = (_uw) ptr;
264 }
265 return _UVRSR_OK;
266
267 case _UVRSC_PAC:
268 {
269 _uw *ptr = (_uw *) vrs->core.r[R_SP];
270 if (discriminator != 0)
271 return _UVRSR_FAILED;
272 vrs->pseudo.pac = *(ptr++);
273 vrs->core.r[R_SP] = (_uw) ptr;
274 return _UVRSR_OK;
275 }
276
277 case _UVRSC_VFP:
278 {
279 _uw start = discriminator >> 16;
280 _uw count = discriminator & 0xffff;
281 struct vfp_regs tmp;
282 struct vfpv3_regs tmp_16_to_31;
283 int tmp_count;
284 _uw *sp;
285 _uw *dest;
286 int num_vfpv3_regs = 0;
287
288 /* We use an approximation here by bounding _UVRSD_DOUBLE
289 register numbers at 32 always, since we can't detect if
290 VFPv3 isn't present (in such a case the upper limit is 16). */
291 if ((representation != _UVRSD_VFPX && representation != _UVRSD_DOUBLE)
292 || start + count > (representation == _UVRSD_VFPX ? 16 : 32)
293 || (representation == _UVRSD_VFPX && start >= 16))
294 return _UVRSR_FAILED;
295
296 /* Check if we're being asked to pop VFPv3-only registers
297 (numbers 16 through 31). */
298 if (start >= 16)
299 num_vfpv3_regs = count;
300 else if (start + count > 16)
301 num_vfpv3_regs = start + count - 16;
302
303 if (num_vfpv3_regs && representation != _UVRSD_DOUBLE)
304 return _UVRSR_FAILED;
305
306 /* Demand-save coprocessor registers for stage1. */
307 if (start < 16 && (vrs->demand_save_flags & DEMAND_SAVE_VFP))
308 {
309 vrs->demand_save_flags &= ~DEMAND_SAVE_VFP;
310
311 if (representation == _UVRSD_DOUBLE)
312 {
313 /* Save in FLDMD/FSTMD format. */
314 vrs->demand_save_flags |= DEMAND_SAVE_VFP_D;
315 __gnu_Unwind_Save_VFP_D (&vrs->vfp);
316 }
317 else
318 {
319 /* Save in FLDMX/FSTMX format. */
320 vrs->demand_save_flags &= ~DEMAND_SAVE_VFP_D;
321 __gnu_Unwind_Save_VFP (&vrs->vfp);
322 }
323 }
324
325 if (num_vfpv3_regs > 0
326 && (vrs->demand_save_flags & DEMAND_SAVE_VFP_V3))
327 {
328 vrs->demand_save_flags &= ~DEMAND_SAVE_VFP_V3;
329 __gnu_Unwind_Save_VFP_D_16_to_31 (&vrs->vfp_regs_16_to_31);
330 }
331
332 /* Restore the registers from the stack. Do this by saving the
333 current VFP registers to a memory area, moving the in-memory
334 values into that area, and restoring from the whole area.
335 For _UVRSD_VFPX we assume FSTMX standard format 1. */
336 if (representation == _UVRSD_VFPX)
337 __gnu_Unwind_Save_VFP (&tmp);
338 else
339 {
340 /* Save registers 0 .. 15 if required. */
341 if (start < 16)
342 __gnu_Unwind_Save_VFP_D (&tmp);
343
344 /* Save VFPv3 registers 16 .. 31 if required. */
345 if (num_vfpv3_regs)
346 __gnu_Unwind_Save_VFP_D_16_to_31 (&tmp_16_to_31);
347 }
348
349 /* Work out how many registers below register 16 need popping. */
350 tmp_count = num_vfpv3_regs > 0 ? 16 - start : count;
351
352 /* Copy registers below 16, if needed.
353 The stack address is only guaranteed to be word aligned, so
354 we can't use doubleword copies. */
355 sp = (_uw *) vrs->core.r[R_SP];
356 if (tmp_count > 0)
357 {
358 tmp_count *= 2;
359 dest = (_uw *) &tmp.d[start];
360 while (tmp_count--)
361 *(dest++) = *(sp++);
362 }
363
364 /* Copy VFPv3 registers numbered >= 16, if needed. */
365 if (num_vfpv3_regs > 0)
366 {
367 /* num_vfpv3_regs is needed below, so copy it. */
368 int tmp_count_2 = num_vfpv3_regs * 2;
369 int vfpv3_start = start < 16 ? 16 : start;
370
371 dest = (_uw *) &tmp_16_to_31.d[vfpv3_start - 16];
372 while (tmp_count_2--)
373 *(dest++) = *(sp++);
374 }
375
376 /* Skip the format word space if using FLDMX/FSTMX format. */
377 if (representation == _UVRSD_VFPX)
378 sp++;
379
380 /* Set the new stack pointer. */
381 vrs->core.r[R_SP] = (_uw) sp;
382
383 /* Reload the registers. */
384 if (representation == _UVRSD_VFPX)
385 __gnu_Unwind_Restore_VFP (&tmp);
386 else
387 {
388 /* Restore registers 0 .. 15 if required. */
389 if (start < 16)
390 __gnu_Unwind_Restore_VFP_D (&tmp);
391
392 /* Restore VFPv3 registers 16 .. 31 if required. */
393 if (num_vfpv3_regs > 0)
394 __gnu_Unwind_Restore_VFP_D_16_to_31 (&tmp_16_to_31);
395 }
396 }
397 return _UVRSR_OK;
398
399 case _UVRSC_WMMXD:
400 {
401 _uw start = discriminator >> 16;
402 _uw count = discriminator & 0xffff;
403 struct wmmxd_regs tmp;
404 _uw *sp;
405 _uw *dest;
406
407 if ((representation != _UVRSD_UINT64) || start + count > 16)
408 return _UVRSR_FAILED;
409
410 if (vrs->demand_save_flags & DEMAND_SAVE_WMMXD)
411 {
412 /* Demand-save resisters for stage1. */
413 vrs->demand_save_flags &= ~DEMAND_SAVE_WMMXD;
414 __gnu_Unwind_Save_WMMXD (&vrs->wmmxd);
415 }
416
417 /* Restore the registers from the stack. Do this by saving the
418 current WMMXD registers to a memory area, moving the in-memory
419 values into that area, and restoring from the whole area. */
420 __gnu_Unwind_Save_WMMXD (&tmp);
421
422 /* The stack address is only guaranteed to be word aligned, so
423 we can't use doubleword copies. */
424 sp = (_uw *) vrs->core.r[R_SP];
425 dest = (_uw *) &tmp.wd[start];
426 count *= 2;
427 while (count--)
428 *(dest++) = *(sp++);
429
430 /* Set the new stack pointer. */
431 vrs->core.r[R_SP] = (_uw) sp;
432
433 /* Reload the registers. */
434 __gnu_Unwind_Restore_WMMXD (&tmp);
435 }
436 return _UVRSR_OK;
437
438 case _UVRSC_WMMXC:
439 {
440 int i;
441 struct wmmxc_regs tmp;
442 _uw *sp;
443
444 if ((representation != _UVRSD_UINT32) || discriminator > 16)
445 return _UVRSR_FAILED;
446
447 if (vrs->demand_save_flags & DEMAND_SAVE_WMMXC)
448 {
449 /* Demand-save resisters for stage1. */
450 vrs->demand_save_flags &= ~DEMAND_SAVE_WMMXC;
451 __gnu_Unwind_Save_WMMXC (&vrs->wmmxc);
452 }
453
454 /* Restore the registers from the stack. Do this by saving the
455 current WMMXC registers to a memory area, moving the in-memory
456 values into that area, and restoring from the whole area. */
457 __gnu_Unwind_Save_WMMXC (&tmp);
458
459 sp = (_uw *) vrs->core.r[R_SP];
460 for (i = 0; i < 4; i++)
461 if (discriminator & (1 << i))
462 tmp.wc[i] = *(sp++);
463
464 /* Set the new stack pointer. */
465 vrs->core.r[R_SP] = (_uw) sp;
466
467 /* Reload the registers. */
468 __gnu_Unwind_Restore_WMMXC (&tmp);
469 }
470 return _UVRSR_OK;
471
472 default:
473 return _UVRSR_FAILED;
474 }
475 }
476
477
478 /* Core unwinding functions. */
479
480 /* Calculate the address encoded by a 31-bit self-relative offset at address
481 P. */
482 static inline _uw
483 selfrel_offset31 (const _uw *p)
484 {
485 _uw offset;
486
487 offset = *p;
488 /* Sign extend to 32 bits. */
489 if (offset & (1 << 30))
490 offset |= 1u << 31;
491 else
492 offset &= ~(1u << 31);
493
494 return offset + (_uw) p;
495 }
496
497 static _uw
498 __gnu_unwind_get_pr_addr (int idx)
499 {
500 switch (idx)
501 {
502 case 0:
503 return (_uw) &__aeabi_unwind_cpp_pr0;
504
505 case 1:
506 return (_uw) &__aeabi_unwind_cpp_pr1;
507
508 case 2:
509 return (_uw) &__aeabi_unwind_cpp_pr2;
510
511 default:
512 return 0;
513 }
514 }
515
516 /* ABI defined personality routine entry points. */
517
518 _Unwind_Reason_Code
519 __aeabi_unwind_cpp_pr0 (_Unwind_State state,
520 _Unwind_Control_Block *ucbp,
521 _Unwind_Context *context)
522 {
523 return __gnu_unwind_pr_common (state, ucbp, context, 0);
524 }
525
526 _Unwind_Reason_Code
527 __aeabi_unwind_cpp_pr1 (_Unwind_State state,
528 _Unwind_Control_Block *ucbp,
529 _Unwind_Context *context)
530 {
531 return __gnu_unwind_pr_common (state, ucbp, context, 1);
532 }
533
534 _Unwind_Reason_Code
535 __aeabi_unwind_cpp_pr2 (_Unwind_State state,
536 _Unwind_Control_Block *ucbp,
537 _Unwind_Context *context)
538 {
539 return __gnu_unwind_pr_common (state, ucbp, context, 2);
540 }
541
542 #ifdef __FreeBSD__
543 /* FreeBSD expects these to be functions */
544 inline _Unwind_Ptr
545 _Unwind_GetIP (struct _Unwind_Context *context)
546 {
547 return _Unwind_GetGR (context, 15) & ~(_Unwind_Word)1;
548 }
549
550 inline _Unwind_Ptr
551 _Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
552 {
553 *ip_before_insn = 0;
554 return _Unwind_GetIP (context);
555 }
556
557 inline void
558 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
559 {
560 _Unwind_SetGR (context, 15, val | (_Unwind_GetGR (context, 15) & 1));
561 }
562 #endif