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
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")
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])
42 /* We use normal integer types here to avoid the compiler generating
43 coprocessor instructions. */
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). */
67 /* Holds value of pseudo registers eg. 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
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. */
92 struct vfpv3_regs vfp_regs_16_to_31
;
93 struct wmmxd_regs wmmxd
;
94 struct wmmxc_regs wmmxc
;
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
103 #define DEMAND_SAVE_WMMXC 16 /* iWMMXt control registers have been
106 /* This must match the structure created by the assembly wrappers. */
109 _uw demand_save_flags
;
110 struct core_regs core
;
111 struct pseudo_regs pac
;
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
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. */
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
);
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
,
169 _Unwind_VRS_DataRepresentation representation
,
172 phase1_vrs
*vrs
= (phase1_vrs
*) context
;
177 if (representation
!= _UVRSD_UINT32
179 return _UVRSR_FAILED
;
180 *(_uw
*) valuep
= vrs
->core
.r
[regno
];
186 return _UVRSR_NOT_IMPLEMENTED
;
189 *(_uw
*) valuep
= vrs
->pseudo
.pac
;
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
,
203 _Unwind_VRS_DataRepresentation representation
,
206 phase1_vrs
*vrs
= (phase1_vrs
*) context
;
211 if (representation
!= _UVRSD_UINT32
213 return _UVRSR_FAILED
;
215 vrs
->core
.r
[regno
] = *(_uw
*) valuep
;
221 return _UVRSR_NOT_IMPLEMENTED
;
224 vrs
->pseudo
.pac
= *(_uw
*) valuep
;
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
,
238 _Unwind_VRS_DataRepresentation representation
)
240 phase1_vrs
*vrs
= (phase1_vrs
*) context
;
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
++)
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
;
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
;
279 _uw start
= discriminator
>> 16;
280 _uw count
= discriminator
& 0xffff;
282 struct vfpv3_regs tmp_16_to_31
;
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). */
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
);
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
);
340 /* Save registers 0 .. 15 if required. */
342 __gnu_Unwind_Save_VFP_D (&tmp
);
344 /* Save VFPv3 registers 16 .. 31 if required. */
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
];
359 dest
= (_uw
*) &tmp
.d
[start
];
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
--)
376 /* Skip the format word space if using FLDMX/FSTMX format. */
377 if (representation
== _UVRSD_VFPX
)
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
);
388 /* Restore registers 0 .. 15 if required. */
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
);
401 _uw start
= discriminator
>> 16;
402 _uw count
= discriminator
& 0xffff;
403 struct wmmxd_regs tmp
;
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
];
430 /* Set the new stack pointer. */
431 vrs
->core
.r
[R_SP
] = (_uw
) sp
;
433 /* Reload the registers. */
434 __gnu_Unwind_Restore_WMMXD (&tmp
);
441 struct wmmxc_regs tmp
;
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
))
464 /* Set the new stack pointer. */
465 vrs
->core
.r
[R_SP
] = (_uw
) sp
;
467 /* Reload the registers. */
468 __gnu_Unwind_Restore_WMMXC (&tmp
);
473 return _UVRSR_FAILED
;
478 /* Core unwinding functions. */
480 /* Calculate the address encoded by a 31-bit self-relative offset at address
483 selfrel_offset31 (const _uw
*p
)
488 /* Sign extend to 32 bits. */
489 if (offset
& (1 << 30))
492 offset
&= ~(1u << 31);
494 return offset
+ (_uw
) p
;
498 __gnu_unwind_get_pr_addr (int idx
)
503 return (_uw
) &__aeabi_unwind_cpp_pr0
;
506 return (_uw
) &__aeabi_unwind_cpp_pr1
;
509 return (_uw
) &__aeabi_unwind_cpp_pr2
;
516 /* ABI defined personality routine entry points. */
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);
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);
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);
543 /* FreeBSD expects these to be functions */
545 _Unwind_GetIP (struct _Unwind_Context
*context
)
547 return _Unwind_GetGR (context
, 15) & ~(_Unwind_Word
)1;
551 _Unwind_GetIPInfo (struct _Unwind_Context
*context
, int *ip_before_insn
)
554 return _Unwind_GetIP (context
);
558 _Unwind_SetIP (struct _Unwind_Context
*context
, _Unwind_Ptr val
)
560 _Unwind_SetGR (context
, 15, val
| (_Unwind_GetGR (context
, 15) & 1));