libstdc++: Define __glibcxx_assert_fail for non-verbose build [PR115585]
[official-gcc.git] / libgcc / config / arm / unwind-arm.c
blob345cdc0a71e6e46009fa27edb07d8df523127899
1 /* ARM EABI compliant unwinding routines.
2 Copyright (C) 2004-2024 Free Software Foundation, Inc.
3 Contributed by Paul Brook
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.
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.
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.
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/>. */
24 #pragma GCC target ("general-regs-only")
25 #include "unwind.h"
27 /* Misc constants. */
28 #define R_IP 12
29 #define R_SP 13
30 #define R_LR 14
31 #define R_PC 15
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])
37 struct core_regs
39 _uw r[16];
42 /* We use normal integer types here to avoid the compiler generating
43 coprocessor instructions. */
44 struct vfp_regs
46 _uw64 d[16];
47 _uw pad;
50 struct vfpv3_regs
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];
57 struct wmmxd_regs
59 _uw64 wd[16];
62 struct wmmxc_regs
64 _uw wc[4];
67 /* Holds value of pseudo registers eg. PAC. */
68 struct pseudo_regs
70 _uw pac;
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.
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. */
82 typedef struct
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;
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. */
106 /* This must match the structure created by the assembly wrappers. */
107 typedef struct
109 _uw demand_save_flags;
110 struct core_regs core;
111 struct pseudo_regs pac;
112 } phase2_vrs;
114 /* Coprocessor register state manipulation functions. */
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);
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);
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);
133 /* Restore coprocessor state after phase1 unwinding. */
134 static void
135 restore_non_core_regs (phase1_vrs * vrs)
137 if ((vrs->demand_save_flags & DEMAND_SAVE_VFP) == 0)
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);
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);
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);
154 #include "unwind-arm-common.inc"
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));
164 /* ABI defined routine to store a virtual register to memory. */
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)
172 phase1_vrs *vrs = (phase1_vrs *) context;
174 switch (regclass)
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;
183 case _UVRSC_VFP:
184 case _UVRSC_WMMXD:
185 case _UVRSC_WMMXC:
186 return _UVRSR_NOT_IMPLEMENTED;
188 case _UVRSC_PAC:
189 *(_uw *) valuep = vrs->pseudo.pac;
190 return _UVRSR_OK;
192 default:
193 return _UVRSR_FAILED;
198 /* ABI defined function to load a virtual register from memory. */
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)
206 phase1_vrs *vrs = (phase1_vrs *) context;
208 switch (regclass)
210 case _UVRSC_CORE:
211 if (representation != _UVRSD_UINT32
212 || regno > 15)
213 return _UVRSR_FAILED;
215 vrs->core.r[regno] = *(_uw *) valuep;
216 return _UVRSR_OK;
218 case _UVRSC_VFP:
219 case _UVRSC_WMMXD:
220 case _UVRSC_WMMXC:
221 return _UVRSR_NOT_IMPLEMENTED;
223 case _UVRSC_PAC:
224 vrs->pseudo.pac = *(_uw *) valuep;
225 return _UVRSR_OK;
227 default:
228 return _UVRSR_FAILED;
233 /* ABI defined function to pop registers off the stack. */
235 _Unwind_VRS_Result _Unwind_VRS_Pop (_Unwind_Context *context,
236 _Unwind_VRS_RegClass regclass,
237 _uw discriminator,
238 _Unwind_VRS_DataRepresentation representation)
240 phase1_vrs *vrs = (phase1_vrs *) context;
242 switch (regclass)
244 case _UVRSC_CORE:
246 _uw *ptr;
247 _uw mask;
248 int i;
250 if (representation != _UVRSD_UINT32)
251 return _UVRSR_FAILED;
253 mask = discriminator & 0xffff;
254 ptr = (_uw *) vrs->core.r[R_SP];
255 /* Pop the requested registers. */
256 for (i = 0; i < 16; i++)
258 if (mask & (1 << i))
259 vrs->core.r[i] = *(ptr++);
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;
265 return _UVRSR_OK;
267 case _UVRSC_PAC:
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;
277 case _UVRSC_VFP:
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;
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;
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;
303 if (num_vfpv3_regs && representation != _UVRSD_DOUBLE)
304 return _UVRSR_FAILED;
306 /* Demand-save coprocessor registers for stage1. */
307 if (start < 16 && (vrs->demand_save_flags & DEMAND_SAVE_VFP))
309 vrs->demand_save_flags &= ~DEMAND_SAVE_VFP;
311 if (representation == _UVRSD_DOUBLE)
313 /* Save in FLDMD/FSTMD format. */
314 vrs->demand_save_flags |= DEMAND_SAVE_VFP_D;
315 __gnu_Unwind_Save_VFP_D (&vrs->vfp);
317 else
319 /* Save in FLDMX/FSTMX format. */
320 vrs->demand_save_flags &= ~DEMAND_SAVE_VFP_D;
321 __gnu_Unwind_Save_VFP (&vrs->vfp);
325 if (num_vfpv3_regs > 0
326 && (vrs->demand_save_flags & DEMAND_SAVE_VFP_V3))
328 vrs->demand_save_flags &= ~DEMAND_SAVE_VFP_V3;
329 __gnu_Unwind_Save_VFP_D_16_to_31 (&vrs->vfp_regs_16_to_31);
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
340 /* Save registers 0 .. 15 if required. */
341 if (start < 16)
342 __gnu_Unwind_Save_VFP_D (&tmp);
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);
349 /* Work out how many registers below register 16 need popping. */
350 tmp_count = num_vfpv3_regs > 0 ? 16 - start : count;
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)
358 tmp_count *= 2;
359 dest = (_uw *) &tmp.d[start];
360 while (tmp_count--)
361 *(dest++) = *(sp++);
364 /* Copy VFPv3 registers numbered >= 16, if needed. */
365 if (num_vfpv3_regs > 0)
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;
371 dest = (_uw *) &tmp_16_to_31.d[vfpv3_start - 16];
372 while (tmp_count_2--)
373 *(dest++) = *(sp++);
376 /* Skip the format word space if using FLDMX/FSTMX format. */
377 if (representation == _UVRSD_VFPX)
378 sp++;
380 /* Set the new stack pointer. */
381 vrs->core.r[R_SP] = (_uw) sp;
383 /* Reload the registers. */
384 if (representation == _UVRSD_VFPX)
385 __gnu_Unwind_Restore_VFP (&tmp);
386 else
388 /* Restore registers 0 .. 15 if required. */
389 if (start < 16)
390 __gnu_Unwind_Restore_VFP_D (&tmp);
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);
397 return _UVRSR_OK;
399 case _UVRSC_WMMXD:
401 _uw start = discriminator >> 16;
402 _uw count = discriminator & 0xffff;
403 struct wmmxd_regs tmp;
404 _uw *sp;
405 _uw *dest;
407 if ((representation != _UVRSD_UINT64) || start + count > 16)
408 return _UVRSR_FAILED;
410 if (vrs->demand_save_flags & DEMAND_SAVE_WMMXD)
412 /* Demand-save resisters for stage1. */
413 vrs->demand_save_flags &= ~DEMAND_SAVE_WMMXD;
414 __gnu_Unwind_Save_WMMXD (&vrs->wmmxd);
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);
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++);
430 /* Set the new stack pointer. */
431 vrs->core.r[R_SP] = (_uw) sp;
433 /* Reload the registers. */
434 __gnu_Unwind_Restore_WMMXD (&tmp);
436 return _UVRSR_OK;
438 case _UVRSC_WMMXC:
440 int i;
441 struct wmmxc_regs tmp;
442 _uw *sp;
444 if ((representation != _UVRSD_UINT32) || discriminator > 16)
445 return _UVRSR_FAILED;
447 if (vrs->demand_save_flags & DEMAND_SAVE_WMMXC)
449 /* Demand-save resisters for stage1. */
450 vrs->demand_save_flags &= ~DEMAND_SAVE_WMMXC;
451 __gnu_Unwind_Save_WMMXC (&vrs->wmmxc);
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);
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++);
464 /* Set the new stack pointer. */
465 vrs->core.r[R_SP] = (_uw) sp;
467 /* Reload the registers. */
468 __gnu_Unwind_Restore_WMMXC (&tmp);
470 return _UVRSR_OK;
472 default:
473 return _UVRSR_FAILED;
478 /* Core unwinding functions. */
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)
485 _uw offset;
487 offset = *p;
488 /* Sign extend to 32 bits. */
489 if (offset & (1 << 30))
490 offset |= 1u << 31;
491 else
492 offset &= ~(1u << 31);
494 return offset + (_uw) p;
497 static _uw
498 __gnu_unwind_get_pr_addr (int idx)
500 switch (idx)
502 case 0:
503 return (_uw) &__aeabi_unwind_cpp_pr0;
505 case 1:
506 return (_uw) &__aeabi_unwind_cpp_pr1;
508 case 2:
509 return (_uw) &__aeabi_unwind_cpp_pr2;
511 default:
512 return 0;
516 /* ABI defined personality routine entry points. */
518 _Unwind_Reason_Code
519 __aeabi_unwind_cpp_pr0 (_Unwind_State state,
520 _Unwind_Control_Block *ucbp,
521 _Unwind_Context *context)
523 return __gnu_unwind_pr_common (state, ucbp, context, 0);
526 _Unwind_Reason_Code
527 __aeabi_unwind_cpp_pr1 (_Unwind_State state,
528 _Unwind_Control_Block *ucbp,
529 _Unwind_Context *context)
531 return __gnu_unwind_pr_common (state, ucbp, context, 1);
534 _Unwind_Reason_Code
535 __aeabi_unwind_cpp_pr2 (_Unwind_State state,
536 _Unwind_Control_Block *ucbp,
537 _Unwind_Context *context)
539 return __gnu_unwind_pr_common (state, ucbp, context, 2);
542 #ifdef __FreeBSD__
543 /* FreeBSD expects these to be functions */
544 inline _Unwind_Ptr
545 _Unwind_GetIP (struct _Unwind_Context *context)
547 return _Unwind_GetGR (context, 15) & ~(_Unwind_Word)1;
550 inline _Unwind_Ptr
551 _Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
553 *ip_before_insn = 0;
554 return _Unwind_GetIP (context);
557 inline void
558 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
560 _Unwind_SetGR (context, 15, val | (_Unwind_GetGR (context, 15) & 1));
562 #endif