]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgcc/unwind-dw2.c
libgcc: Decrease size of _Unwind_FrameState and even more size of cleared area in...
[thirdparty/gcc.git] / libgcc / unwind-dw2.c
CommitLineData
52a11cbf 1/* DWARF2 exception handling and frame unwind runtime interface routines.
7adcbafe 2 Copyright (C) 1997-2022 Free Software Foundation, Inc.
52a11cbf 3
1322177d 4 This file is part of GCC.
52a11cbf 5
1322177d
LB
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
748086b7 8 the Free Software Foundation; either version 3, or (at your option)
52a11cbf
RH
9 any later version.
10
1322177d
LB
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
52a11cbf 15
748086b7
JJ
16 Under Section 7 of GPL version 3, you are granted additional
17 permissions described in the GCC Runtime Library Exception, version
18 3.1, as published by the Free Software Foundation.
19
20 You should have received a copy of the GNU General Public License and
21 a copy of the GCC Runtime Library Exception along with this program;
22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 <http://www.gnu.org/licenses/>. */
52a11cbf
RH
24
25#include "tconfig.h"
26#include "tsystem.h"
4977bab6
ZW
27#include "coretypes.h"
28#include "tm.h"
852b75ed 29#include "libgcc_tm.h"
a80b0574 30#include "dwarf2.h"
52a11cbf 31#include "unwind.h"
525996eb
KG
32#ifdef __USING_SJLJ_EXCEPTIONS__
33# define NO_SIZE_OF_ENCODED_VALUE
34#endif
e1f9550a 35#include "unwind-pe.h"
52a11cbf
RH
36#include "unwind-dw2-fde.h"
37#include "gthr.h"
f8a57be8 38#include "unwind-dw2.h"
146e4591 39#include <stddef.h>
52a11cbf 40
f4e749b4
TT
41#ifdef HAVE_SYS_SDT_H
42#include <sys/sdt.h>
43#endif
44
0d24f4d1 45#ifndef __USING_SJLJ_EXCEPTIONS__
52a11cbf 46
53d68b9f
JM
47#ifndef __LIBGCC_STACK_GROWS_DOWNWARD__
48#define __LIBGCC_STACK_GROWS_DOWNWARD__ 0
52a11cbf 49#else
53d68b9f
JM
50#undef __LIBGCC_STACK_GROWS_DOWNWARD__
51#define __LIBGCC_STACK_GROWS_DOWNWARD__ 1
52a11cbf
RH
52#endif
53
919543ab
AH
54/* Dwarf frame registers used for pre gcc 3.0 compiled glibc. */
55#ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
53d68b9f 56#define PRE_GCC3_DWARF_FRAME_REGISTERS __LIBGCC_DWARF_FRAME_REGISTERS__
919543ab
AH
57#endif
58
0ec33224
RH
59/* ??? For the public function interfaces, we tend to gcc_assert that the
60 column numbers are in range. For the dwarf2 unwind info this does happen,
61 although so far in a case that doesn't actually matter.
62
63 See PR49146, in which a call from x86_64 ms abi to x86_64 unix abi stores
64 the call-saved xmm registers and annotates them. We havn't bothered
65 providing support for the xmm registers for the x86_64 port primarily
66 because the 64-bit windows targets don't use dwarf2 unwind, using sjlj or
67 SEH instead. Adding the support for unix targets would generally be a
68 waste. However, some runtime libraries supplied with ICC do contain such
69 an unorthodox transition, as well as the unwind info to match. This loss
70 of register restoration doesn't matter in practice, because the exception
71 is caught in the native unix abi, where all of the xmm registers are
72 call clobbered.
73
74 Ideally, we'd record some bit to notice when we're failing to restore some
75 register recorded in the unwind info, but to do that we need annotation on
76 the unix->ms abi edge, so that we know when the register data may be
77 discarded. And since this edge is also within the ICC library, we're
78 unlikely to be able to get the new annotation.
79
80 Barring a magic solution to restore the ms abi defined 128-bit xmm registers
81 (as distictly opposed to the full runtime width) without causing extra
82 overhead for normal unix abis, the best solution seems to be to simply
83 ignore unwind data for unknown columns. */
84
85#define UNWIND_COLUMN_IN_RANGE(x) \
53d68b9f 86 __builtin_expect((x) <= __LIBGCC_DWARF_FRAME_REGISTERS__, 1)
0ec33224 87
cca2207a
L
88#ifdef REG_VALUE_IN_UNWIND_CONTEXT
89typedef _Unwind_Word _Unwind_Context_Reg_Val;
90
91#ifndef ASSUME_EXTENDED_UNWIND_CONTEXT
92#define ASSUME_EXTENDED_UNWIND_CONTEXT 1
93#endif
94
95static inline _Unwind_Word
96_Unwind_Get_Unwind_Word (_Unwind_Context_Reg_Val val)
97{
98 return val;
99}
100
101static inline _Unwind_Context_Reg_Val
102_Unwind_Get_Unwind_Context_Reg_Val (_Unwind_Word val)
103{
104 return val;
105}
106#else
107typedef void *_Unwind_Context_Reg_Val;
108
109static inline _Unwind_Word
110_Unwind_Get_Unwind_Word (_Unwind_Context_Reg_Val val)
111{
112 return (_Unwind_Word) (_Unwind_Internal_Ptr) val;
113}
114
115static inline _Unwind_Context_Reg_Val
116_Unwind_Get_Unwind_Context_Reg_Val (_Unwind_Word val)
117{
118 return (_Unwind_Context_Reg_Val) (_Unwind_Internal_Ptr) val;
119}
120#endif
121
122#ifndef ASSUME_EXTENDED_UNWIND_CONTEXT
123#define ASSUME_EXTENDED_UNWIND_CONTEXT 0
124#endif
125
81a60e6c
JM
126/* This is the register and unwind state for a particular frame. This
127 provides the information necessary to unwind up past a frame and return
128 to its caller. */
52a11cbf
RH
129struct _Unwind_Context
130{
53d68b9f 131 _Unwind_Context_Reg_Val reg[__LIBGCC_DWARF_FRAME_REGISTERS__+1];
52a11cbf
RH
132 void *cfa;
133 void *ra;
134 void *lsda;
135 struct dwarf_eh_bases bases;
f8e7718c
JJ
136 /* Signal frame context. */
137#define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1)
138 /* Context which has version/args_size/by_value fields. */
139#define EXTENDED_CONTEXT_BIT ((~(_Unwind_Word) 0 >> 2) + 1)
8fc16d72
ST
140 /* Bit reserved on AArch64, return address has been signed with A or B
141 key. */
142#define RA_SIGNED_BIT ((~(_Unwind_Word) 0 >> 3) + 1)
f8e7718c
JJ
143 _Unwind_Word flags;
144 /* 0 for now, can be increased when further fields are added to
145 struct _Unwind_Context. */
146 _Unwind_Word version;
52a11cbf 147 _Unwind_Word args_size;
53d68b9f 148 char by_value[__LIBGCC_DWARF_FRAME_REGISTERS__+1];
52a11cbf
RH
149};
150
151/* Byte size of every register managed by these routines. */
53d68b9f 152static unsigned char dwarf_reg_size_table[__LIBGCC_DWARF_FRAME_REGISTERS__+1];
52a11cbf 153
52a11cbf 154\f
52a11cbf
RH
155/* Read unaligned data from the instruction buffer. */
156
157union unaligned
158{
159 void *p;
160 unsigned u2 __attribute__ ((mode (HI)));
161 unsigned u4 __attribute__ ((mode (SI)));
162 unsigned u8 __attribute__ ((mode (DI)));
163 signed s2 __attribute__ ((mode (HI)));
164 signed s4 __attribute__ ((mode (SI)));
165 signed s8 __attribute__ ((mode (DI)));
166} __attribute__ ((packed));
167
edbaf6a2
JDA
168static void uw_update_context (struct _Unwind_Context *, _Unwind_FrameState *);
169static _Unwind_Reason_Code uw_frame_state_for (struct _Unwind_Context *,
170 _Unwind_FrameState *);
171
52a11cbf 172static inline void *
e1f9550a 173read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
52a11cbf
RH
174
175static inline int
e9d1b155 176read_1u (const void *p) { return *(const unsigned char *) p; }
52a11cbf
RH
177
178static inline int
e9d1b155 179read_1s (const void *p) { return *(const signed char *) p; }
52a11cbf
RH
180
181static inline int
e1f9550a 182read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
52a11cbf
RH
183
184static inline int
e1f9550a 185read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
52a11cbf
RH
186
187static inline unsigned int
e1f9550a 188read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
52a11cbf
RH
189
190static inline int
e1f9550a 191read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
52a11cbf
RH
192
193static inline unsigned long
e1f9550a 194read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
52a11cbf
RH
195
196static inline unsigned long
e1f9550a 197read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
52a11cbf 198\f
f8e7718c
JJ
199static inline _Unwind_Word
200_Unwind_IsSignalFrame (struct _Unwind_Context *context)
201{
202 return (context->flags & SIGNAL_FRAME_BIT) ? 1 : 0;
203}
204
205static inline void
206_Unwind_SetSignalFrame (struct _Unwind_Context *context, int val)
207{
208 if (val)
209 context->flags |= SIGNAL_FRAME_BIT;
210 else
211 context->flags &= ~SIGNAL_FRAME_BIT;
212}
213
214static inline _Unwind_Word
215_Unwind_IsExtendedContext (struct _Unwind_Context *context)
216{
cca2207a
L
217 return (ASSUME_EXTENDED_UNWIND_CONTEXT
218 || (context->flags & EXTENDED_CONTEXT_BIT));
f8e7718c
JJ
219}
220\f
dbc3af4f 221/* Get the value of register REGNO as saved in CONTEXT. */
52a11cbf
RH
222
223inline _Unwind_Word
dbc3af4f 224_Unwind_GetGR (struct _Unwind_Context *context, int regno)
52a11cbf 225{
dbc3af4f 226 int size, index;
cca2207a 227 _Unwind_Context_Reg_Val val;
71628aa0 228
282efe1c 229#ifdef DWARF_ZERO_REG
fe95aee9 230 if (regno == DWARF_ZERO_REG)
282efe1c
RH
231 return 0;
232#endif
233
dbc3af4f 234 index = DWARF_REG_TO_UNWIND_COLUMN (regno);
79d0dfa3 235 gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
71628aa0 236 size = dwarf_reg_size_table[index];
cca2207a 237 val = context->reg[index];
71628aa0 238
f8e7718c 239 if (_Unwind_IsExtendedContext (context) && context->by_value[index])
cca2207a 240 return _Unwind_Get_Unwind_Word (val);
4469af7a 241
dbc3af4f
RS
242#ifdef DWARF_LAZY_REGISTER_VALUE
243 {
244 _Unwind_Word value;
245 if (DWARF_LAZY_REGISTER_VALUE (regno, &value))
246 return value;
247 }
248#endif
249
52a11cbf 250 /* This will segfault if the register hasn't been saved. */
71628aa0 251 if (size == sizeof(_Unwind_Ptr))
cca2207a 252 return * (_Unwind_Ptr *) (_Unwind_Internal_Ptr) val;
79d0dfa3
NS
253 else
254 {
255 gcc_assert (size == sizeof(_Unwind_Word));
cca2207a 256 return * (_Unwind_Word *) (_Unwind_Internal_Ptr) val;
79d0dfa3 257 }
71628aa0
R
258}
259
260static inline void *
261_Unwind_GetPtr (struct _Unwind_Context *context, int index)
262{
263 return (void *)(_Unwind_Ptr) _Unwind_GetGR (context, index);
52a11cbf
RH
264}
265
378683cf
RH
266/* Get the value of the CFA as saved in CONTEXT. */
267
268_Unwind_Word
269_Unwind_GetCFA (struct _Unwind_Context *context)
270{
9330e977 271 return (_Unwind_Ptr) context->cfa;
378683cf
RH
272}
273
4469af7a 274/* Overwrite the saved value for register INDEX in CONTEXT with VAL. */
52a11cbf
RH
275
276inline void
277_Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
278{
71628aa0
R
279 int size;
280 void *ptr;
281
41f3a930 282 index = DWARF_REG_TO_UNWIND_COLUMN (index);
79d0dfa3 283 gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
71628aa0 284 size = dwarf_reg_size_table[index];
4469af7a 285
f8e7718c 286 if (_Unwind_IsExtendedContext (context) && context->by_value[index])
4469af7a 287 {
cca2207a 288 context->reg[index] = _Unwind_Get_Unwind_Context_Reg_Val (val);
4469af7a
JJ
289 return;
290 }
291
cca2207a 292 ptr = (void *) (_Unwind_Internal_Ptr) context->reg[index];
71628aa0
R
293
294 if (size == sizeof(_Unwind_Ptr))
295 * (_Unwind_Ptr *) ptr = val;
71628aa0 296 else
79d0dfa3
NS
297 {
298 gcc_assert (size == sizeof(_Unwind_Word));
299 * (_Unwind_Word *) ptr = val;
300 }
52a11cbf
RH
301}
302
41f3a930
AH
303/* Get the pointer to a register INDEX as saved in CONTEXT. */
304
305static inline void *
306_Unwind_GetGRPtr (struct _Unwind_Context *context, int index)
307{
308 index = DWARF_REG_TO_UNWIND_COLUMN (index);
f8e7718c 309 if (_Unwind_IsExtendedContext (context) && context->by_value[index])
4469af7a 310 return &context->reg[index];
cca2207a 311 return (void *) (_Unwind_Internal_Ptr) context->reg[index];
41f3a930
AH
312}
313
314/* Set the pointer to a register INDEX as saved in CONTEXT. */
315
316static inline void
317_Unwind_SetGRPtr (struct _Unwind_Context *context, int index, void *p)
318{
319 index = DWARF_REG_TO_UNWIND_COLUMN (index);
f8e7718c
JJ
320 if (_Unwind_IsExtendedContext (context))
321 context->by_value[index] = 0;
cca2207a 322 context->reg[index] = (_Unwind_Context_Reg_Val) (_Unwind_Internal_Ptr) p;
41f3a930
AH
323}
324
4469af7a
JJ
325/* Overwrite the saved value for register INDEX in CONTEXT with VAL. */
326
327static inline void
328_Unwind_SetGRValue (struct _Unwind_Context *context, int index,
329 _Unwind_Word val)
330{
331 index = DWARF_REG_TO_UNWIND_COLUMN (index);
332 gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
f155bc64
L
333 /* Return column size may be smaller than _Unwind_Context_Reg_Val. */
334 gcc_assert (dwarf_reg_size_table[index] <= sizeof (_Unwind_Context_Reg_Val));
4469af7a
JJ
335
336 context->by_value[index] = 1;
cca2207a 337 context->reg[index] = _Unwind_Get_Unwind_Context_Reg_Val (val);
4469af7a
JJ
338}
339
c0220ea4 340/* Return nonzero if register INDEX is stored by value rather than
4469af7a
JJ
341 by reference. */
342
343static inline int
344_Unwind_GRByValue (struct _Unwind_Context *context, int index)
345{
346 index = DWARF_REG_TO_UNWIND_COLUMN (index);
347 return context->by_value[index];
348}
349
52a11cbf
RH
350/* Retrieve the return address for CONTEXT. */
351
352inline _Unwind_Ptr
353_Unwind_GetIP (struct _Unwind_Context *context)
354{
355 return (_Unwind_Ptr) context->ra;
356}
357
754e45a8
JJ
358/* Retrieve the return address and flag whether that IP is before
359 or after first not yet fully executed instruction. */
360
361inline _Unwind_Ptr
362_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
363{
f8e7718c 364 *ip_before_insn = _Unwind_IsSignalFrame (context);
754e45a8
JJ
365 return (_Unwind_Ptr) context->ra;
366}
367
52a11cbf
RH
368/* Overwrite the return address for CONTEXT with VAL. */
369
370inline void
371_Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
372{
373 context->ra = (void *) val;
374}
375
376void *
377_Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
378{
379 return context->lsda;
380}
381
382_Unwind_Ptr
383_Unwind_GetRegionStart (struct _Unwind_Context *context)
384{
385 return (_Unwind_Ptr) context->bases.func;
386}
387
5dafd282 388void *
5154b05d 389_Unwind_FindEnclosingFunction (void *pc)
5dafd282
AH
390{
391 struct dwarf_eh_bases bases;
f1518966 392 const struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases);
5dafd282
AH
393 if (fde)
394 return bases.func;
395 else
396 return NULL;
397}
398
2a1ee410
RH
399#ifndef __ia64__
400_Unwind_Ptr
401_Unwind_GetDataRelBase (struct _Unwind_Context *context)
402{
403 return (_Unwind_Ptr) context->bases.dbase;
404}
405
406_Unwind_Ptr
407_Unwind_GetTextRelBase (struct _Unwind_Context *context)
408{
409 return (_Unwind_Ptr) context->bases.tbase;
410}
411#endif
8662eb14 412
58cd1d70 413#include "md-unwind-support.h"
52a11cbf
RH
414\f
415/* Extract any interesting information from the CIE for the translation
416 unit F belongs to. Return a pointer to the byte after the augmentation,
417 or NULL if we encountered an undecipherable augmentation. */
418
e1f9550a 419static const unsigned char *
f1518966 420extract_cie_info (const struct dwarf_cie *cie, struct _Unwind_Context *context,
52a11cbf
RH
421 _Unwind_FrameState *fs)
422{
e1f9550a 423 const unsigned char *aug = cie->augmentation;
ca29916b 424 const unsigned char *p = aug + strlen ((const char *)aug) + 1;
e1f9550a 425 const unsigned char *ret = NULL;
f767122b
AK
426 _uleb128_t utmp;
427 _sleb128_t stmp;
52a11cbf 428
5442cf15
MK
429 /* g++ v2 "eh" has pointer immediately following augmentation string,
430 so it must be handled first. */
431 if (aug[0] == 'e' && aug[1] == 'h')
432 {
433 fs->eh_ptr = read_pointer (p);
434 p += sizeof (void *);
435 aug += 2;
436 }
437
8f65940d
JJ
438 /* After the augmentation resp. pointer for "eh" augmentation
439 follows for CIE version >= 4 address size byte and
440 segment size byte. */
441 if (__builtin_expect (cie->version >= 4, 0))
442 {
443 if (p[0] != sizeof (void *) || p[1] != 0)
444 return NULL;
445 p += 2;
446 }
447 /* Immediately following this are the code and
52a11cbf 448 data alignment and return address column. */
f767122b
AK
449 p = read_uleb128 (p, &utmp);
450 fs->code_align = (_Unwind_Word)utmp;
451 p = read_sleb128 (p, &stmp);
452 fs->data_align = (_Unwind_Sword)stmp;
0ef54a47
PB
453 if (cie->version == 1)
454 fs->retaddr_column = *p++;
455 else
f767122b
AK
456 {
457 p = read_uleb128 (p, &utmp);
458 fs->retaddr_column = (_Unwind_Word)utmp;
459 }
e1f9550a 460 fs->lsda_encoding = DW_EH_PE_omit;
52a11cbf
RH
461
462 /* If the augmentation starts with 'z', then a uleb128 immediately
463 follows containing the length of the augmentation field following
464 the size. */
465 if (*aug == 'z')
466 {
a9985a92
JM
467 p = read_uleb128 (p, &utmp);
468 ret = p + utmp;
52a11cbf
RH
469
470 fs->saw_z = 1;
471 ++aug;
472 }
473
474 /* Iterate over recognized augmentation subsequences. */
475 while (*aug != '\0')
476 {
e1f9550a 477 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
5442cf15 478 if (aug[0] == 'L')
e1f9550a
RH
479 {
480 fs->lsda_encoding = *p++;
481 aug += 1;
482 }
483
484 /* "R" indicates a byte indicating how FDE addresses are encoded. */
52a11cbf
RH
485 else if (aug[0] == 'R')
486 {
e1f9550a 487 fs->fde_encoding = *p++;
52a11cbf
RH
488 aug += 1;
489 }
490
e1f9550a 491 /* "P" indicates a personality routine in the CIE augmentation. */
52a11cbf
RH
492 else if (aug[0] == 'P')
493 {
950ccbc4 494 _Unwind_Ptr personality;
b8698a0f 495
950ccbc4
NS
496 p = read_encoded_value (context, *p, p + 1, &personality);
497 fs->personality = (_Unwind_Personality_Fn) personality;
52a11cbf
RH
498 aug += 1;
499 }
500
754e45a8
JJ
501 /* "S" indicates a signal frame. */
502 else if (aug[0] == 'S')
503 {
504 fs->signal_frame = 1;
505 aug += 1;
506 }
8fc16d72
ST
507 /* aarch64 B-key pointer authentication. */
508 else if (aug[0] == 'B')
509 {
510 aug += 1;
511 }
754e45a8 512
52a11cbf
RH
513 /* Otherwise we have an unknown augmentation string.
514 Bail unless we saw a 'z' prefix. */
515 else
516 return ret;
517 }
518
519 return ret ? ret : p;
520}
521
522
523/* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
524 onto the stack to start. */
525
526static _Unwind_Word
e1f9550a 527execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
52a11cbf
RH
528 struct _Unwind_Context *context, _Unwind_Word initial)
529{
2d76cb1a 530 _Unwind_Word stack[64]; /* ??? Assume this is enough. */
52a11cbf
RH
531 int stack_elt;
532
533 stack[0] = initial;
534 stack_elt = 1;
535
536 while (op_ptr < op_end)
537 {
538 enum dwarf_location_atom op = *op_ptr++;
f767122b
AK
539 _Unwind_Word result;
540 _uleb128_t reg, utmp;
541 _sleb128_t offset, stmp;
52a11cbf
RH
542
543 switch (op)
544 {
545 case DW_OP_lit0:
546 case DW_OP_lit1:
547 case DW_OP_lit2:
548 case DW_OP_lit3:
549 case DW_OP_lit4:
550 case DW_OP_lit5:
551 case DW_OP_lit6:
552 case DW_OP_lit7:
553 case DW_OP_lit8:
554 case DW_OP_lit9:
555 case DW_OP_lit10:
556 case DW_OP_lit11:
557 case DW_OP_lit12:
558 case DW_OP_lit13:
559 case DW_OP_lit14:
560 case DW_OP_lit15:
561 case DW_OP_lit16:
562 case DW_OP_lit17:
563 case DW_OP_lit18:
564 case DW_OP_lit19:
565 case DW_OP_lit20:
566 case DW_OP_lit21:
567 case DW_OP_lit22:
568 case DW_OP_lit23:
569 case DW_OP_lit24:
570 case DW_OP_lit25:
571 case DW_OP_lit26:
572 case DW_OP_lit27:
573 case DW_OP_lit28:
574 case DW_OP_lit29:
575 case DW_OP_lit30:
576 case DW_OP_lit31:
577 result = op - DW_OP_lit0;
578 break;
579
580 case DW_OP_addr:
581 result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
582 op_ptr += sizeof (void *);
583 break;
584
b5e9dce1
RH
585 case DW_OP_GNU_encoded_addr:
586 {
587 _Unwind_Ptr presult;
588 op_ptr = read_encoded_value (context, *op_ptr, op_ptr+1, &presult);
589 result = presult;
590 }
591 break;
592
52a11cbf
RH
593 case DW_OP_const1u:
594 result = read_1u (op_ptr);
595 op_ptr += 1;
596 break;
597 case DW_OP_const1s:
598 result = read_1s (op_ptr);
599 op_ptr += 1;
600 break;
601 case DW_OP_const2u:
602 result = read_2u (op_ptr);
603 op_ptr += 2;
604 break;
605 case DW_OP_const2s:
606 result = read_2s (op_ptr);
607 op_ptr += 2;
608 break;
609 case DW_OP_const4u:
610 result = read_4u (op_ptr);
611 op_ptr += 4;
612 break;
613 case DW_OP_const4s:
614 result = read_4s (op_ptr);
615 op_ptr += 4;
616 break;
617 case DW_OP_const8u:
618 result = read_8u (op_ptr);
619 op_ptr += 8;
620 break;
621 case DW_OP_const8s:
622 result = read_8s (op_ptr);
623 op_ptr += 8;
624 break;
625 case DW_OP_constu:
f767122b
AK
626 op_ptr = read_uleb128 (op_ptr, &utmp);
627 result = (_Unwind_Word)utmp;
52a11cbf
RH
628 break;
629 case DW_OP_consts:
a9985a92 630 op_ptr = read_sleb128 (op_ptr, &stmp);
f767122b 631 result = (_Unwind_Sword)stmp;
52a11cbf
RH
632 break;
633
634 case DW_OP_reg0:
635 case DW_OP_reg1:
636 case DW_OP_reg2:
637 case DW_OP_reg3:
638 case DW_OP_reg4:
639 case DW_OP_reg5:
640 case DW_OP_reg6:
641 case DW_OP_reg7:
642 case DW_OP_reg8:
643 case DW_OP_reg9:
644 case DW_OP_reg10:
645 case DW_OP_reg11:
646 case DW_OP_reg12:
647 case DW_OP_reg13:
648 case DW_OP_reg14:
649 case DW_OP_reg15:
650 case DW_OP_reg16:
651 case DW_OP_reg17:
652 case DW_OP_reg18:
653 case DW_OP_reg19:
654 case DW_OP_reg20:
655 case DW_OP_reg21:
656 case DW_OP_reg22:
657 case DW_OP_reg23:
658 case DW_OP_reg24:
659 case DW_OP_reg25:
660 case DW_OP_reg26:
661 case DW_OP_reg27:
662 case DW_OP_reg28:
663 case DW_OP_reg29:
664 case DW_OP_reg30:
665 case DW_OP_reg31:
666 result = _Unwind_GetGR (context, op - DW_OP_reg0);
667 break;
668 case DW_OP_regx:
a9985a92 669 op_ptr = read_uleb128 (op_ptr, &reg);
52a11cbf
RH
670 result = _Unwind_GetGR (context, reg);
671 break;
672
673 case DW_OP_breg0:
674 case DW_OP_breg1:
675 case DW_OP_breg2:
676 case DW_OP_breg3:
677 case DW_OP_breg4:
678 case DW_OP_breg5:
679 case DW_OP_breg6:
680 case DW_OP_breg7:
681 case DW_OP_breg8:
682 case DW_OP_breg9:
683 case DW_OP_breg10:
684 case DW_OP_breg11:
685 case DW_OP_breg12:
686 case DW_OP_breg13:
687 case DW_OP_breg14:
688 case DW_OP_breg15:
689 case DW_OP_breg16:
690 case DW_OP_breg17:
691 case DW_OP_breg18:
692 case DW_OP_breg19:
693 case DW_OP_breg20:
694 case DW_OP_breg21:
695 case DW_OP_breg22:
696 case DW_OP_breg23:
697 case DW_OP_breg24:
698 case DW_OP_breg25:
699 case DW_OP_breg26:
700 case DW_OP_breg27:
701 case DW_OP_breg28:
702 case DW_OP_breg29:
703 case DW_OP_breg30:
704 case DW_OP_breg31:
a9985a92 705 op_ptr = read_sleb128 (op_ptr, &offset);
52a11cbf
RH
706 result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
707 break;
708 case DW_OP_bregx:
a9985a92
JM
709 op_ptr = read_uleb128 (op_ptr, &reg);
710 op_ptr = read_sleb128 (op_ptr, &offset);
f767122b 711 result = _Unwind_GetGR (context, reg) + (_Unwind_Word)offset;
52a11cbf
RH
712 break;
713
714 case DW_OP_dup:
79d0dfa3 715 gcc_assert (stack_elt);
52a11cbf
RH
716 result = stack[stack_elt - 1];
717 break;
718
719 case DW_OP_drop:
79d0dfa3
NS
720 gcc_assert (stack_elt);
721 stack_elt -= 1;
52a11cbf
RH
722 goto no_push;
723
724 case DW_OP_pick:
725 offset = *op_ptr++;
79d0dfa3 726 gcc_assert (offset < stack_elt - 1);
52a11cbf
RH
727 result = stack[stack_elt - 1 - offset];
728 break;
729
730 case DW_OP_over:
79d0dfa3 731 gcc_assert (stack_elt >= 2);
52a11cbf
RH
732 result = stack[stack_elt - 2];
733 break;
734
9dc5c4f5
GK
735 case DW_OP_swap:
736 {
737 _Unwind_Word t;
738 gcc_assert (stack_elt >= 2);
739 t = stack[stack_elt - 1];
740 stack[stack_elt - 1] = stack[stack_elt - 2];
741 stack[stack_elt - 2] = t;
742 goto no_push;
743 }
744
52a11cbf
RH
745 case DW_OP_rot:
746 {
747 _Unwind_Word t1, t2, t3;
748
79d0dfa3 749 gcc_assert (stack_elt >= 3);
52a11cbf
RH
750 t1 = stack[stack_elt - 1];
751 t2 = stack[stack_elt - 2];
752 t3 = stack[stack_elt - 3];
753 stack[stack_elt - 1] = t2;
754 stack[stack_elt - 2] = t3;
755 stack[stack_elt - 3] = t1;
756 goto no_push;
757 }
758
759 case DW_OP_deref:
760 case DW_OP_deref_size:
761 case DW_OP_abs:
762 case DW_OP_neg:
763 case DW_OP_not:
764 case DW_OP_plus_uconst:
765 /* Unary operations. */
79d0dfa3
NS
766 gcc_assert (stack_elt);
767 stack_elt -= 1;
b8698a0f 768
52a11cbf
RH
769 result = stack[stack_elt];
770
771 switch (op)
772 {
773 case DW_OP_deref:
774 {
a01da83b 775 void *ptr = (void *) (_Unwind_Ptr) result;
52a11cbf
RH
776 result = (_Unwind_Ptr) read_pointer (ptr);
777 }
778 break;
779
780 case DW_OP_deref_size:
781 {
a01da83b 782 void *ptr = (void *) (_Unwind_Ptr) result;
52a11cbf
RH
783 switch (*op_ptr++)
784 {
785 case 1:
786 result = read_1u (ptr);
787 break;
788 case 2:
789 result = read_2u (ptr);
790 break;
791 case 4:
792 result = read_4u (ptr);
793 break;
794 case 8:
795 result = read_8u (ptr);
796 break;
797 default:
79d0dfa3 798 gcc_unreachable ();
52a11cbf
RH
799 }
800 }
801 break;
802
803 case DW_OP_abs:
804 if ((_Unwind_Sword) result < 0)
805 result = -result;
806 break;
807 case DW_OP_neg:
808 result = -result;
809 break;
810 case DW_OP_not:
811 result = ~result;
812 break;
813 case DW_OP_plus_uconst:
a9985a92 814 op_ptr = read_uleb128 (op_ptr, &utmp);
f767122b 815 result += (_Unwind_Word)utmp;
52a11cbf 816 break;
5ed3149c
ZW
817
818 default:
79d0dfa3 819 gcc_unreachable ();
52a11cbf
RH
820 }
821 break;
822
823 case DW_OP_and:
824 case DW_OP_div:
825 case DW_OP_minus:
826 case DW_OP_mod:
827 case DW_OP_mul:
828 case DW_OP_or:
829 case DW_OP_plus:
7a706738
AM
830 case DW_OP_shl:
831 case DW_OP_shr:
832 case DW_OP_shra:
833 case DW_OP_xor:
52a11cbf
RH
834 case DW_OP_le:
835 case DW_OP_ge:
836 case DW_OP_eq:
837 case DW_OP_lt:
838 case DW_OP_gt:
839 case DW_OP_ne:
840 {
841 /* Binary operations. */
842 _Unwind_Word first, second;
79d0dfa3
NS
843 gcc_assert (stack_elt >= 2);
844 stack_elt -= 2;
b8698a0f 845
41077ce4
KH
846 second = stack[stack_elt];
847 first = stack[stack_elt + 1];
848
849 switch (op)
850 {
851 case DW_OP_and:
852 result = second & first;
853 break;
854 case DW_OP_div:
855 result = (_Unwind_Sword) second / (_Unwind_Sword) first;
856 break;
857 case DW_OP_minus:
858 result = second - first;
859 break;
860 case DW_OP_mod:
80c35b40 861 result = second % first;
41077ce4
KH
862 break;
863 case DW_OP_mul:
864 result = second * first;
865 break;
866 case DW_OP_or:
867 result = second | first;
868 break;
869 case DW_OP_plus:
870 result = second + first;
871 break;
872 case DW_OP_shl:
873 result = second << first;
874 break;
875 case DW_OP_shr:
876 result = second >> first;
877 break;
878 case DW_OP_shra:
879 result = (_Unwind_Sword) second >> first;
880 break;
881 case DW_OP_xor:
882 result = second ^ first;
883 break;
884 case DW_OP_le:
4793ad6b 885 result = (_Unwind_Sword) second <= (_Unwind_Sword) first;
41077ce4
KH
886 break;
887 case DW_OP_ge:
4793ad6b 888 result = (_Unwind_Sword) second >= (_Unwind_Sword) first;
41077ce4
KH
889 break;
890 case DW_OP_eq:
4793ad6b 891 result = (_Unwind_Sword) second == (_Unwind_Sword) first;
41077ce4
KH
892 break;
893 case DW_OP_lt:
4793ad6b 894 result = (_Unwind_Sword) second < (_Unwind_Sword) first;
41077ce4
KH
895 break;
896 case DW_OP_gt:
4793ad6b 897 result = (_Unwind_Sword) second > (_Unwind_Sword) first;
41077ce4
KH
898 break;
899 case DW_OP_ne:
4793ad6b 900 result = (_Unwind_Sword) second != (_Unwind_Sword) first;
41077ce4
KH
901 break;
902
903 default:
79d0dfa3 904 gcc_unreachable ();
41077ce4 905 }
52a11cbf
RH
906 }
907 break;
908
909 case DW_OP_skip:
910 offset = read_2s (op_ptr);
911 op_ptr += 2;
912 op_ptr += offset;
913 goto no_push;
914
915 case DW_OP_bra:
79d0dfa3
NS
916 gcc_assert (stack_elt);
917 stack_elt -= 1;
b8698a0f 918
52a11cbf
RH
919 offset = read_2s (op_ptr);
920 op_ptr += 2;
921 if (stack[stack_elt] != 0)
922 op_ptr += offset;
923 goto no_push;
924
925 case DW_OP_nop:
926 goto no_push;
927
928 default:
79d0dfa3 929 gcc_unreachable ();
52a11cbf
RH
930 }
931
932 /* Most things push a result value. */
79d0dfa3 933 gcc_assert ((size_t) stack_elt < sizeof(stack)/sizeof(*stack));
9c80ff25 934 stack[stack_elt++] = result;
52a11cbf
RH
935 no_push:;
936 }
937
938 /* We were executing this program to get a value. It should be
939 at top of stack. */
79d0dfa3
NS
940 gcc_assert (stack_elt);
941 stack_elt -= 1;
52a11cbf
RH
942 return stack[stack_elt];
943}
944
945
946/* Decode DWARF 2 call frame information. Takes pointers the
947 instruction sequence to decode, current register information and
948 CIE info, and the PC range to evaluate. */
949
950static void
e1f9550a
RH
951execute_cfa_program (const unsigned char *insn_ptr,
952 const unsigned char *insn_end,
953 struct _Unwind_Context *context,
954 _Unwind_FrameState *fs)
52a11cbf
RH
955{
956 struct frame_state_reg_info *unused_rs = NULL;
957
958 /* Don't allow remember/restore between CIE and FDE programs. */
959 fs->regs.prev = NULL;
960
7d8ac293
JM
961 /* The comparison with the return address uses < rather than <= because
962 we are only interested in the effects of code before the call; for a
963 noreturn function, the return address may point to unrelated code with
964 a different stack configuration that we are not interested in. We
965 assume that the call itself is unwind info-neutral; if not, or if
966 there are delay instructions that adjust the stack, these must be
754e45a8
JJ
967 reflected at the point immediately before the call insn.
968 In signal frames, return address is after last completed instruction,
969 so we add 1 to return address to make the comparison <=. */
f8e7718c
JJ
970 while (insn_ptr < insn_end
971 && fs->pc < context->ra + _Unwind_IsSignalFrame (context))
52a11cbf
RH
972 {
973 unsigned char insn = *insn_ptr++;
f767122b
AK
974 _uleb128_t reg, utmp;
975 _sleb128_t offset, stmp;
52a11cbf 976
f0451e26 977 if ((insn & 0xc0) == DW_CFA_advance_loc)
52a11cbf 978 fs->pc += (insn & 0x3f) * fs->code_align;
f0451e26 979 else if ((insn & 0xc0) == DW_CFA_offset)
52a11cbf
RH
980 {
981 reg = insn & 0x3f;
a9985a92 982 insn_ptr = read_uleb128 (insn_ptr, &utmp);
e9d1b155 983 offset = (_Unwind_Sword) utmp * fs->data_align;
0ec33224
RH
984 reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
985 if (UNWIND_COLUMN_IN_RANGE (reg))
986 {
146e4591 987 fs->regs.how[reg] = REG_SAVED_OFFSET;
0ec33224
RH
988 fs->regs.reg[reg].loc.offset = offset;
989 }
52a11cbf 990 }
f0451e26 991 else if ((insn & 0xc0) == DW_CFA_restore)
52a11cbf
RH
992 {
993 reg = insn & 0x3f;
0ec33224
RH
994 reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
995 if (UNWIND_COLUMN_IN_RANGE (reg))
146e4591 996 fs->regs.how[reg] = REG_UNSAVED;
52a11cbf
RH
997 }
998 else switch (insn)
999 {
1000 case DW_CFA_set_loc:
950ccbc4
NS
1001 {
1002 _Unwind_Ptr pc;
b8698a0f 1003
950ccbc4
NS
1004 insn_ptr = read_encoded_value (context, fs->fde_encoding,
1005 insn_ptr, &pc);
1006 fs->pc = (void *) pc;
1007 }
52a11cbf
RH
1008 break;
1009
1010 case DW_CFA_advance_loc1:
9e800206 1011 fs->pc += read_1u (insn_ptr) * fs->code_align;
52a11cbf
RH
1012 insn_ptr += 1;
1013 break;
1014 case DW_CFA_advance_loc2:
9e800206 1015 fs->pc += read_2u (insn_ptr) * fs->code_align;
52a11cbf
RH
1016 insn_ptr += 2;
1017 break;
1018 case DW_CFA_advance_loc4:
9e800206 1019 fs->pc += read_4u (insn_ptr) * fs->code_align;
52a11cbf
RH
1020 insn_ptr += 4;
1021 break;
1022
1023 case DW_CFA_offset_extended:
a9985a92
JM
1024 insn_ptr = read_uleb128 (insn_ptr, &reg);
1025 insn_ptr = read_uleb128 (insn_ptr, &utmp);
e9d1b155 1026 offset = (_Unwind_Sword) utmp * fs->data_align;
0ec33224
RH
1027 reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1028 if (UNWIND_COLUMN_IN_RANGE (reg))
1029 {
146e4591 1030 fs->regs.how[reg] = REG_SAVED_OFFSET;
0ec33224
RH
1031 fs->regs.reg[reg].loc.offset = offset;
1032 }
52a11cbf
RH
1033 break;
1034
1035 case DW_CFA_restore_extended:
a9985a92 1036 insn_ptr = read_uleb128 (insn_ptr, &reg);
f8a57be8
GK
1037 /* FIXME, this is wrong; the CIE might have said that the
1038 register was saved somewhere. */
0ec33224
RH
1039 reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1040 if (UNWIND_COLUMN_IN_RANGE (reg))
146e4591 1041 fs->regs.how[reg] = REG_UNSAVED;
52a11cbf
RH
1042 break;
1043
52a11cbf 1044 case DW_CFA_same_value:
cb25b0ce 1045 insn_ptr = read_uleb128 (insn_ptr, &reg);
0ec33224
RH
1046 reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1047 if (UNWIND_COLUMN_IN_RANGE (reg))
146e4591 1048 fs->regs.how[reg] = REG_UNSAVED;
cb25b0ce
BK
1049 break;
1050
54f5943c
JJ
1051 case DW_CFA_undefined:
1052 insn_ptr = read_uleb128 (insn_ptr, &reg);
0ec33224
RH
1053 reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1054 if (UNWIND_COLUMN_IN_RANGE (reg))
146e4591 1055 fs->regs.how[reg] = REG_UNDEFINED;
54f5943c
JJ
1056 break;
1057
52a11cbf
RH
1058 case DW_CFA_nop:
1059 break;
1060
1061 case DW_CFA_register:
1062 {
f767122b 1063 _uleb128_t reg2;
a9985a92
JM
1064 insn_ptr = read_uleb128 (insn_ptr, &reg);
1065 insn_ptr = read_uleb128 (insn_ptr, &reg2);
0ec33224
RH
1066 reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1067 if (UNWIND_COLUMN_IN_RANGE (reg))
1068 {
146e4591 1069 fs->regs.how[reg] = REG_SAVED_REG;
0ec33224
RH
1070 fs->regs.reg[reg].loc.reg = (_Unwind_Word)reg2;
1071 }
52a11cbf
RH
1072 }
1073 break;
41077ce4 1074
52a11cbf
RH
1075 case DW_CFA_remember_state:
1076 {
1077 struct frame_state_reg_info *new_rs;
1078 if (unused_rs)
1079 {
1080 new_rs = unused_rs;
1081 unused_rs = unused_rs->prev;
1082 }
1083 else
2c82eecc 1084 new_rs = alloca (sizeof (struct frame_state_reg_info));
52a11cbf
RH
1085
1086 *new_rs = fs->regs;
1087 fs->regs.prev = new_rs;
1088 }
1089 break;
1090
1091 case DW_CFA_restore_state:
1092 {
1093 struct frame_state_reg_info *old_rs = fs->regs.prev;
1094 fs->regs = *old_rs;
1095 old_rs->prev = unused_rs;
1096 unused_rs = old_rs;
1097 }
1098 break;
1099
1100 case DW_CFA_def_cfa:
a9985a92 1101 insn_ptr = read_uleb128 (insn_ptr, &utmp);
f767122b
AK
1102 fs->regs.cfa_reg = (_Unwind_Word)utmp;
1103 insn_ptr = read_uleb128 (insn_ptr, &utmp);
1104 fs->regs.cfa_offset = (_Unwind_Word)utmp;
6673f90b 1105 fs->regs.cfa_how = CFA_REG_OFFSET;
52a11cbf
RH
1106 break;
1107
1108 case DW_CFA_def_cfa_register:
f767122b
AK
1109 insn_ptr = read_uleb128 (insn_ptr, &utmp);
1110 fs->regs.cfa_reg = (_Unwind_Word)utmp;
6673f90b 1111 fs->regs.cfa_how = CFA_REG_OFFSET;
52a11cbf
RH
1112 break;
1113
1114 case DW_CFA_def_cfa_offset:
a9985a92 1115 insn_ptr = read_uleb128 (insn_ptr, &utmp);
6673f90b 1116 fs->regs.cfa_offset = utmp;
52a11cbf
RH
1117 /* cfa_how deliberately not set. */
1118 break;
1119
1120 case DW_CFA_def_cfa_expression:
6673f90b
NF
1121 fs->regs.cfa_exp = insn_ptr;
1122 fs->regs.cfa_how = CFA_EXP;
9c80ff25 1123 insn_ptr = read_uleb128 (insn_ptr, &utmp);
a9985a92 1124 insn_ptr += utmp;
52a11cbf
RH
1125 break;
1126
1127 case DW_CFA_expression:
a9985a92 1128 insn_ptr = read_uleb128 (insn_ptr, &reg);
0ec33224
RH
1129 reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1130 if (UNWIND_COLUMN_IN_RANGE (reg))
1131 {
146e4591 1132 fs->regs.how[reg] = REG_SAVED_EXP;
0ec33224
RH
1133 fs->regs.reg[reg].loc.exp = insn_ptr;
1134 }
9c80ff25 1135 insn_ptr = read_uleb128 (insn_ptr, &utmp);
a9985a92 1136 insn_ptr += utmp;
52a11cbf
RH
1137 break;
1138
4469af7a 1139 /* Dwarf3. */
52a11cbf 1140 case DW_CFA_offset_extended_sf:
a9985a92
JM
1141 insn_ptr = read_uleb128 (insn_ptr, &reg);
1142 insn_ptr = read_sleb128 (insn_ptr, &stmp);
1143 offset = stmp * fs->data_align;
0ec33224
RH
1144 reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1145 if (UNWIND_COLUMN_IN_RANGE (reg))
1146 {
146e4591 1147 fs->regs.how[reg] = REG_SAVED_OFFSET;
0ec33224
RH
1148 fs->regs.reg[reg].loc.offset = offset;
1149 }
52a11cbf 1150 break;
41077ce4 1151
52a11cbf 1152 case DW_CFA_def_cfa_sf:
f767122b
AK
1153 insn_ptr = read_uleb128 (insn_ptr, &utmp);
1154 fs->regs.cfa_reg = (_Unwind_Word)utmp;
1155 insn_ptr = read_sleb128 (insn_ptr, &stmp);
1156 fs->regs.cfa_offset = (_Unwind_Sword)stmp;
6673f90b
NF
1157 fs->regs.cfa_how = CFA_REG_OFFSET;
1158 fs->regs.cfa_offset *= fs->data_align;
52a11cbf
RH
1159 break;
1160
1161 case DW_CFA_def_cfa_offset_sf:
f767122b
AK
1162 insn_ptr = read_sleb128 (insn_ptr, &stmp);
1163 fs->regs.cfa_offset = (_Unwind_Sword)stmp;
6673f90b 1164 fs->regs.cfa_offset *= fs->data_align;
52a11cbf
RH
1165 /* cfa_how deliberately not set. */
1166 break;
1167
4469af7a
JJ
1168 case DW_CFA_val_offset:
1169 insn_ptr = read_uleb128 (insn_ptr, &reg);
1170 insn_ptr = read_uleb128 (insn_ptr, &utmp);
1171 offset = (_Unwind_Sword) utmp * fs->data_align;
0ec33224
RH
1172 reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1173 if (UNWIND_COLUMN_IN_RANGE (reg))
1174 {
146e4591 1175 fs->regs.how[reg] = REG_SAVED_VAL_OFFSET;
0ec33224
RH
1176 fs->regs.reg[reg].loc.offset = offset;
1177 }
4469af7a
JJ
1178 break;
1179
1180 case DW_CFA_val_offset_sf:
1181 insn_ptr = read_uleb128 (insn_ptr, &reg);
1182 insn_ptr = read_sleb128 (insn_ptr, &stmp);
1183 offset = stmp * fs->data_align;
0ec33224
RH
1184 reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1185 if (UNWIND_COLUMN_IN_RANGE (reg))
1186 {
146e4591 1187 fs->regs.how[reg] = REG_SAVED_VAL_OFFSET;
0ec33224
RH
1188 fs->regs.reg[reg].loc.offset = offset;
1189 }
4469af7a
JJ
1190 break;
1191
1192 case DW_CFA_val_expression:
1193 insn_ptr = read_uleb128 (insn_ptr, &reg);
0ec33224
RH
1194 reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1195 if (UNWIND_COLUMN_IN_RANGE (reg))
1196 {
146e4591 1197 fs->regs.how[reg] = REG_SAVED_VAL_EXP;
0ec33224
RH
1198 fs->regs.reg[reg].loc.exp = insn_ptr;
1199 }
4469af7a
JJ
1200 insn_ptr = read_uleb128 (insn_ptr, &utmp);
1201 insn_ptr += utmp;
1202 break;
1203
52a11cbf 1204 case DW_CFA_GNU_window_save:
a876231c 1205#if defined (__aarch64__) && !defined (__ILP32__)
5636faf2
JW
1206 /* This CFA is multiplexed with Sparc. On AArch64 it's used to toggle
1207 return address signing status. */
0d344b55 1208 reg = DWARF_REGNUM_AARCH64_RA_STATE;
146e4591 1209 gcc_assert (fs->regs.how[reg] == REG_UNSAVED);
0d344b55 1210 fs->regs.reg[reg].loc.offset ^= 1;
5636faf2 1211#else
52a11cbf 1212 /* ??? Hardcoded for SPARC register window configuration. */
53d68b9f 1213 if (__LIBGCC_DWARF_FRAME_REGISTERS__ >= 32)
fbd28bc3
JJ
1214 for (reg = 16; reg < 32; ++reg)
1215 {
146e4591 1216 fs->regs.how[reg] = REG_SAVED_OFFSET;
fbd28bc3
JJ
1217 fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
1218 }
5636faf2 1219#endif
52a11cbf
RH
1220 break;
1221
1222 case DW_CFA_GNU_args_size:
f767122b
AK
1223 insn_ptr = read_uleb128 (insn_ptr, &utmp);
1224 context->args_size = (_Unwind_Word)utmp;
52a11cbf
RH
1225 break;
1226
1227 case DW_CFA_GNU_negative_offset_extended:
1228 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
1229 older PowerPC code. */
a9985a92
JM
1230 insn_ptr = read_uleb128 (insn_ptr, &reg);
1231 insn_ptr = read_uleb128 (insn_ptr, &utmp);
e9d1b155 1232 offset = (_Unwind_Word) utmp * fs->data_align;
0ec33224
RH
1233 reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1234 if (UNWIND_COLUMN_IN_RANGE (reg))
1235 {
146e4591 1236 fs->regs.how[reg] = REG_SAVED_OFFSET;
0ec33224
RH
1237 fs->regs.reg[reg].loc.offset = -offset;
1238 }
52a11cbf
RH
1239 break;
1240
1241 default:
79d0dfa3 1242 gcc_unreachable ();
52a11cbf
RH
1243 }
1244 }
1245}
1246\f
81a60e6c
JM
1247/* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
1248 its caller and decode it into FS. This function also sets the
1249 args_size and lsda members of CONTEXT, as they are really information
1250 about the caller's frame. */
1251
52a11cbf
RH
1252static _Unwind_Reason_Code
1253uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1254{
f1518966
AJ
1255 const struct dwarf_fde *fde;
1256 const struct dwarf_cie *cie;
e1f9550a 1257 const unsigned char *aug, *insn, *end;
52a11cbf 1258
146e4591
JJ
1259 memset (&fs->regs.how[0], 0,
1260 sizeof (*fs) - offsetof (_Unwind_FrameState, regs.how[0]));
52a11cbf
RH
1261 context->args_size = 0;
1262 context->lsda = 0;
1263
ed80cd68
RH
1264 if (context->ra == 0)
1265 return _URC_END_OF_STACK;
1266
f8e7718c 1267 fde = _Unwind_Find_FDE (context->ra + _Unwind_IsSignalFrame (context) - 1,
754e45a8 1268 &context->bases);
52a11cbf
RH
1269 if (fde == NULL)
1270 {
8662eb14 1271#ifdef MD_FALLBACK_FRAME_STATE_FOR
52a11cbf
RH
1272 /* Couldn't find frame unwind info for this function. Try a
1273 target-specific fallback mechanism. This will necessarily
e3aafbad 1274 not provide a personality routine or LSDA. */
8662eb14 1275 return MD_FALLBACK_FRAME_STATE_FOR (context, fs);
52a11cbf
RH
1276#else
1277 return _URC_END_OF_STACK;
1278#endif
1279 }
1280
e1f9550a 1281 fs->pc = context->bases.func;
52a11cbf
RH
1282
1283 cie = get_cie (fde);
1284 insn = extract_cie_info (cie, context, fs);
1285 if (insn == NULL)
1286 /* CIE contained unknown augmentation. */
1287 return _URC_FATAL_PHASE1_ERROR;
1288
1289 /* First decode all the insns in the CIE. */
5f754896 1290 end = (const unsigned char *) next_fde ((const struct dwarf_fde *) cie);
52a11cbf
RH
1291 execute_cfa_program (insn, end, context, fs);
1292
1293 /* Locate augmentation for the fde. */
5f754896 1294 aug = (const unsigned char *) fde + sizeof (*fde);
e1f9550a 1295 aug += 2 * size_of_encoded_value (fs->fde_encoding);
52a11cbf
RH
1296 insn = NULL;
1297 if (fs->saw_z)
1298 {
f767122b 1299 _uleb128_t i;
52a11cbf
RH
1300 aug = read_uleb128 (aug, &i);
1301 insn = aug + i;
1302 }
e1f9550a 1303 if (fs->lsda_encoding != DW_EH_PE_omit)
950ccbc4
NS
1304 {
1305 _Unwind_Ptr lsda;
b8698a0f 1306
950ccbc4
NS
1307 aug = read_encoded_value (context, fs->lsda_encoding, aug, &lsda);
1308 context->lsda = (void *) lsda;
1309 }
52a11cbf
RH
1310
1311 /* Then the insns in the FDE up to our target PC. */
1312 if (insn == NULL)
1313 insn = aug;
5f754896 1314 end = (const unsigned char *) next_fde (fde);
52a11cbf
RH
1315 execute_cfa_program (insn, end, context, fs);
1316
1317 return _URC_NO_REASON;
1318}
5442cf15
MK
1319\f
1320typedef struct frame_state
1321{
1322 void *cfa;
1323 void *eh_ptr;
1324 long cfa_offset;
1325 long args_size;
919543ab 1326 long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
5442cf15
MK
1327 unsigned short cfa_reg;
1328 unsigned short retaddr_column;
919543ab 1329 char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
5442cf15
MK
1330} frame_state;
1331
1332struct frame_state * __frame_state_for (void *, struct frame_state *);
1333
1334/* Called from pre-G++ 3.0 __throw to find the registers to restore for
1335 a given PC_TARGET. The caller should allocate a local variable of
1336 `struct frame_state' and pass its address to STATE_IN. */
1337
1338struct frame_state *
1339__frame_state_for (void *pc_target, struct frame_state *state_in)
1340{
1341 struct _Unwind_Context context;
1342 _Unwind_FrameState fs;
1343 int reg;
1344
1345 memset (&context, 0, sizeof (struct _Unwind_Context));
cca2207a
L
1346 if (!ASSUME_EXTENDED_UNWIND_CONTEXT)
1347 context.flags = EXTENDED_CONTEXT_BIT;
5442cf15
MK
1348 context.ra = pc_target + 1;
1349
1350 if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
1351 return 0;
52a11cbf 1352
5442cf15
MK
1353 /* We have no way to pass a location expression for the CFA to our
1354 caller. It wouldn't understand it anyway. */
6673f90b 1355 if (fs.regs.cfa_how == CFA_EXP)
5442cf15 1356 return 0;
52a11cbf 1357
919543ab 1358 for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
5442cf15 1359 {
146e4591 1360 state_in->saved[reg] = fs.regs.how[reg];
5442cf15
MK
1361 switch (state_in->saved[reg])
1362 {
1363 case REG_SAVED_REG:
1364 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
1365 break;
1366 case REG_SAVED_OFFSET:
1367 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
1368 break;
1369 default:
1370 state_in->reg_or_offset[reg] = 0;
1371 break;
1372 }
1373 }
1374
6673f90b
NF
1375 state_in->cfa_offset = fs.regs.cfa_offset;
1376 state_in->cfa_reg = fs.regs.cfa_reg;
5442cf15
MK
1377 state_in->retaddr_column = fs.retaddr_column;
1378 state_in->args_size = context.args_size;
1379 state_in->eh_ptr = fs.eh_ptr;
1380
1381 return state_in;
1382}
1383\f
71628aa0
R
1384typedef union { _Unwind_Ptr ptr; _Unwind_Word word; } _Unwind_SpTmp;
1385
1386static inline void
1387_Unwind_SetSpColumn (struct _Unwind_Context *context, void *cfa,
4469af7a 1388 _Unwind_SpTmp *tmp_sp)
71628aa0
R
1389{
1390 int size = dwarf_reg_size_table[__builtin_dwarf_sp_column ()];
b8698a0f 1391
71628aa0
R
1392 if (size == sizeof(_Unwind_Ptr))
1393 tmp_sp->ptr = (_Unwind_Ptr) cfa;
71628aa0 1394 else
79d0dfa3
NS
1395 {
1396 gcc_assert (size == sizeof(_Unwind_Word));
1397 tmp_sp->word = (_Unwind_Ptr) cfa;
1398 }
71628aa0
R
1399 _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), tmp_sp);
1400}
1401
52a11cbf
RH
1402static void
1403uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1404{
1405 struct _Unwind_Context orig_context = *context;
1406 void *cfa;
1407 long i;
1408
53d68b9f 1409#ifdef __LIBGCC_EH_RETURN_STACKADJ_RTX__
9c80ff25
RH
1410 /* Special handling here: Many machines do not use a frame pointer,
1411 and track the CFA only through offsets from the stack pointer from
1412 one frame to the next. In this case, the stack pointer is never
1413 stored, so it has no saved address in the context. What we do
1414 have is the CFA from the previous stack frame.
1415
1416 In very special situations (such as unwind info for signal return),
1417 there may be location expressions that use the stack pointer as well.
1418
8b689196
RH
1419 Do this conditionally for one frame. This allows the unwind info
1420 for one frame to save a copy of the stack pointer from the previous
1421 frame, and be able to use much easier CFA mechanisms to do it.
1422 Always zap the saved stack pointer value for the next frame; carrying
1423 the value over from one frame to another doesn't make sense. */
34dc173c 1424
71628aa0 1425 _Unwind_SpTmp tmp_sp;
34dc173c 1426
8b689196 1427 if (!_Unwind_GetGRPtr (&orig_context, __builtin_dwarf_sp_column ()))
71628aa0 1428 _Unwind_SetSpColumn (&orig_context, context->cfa, &tmp_sp);
8b689196 1429 _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), NULL);
34dc173c 1430#endif
9c80ff25 1431
52a11cbf 1432 /* Compute this frame's CFA. */
6673f90b 1433 switch (fs->regs.cfa_how)
52a11cbf
RH
1434 {
1435 case CFA_REG_OFFSET:
6673f90b
NF
1436 cfa = _Unwind_GetPtr (&orig_context, fs->regs.cfa_reg);
1437 cfa += fs->regs.cfa_offset;
52a11cbf
RH
1438 break;
1439
1440 case CFA_EXP:
52a11cbf 1441 {
6673f90b 1442 const unsigned char *exp = fs->regs.cfa_exp;
f767122b 1443 _uleb128_t len;
52a11cbf
RH
1444
1445 exp = read_uleb128 (exp, &len);
1446 cfa = (void *) (_Unwind_Ptr)
9c80ff25 1447 execute_stack_op (exp, exp + len, &orig_context, 0);
52a11cbf
RH
1448 break;
1449 }
1450
1451 default:
79d0dfa3 1452 gcc_unreachable ();
52a11cbf
RH
1453 }
1454 context->cfa = cfa;
1455
1456 /* Compute the addresses of all registers saved in this frame. */
53d68b9f 1457 for (i = 0; i < __LIBGCC_DWARF_FRAME_REGISTERS__ + 1; ++i)
146e4591 1458 switch (fs->regs.how[i])
52a11cbf
RH
1459 {
1460 case REG_UNSAVED:
54f5943c 1461 case REG_UNDEFINED:
52a11cbf 1462 break;
9c80ff25 1463
52a11cbf 1464 case REG_SAVED_OFFSET:
9c80ff25
RH
1465 _Unwind_SetGRPtr (context, i,
1466 (void *) (cfa + fs->regs.reg[i].loc.offset));
52a11cbf 1467 break;
9c80ff25 1468
52a11cbf 1469 case REG_SAVED_REG:
4469af7a
JJ
1470 if (_Unwind_GRByValue (&orig_context, fs->regs.reg[i].loc.reg))
1471 _Unwind_SetGRValue (context, i,
1472 _Unwind_GetGR (&orig_context,
1473 fs->regs.reg[i].loc.reg));
1474 else
1475 _Unwind_SetGRPtr (context, i,
1476 _Unwind_GetGRPtr (&orig_context,
1477 fs->regs.reg[i].loc.reg));
52a11cbf 1478 break;
9c80ff25 1479
52a11cbf
RH
1480 case REG_SAVED_EXP:
1481 {
e1f9550a 1482 const unsigned char *exp = fs->regs.reg[i].loc.exp;
f767122b 1483 _uleb128_t len;
52a11cbf
RH
1484 _Unwind_Ptr val;
1485
1486 exp = read_uleb128 (exp, &len);
1487 val = execute_stack_op (exp, exp + len, &orig_context,
1488 (_Unwind_Ptr) cfa);
41f3a930 1489 _Unwind_SetGRPtr (context, i, (void *) val);
52a11cbf
RH
1490 }
1491 break;
4469af7a
JJ
1492
1493 case REG_SAVED_VAL_OFFSET:
1494 _Unwind_SetGRValue (context, i,
1495 (_Unwind_Internal_Ptr)
1496 (cfa + fs->regs.reg[i].loc.offset));
1497 break;
1498
1499 case REG_SAVED_VAL_EXP:
1500 {
1501 const unsigned char *exp = fs->regs.reg[i].loc.exp;
f767122b 1502 _uleb128_t len;
4469af7a
JJ
1503 _Unwind_Ptr val;
1504
1505 exp = read_uleb128 (exp, &len);
1506 val = execute_stack_op (exp, exp + len, &orig_context,
1507 (_Unwind_Ptr) cfa);
1508 _Unwind_SetGRValue (context, i, val);
1509 }
1510 break;
52a11cbf 1511 }
fc4767bb 1512
f8e7718c 1513 _Unwind_SetSignalFrame (context, fs->signal_frame);
754e45a8 1514
8662eb14 1515#ifdef MD_FROB_UPDATE_CONTEXT
fc4767bb 1516 MD_FROB_UPDATE_CONTEXT (context, fs);
8662eb14 1517#endif
52a11cbf
RH
1518}
1519
81a60e6c
JM
1520/* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1521 of its caller. Update CONTEXT to refer to the caller as well. Note
1522 that the args_size and lsda members are not updated here, but later in
1523 uw_frame_state_for. */
1524
52a11cbf
RH
1525static void
1526uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1527{
1528 uw_update_context_1 (context, fs);
1529
54f5943c
JJ
1530 /* In general this unwinder doesn't make any distinction between
1531 undefined and same_value rule. Call-saved registers are assumed
1532 to have same_value rule by default and explicit undefined
1533 rule is handled like same_value. The only exception is
1534 DW_CFA_undefined on retaddr_column which is supposed to
1535 mark outermost frame in DWARF 3. */
146e4591 1536 if (fs->regs.how[DWARF_REG_TO_UNWIND_COLUMN (fs->retaddr_column)]
54f5943c
JJ
1537 == REG_UNDEFINED)
1538 /* uw_frame_state_for uses context->ra == 0 check to find outermost
1539 stack frame. */
1540 context->ra = 0;
1541 else
5636faf2
JW
1542 {
1543 /* Compute the return address now, since the return address column
1544 can change from frame to frame. */
b097c7a2
SN
1545 void *ret_addr;
1546#ifdef MD_DEMANGLE_RETURN_ADDR
1547 _Unwind_Word ra = _Unwind_GetGR (context, fs->retaddr_column);
1548 ret_addr = MD_DEMANGLE_RETURN_ADDR (context, fs, ra);
1549#else
1550 ret_addr = _Unwind_GetPtr (context, fs->retaddr_column);
5636faf2 1551#endif
b097c7a2 1552 context->ra = __builtin_extract_return_addr (ret_addr);
5636faf2 1553 }
52a11cbf 1554}
60aef23e
DJ
1555
1556static void
1557uw_advance_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1558{
1559 uw_update_context (context, fs);
1560}
52a11cbf
RH
1561\f
1562/* Fill in CONTEXT for top-of-stack. The only valid registers at this
1563 level will be the return address and the CFA. */
41077ce4 1564
a01da83b
KH
1565#define uw_init_context(CONTEXT) \
1566 do \
1567 { \
1568 /* Do any necessary initialization to access arbitrary stack frames. \
1569 On the SPARC, this means flushing the register windows. */ \
1570 __builtin_unwind_init (); \
1571 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1572 __builtin_return_address (0)); \
1573 } \
1574 while (0)
52a11cbf 1575
71628aa0
R
1576static inline void
1577init_dwarf_reg_size_table (void)
1578{
1579 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
1580}
1581
e5b258a4 1582static void __attribute__((noinline))
52a11cbf
RH
1583uw_init_context_1 (struct _Unwind_Context *context,
1584 void *outer_cfa, void *outer_ra)
1585{
1586 void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
1587 _Unwind_FrameState fs;
71628aa0 1588 _Unwind_SpTmp sp_slot;
79d0dfa3 1589 _Unwind_Reason_Code code;
52a11cbf
RH
1590
1591 memset (context, 0, sizeof (struct _Unwind_Context));
1592 context->ra = ra;
cca2207a
L
1593 if (!ASSUME_EXTENDED_UNWIND_CONTEXT)
1594 context->flags = EXTENDED_CONTEXT_BIT;
52a11cbf 1595
79d0dfa3
NS
1596 code = uw_frame_state_for (context, &fs);
1597 gcc_assert (code == _URC_NO_REASON);
52a11cbf 1598
71628aa0
R
1599#if __GTHREADS
1600 {
1601 static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
1602 if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
7bec3e84 1603 && dwarf_reg_size_table[0] == 0)
71628aa0
R
1604 init_dwarf_reg_size_table ();
1605 }
1606#else
1607 if (dwarf_reg_size_table[0] == 0)
1608 init_dwarf_reg_size_table ();
1609#endif
1610
52a11cbf 1611 /* Force the frame state to use the known cfa value. */
71628aa0 1612 _Unwind_SetSpColumn (context, outer_cfa, &sp_slot);
6673f90b
NF
1613 fs.regs.cfa_how = CFA_REG_OFFSET;
1614 fs.regs.cfa_reg = __builtin_dwarf_sp_column ();
1615 fs.regs.cfa_offset = 0;
52a11cbf
RH
1616
1617 uw_update_context_1 (context, &fs);
1618
1619 /* If the return address column was saved in a register in the
1620 initialization context, then we can't see it in the given
1621 call frame data. So have the initialization context tell us. */
1622 context->ra = __builtin_extract_return_addr (outer_ra);
1623}
1624
934f5b42
JJ
1625static void _Unwind_DebugHook (void *, void *)
1626 __attribute__ ((__noinline__, __used__, __noclone__));
e455776a
TT
1627
1628/* This function is called during unwinding. It is intended as a hook
1629 for a debugger to intercept exceptions. CFA is the CFA of the
1630 target frame. HANDLER is the PC to which control will be
1631 transferred. */
1632static void
1633_Unwind_DebugHook (void *cfa __attribute__ ((__unused__)),
1634 void *handler __attribute__ ((__unused__)))
1635{
f4e749b4
TT
1636 /* We only want to use stap probes starting with v3. Earlier
1637 versions added too much startup cost. */
1638#if defined (HAVE_SYS_SDT_H) && defined (STAP_PROBE2) && _SDT_NOTE_TYPE >= 3
1639 STAP_PROBE2 (libgcc, unwind, cfa, handler);
1640#else
e455776a 1641 asm ("");
f4e749b4 1642#endif
e455776a 1643}
52a11cbf
RH
1644
1645/* Install TARGET into CURRENT so that we can return to it. This is a
1646 macro because __builtin_eh_return must be invoked in the context of
6a10fff4
IT
1647 our caller. FRAMES is a number of frames to be unwind.
1648 _Unwind_Frames_Extra is a macro to do additional work during unwinding
1649 if needed, for example shadow stack pointer adjustment for Intel CET
1650 technology. */
52a11cbf 1651
6a10fff4 1652#define uw_install_context(CURRENT, TARGET, FRAMES) \
e455776a
TT
1653 do \
1654 { \
1655 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
b097c7a2 1656 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
e455776a 1657 _Unwind_DebugHook ((TARGET)->cfa, handler); \
6a10fff4 1658 _Unwind_Frames_Extra (FRAMES); \
e455776a
TT
1659 __builtin_eh_return (offset, handler); \
1660 } \
a01da83b 1661 while (0)
52a11cbf 1662
52a11cbf
RH
1663static long
1664uw_install_context_1 (struct _Unwind_Context *current,
1665 struct _Unwind_Context *target)
1666{
1667 long i;
9d8646d7
PB
1668 _Unwind_SpTmp sp_slot;
1669
1670 /* If the target frame does not have a saved stack pointer,
1671 then set up the target's CFA. */
1672 if (!_Unwind_GetGRPtr (target, __builtin_dwarf_sp_column ()))
4469af7a 1673 _Unwind_SetSpColumn (target, target->cfa, &sp_slot);
52a11cbf 1674
53d68b9f 1675 for (i = 0; i < __LIBGCC_DWARF_FRAME_REGISTERS__; ++i)
52a11cbf 1676 {
cca2207a
L
1677 void *c = (void *) (_Unwind_Internal_Ptr) current->reg[i];
1678 void *t = (void *) (_Unwind_Internal_Ptr)target->reg[i];
41f3a930 1679
4469af7a
JJ
1680 gcc_assert (current->by_value[i] == 0);
1681 if (target->by_value[i] && c)
1682 {
1683 _Unwind_Word w;
1684 _Unwind_Ptr p;
1685 if (dwarf_reg_size_table[i] == sizeof (_Unwind_Word))
1686 {
1687 w = (_Unwind_Internal_Ptr) t;
1688 memcpy (c, &w, sizeof (_Unwind_Word));
1689 }
1690 else
1691 {
1692 gcc_assert (dwarf_reg_size_table[i] == sizeof (_Unwind_Ptr));
1693 p = (_Unwind_Internal_Ptr) t;
1694 memcpy (c, &p, sizeof (_Unwind_Ptr));
1695 }
1696 }
1697 else if (t && c && t != c)
52a11cbf
RH
1698 memcpy (c, t, dwarf_reg_size_table[i]);
1699 }
1700
9d8646d7
PB
1701 /* If the current frame doesn't have a saved stack pointer, then we
1702 need to rely on EH_RETURN_STACKADJ_RTX to get our target stack
1703 pointer value reloaded. */
1704 if (!_Unwind_GetGRPtr (current, __builtin_dwarf_sp_column ()))
1705 {
1706 void *target_cfa;
34dc173c 1707
71628aa0 1708 target_cfa = _Unwind_GetPtr (target, __builtin_dwarf_sp_column ());
9d8646d7
PB
1709
1710 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
53d68b9f 1711 if (__LIBGCC_STACK_GROWS_DOWNWARD__)
9d8646d7
PB
1712 return target_cfa - current->cfa + target->args_size;
1713 else
1714 return current->cfa - target_cfa - target->args_size;
1715 }
34dc173c 1716 return 0;
52a11cbf
RH
1717}
1718
1719static inline _Unwind_Ptr
1720uw_identify_context (struct _Unwind_Context *context)
1721{
d809253a
EB
1722 /* The CFA is not sufficient to disambiguate the context of a function
1723 interrupted by a signal before establishing its frame and the context
1724 of the signal itself. */
53d68b9f 1725 if (__LIBGCC_STACK_GROWS_DOWNWARD__)
d809253a
EB
1726 return _Unwind_GetCFA (context) - _Unwind_IsSignalFrame (context);
1727 else
1728 return _Unwind_GetCFA (context) + _Unwind_IsSignalFrame (context);
52a11cbf
RH
1729}
1730
1731
1732#include "unwind.inc"
1733
443728bb
L
1734#if defined (USE_GAS_SYMVER) && defined (SHARED) && defined (USE_LIBUNWIND_EXCEPTIONS)
1735alias (_Unwind_Backtrace);
1736alias (_Unwind_DeleteException);
1737alias (_Unwind_FindEnclosingFunction);
443728bb
L
1738alias (_Unwind_ForcedUnwind);
1739alias (_Unwind_GetDataRelBase);
1740alias (_Unwind_GetTextRelBase);
1741alias (_Unwind_GetCFA);
1742alias (_Unwind_GetGR);
1743alias (_Unwind_GetIP);
1744alias (_Unwind_GetLanguageSpecificData);
1745alias (_Unwind_GetRegionStart);
1746alias (_Unwind_RaiseException);
1747alias (_Unwind_Resume);
1748alias (_Unwind_Resume_or_Rethrow);
1749alias (_Unwind_SetGR);
1750alias (_Unwind_SetIP);
1751#endif
1752
52a11cbf 1753#endif /* !USING_SJLJ_EXCEPTIONS */