Add a test for longjmp from user context
[glibc.git] / sysdeps / generic / unwind-dw2.c
blob1da102c0a248dc1f4b0e5553d9ab3029d0303ef6
1 /* DWARF2 exception handling and frame unwind runtime interface routines.
2 Copyright (C) 1997-2023 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <https://www.gnu.org/licenses/>. */
20 #ifdef _LIBC
21 #include <stdlib.h>
22 #include <string.h>
23 #include <error.h>
24 #include <libintl.h>
25 #include <dwarf2.h>
26 #include <stdio.h>
27 #include <unwind.h>
28 #include <unwind-pe.h>
29 #include <unwind-dw2-fde.h>
30 #else
31 #include "tconfig.h"
32 #include "tsystem.h"
33 #include "dwarf2.h"
34 #include "unwind.h"
35 #include "unwind-pe.h"
36 #include "unwind-dw2-fde.h"
37 #include "gthr.h"
38 #endif
42 #ifndef STACK_GROWS_DOWNWARD
43 #define STACK_GROWS_DOWNWARD 0
44 #else
45 #undef STACK_GROWS_DOWNWARD
46 #define STACK_GROWS_DOWNWARD 1
47 #endif
49 /* A target can override (perhaps for backward compatibility) how
50 many dwarf2 columns are unwound. */
51 #ifndef DWARF_FRAME_REGISTERS
52 #define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
53 #endif
55 /* Dwarf frame registers used for pre gcc 3.0 compiled glibc. */
56 #ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
57 #define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
58 #endif
60 /* This is the register and unwind state for a particular frame. This
61 provides the information necessary to unwind up past a frame and return
62 to its caller. */
63 struct _Unwind_Context
65 void *reg[DWARF_FRAME_REGISTERS+1];
66 void *cfa;
67 void *ra;
68 void *lsda;
69 struct dwarf_eh_bases bases;
70 _Unwind_Word args_size;
73 #ifndef _LIBC
74 /* Byte size of every register managed by these routines. */
75 static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS];
76 #endif
79 /* The result of interpreting the frame unwind info for a frame.
80 This is all symbolic at this point, as none of the values can
81 be resolved until the target pc is located. */
82 typedef struct
84 /* Each register save state can be described in terms of a CFA slot,
85 another register, or a location expression. */
86 struct frame_state_reg_info
88 struct {
89 union {
90 _Unwind_Word reg;
91 _Unwind_Sword offset;
92 const unsigned char *exp;
93 } loc;
94 enum {
95 REG_UNSAVED,
96 REG_SAVED_OFFSET,
97 REG_SAVED_REG,
98 REG_SAVED_EXP,
99 } how;
100 } reg[DWARF_FRAME_REGISTERS+1];
102 /* Used to implement DW_CFA_remember_state. */
103 struct frame_state_reg_info *prev;
104 } regs;
106 /* The CFA can be described in terms of a reg+offset or a
107 location expression. */
108 _Unwind_Sword cfa_offset;
109 _Unwind_Word cfa_reg;
110 const unsigned char *cfa_exp;
111 enum {
112 CFA_UNSET,
113 CFA_REG_OFFSET,
114 CFA_EXP,
115 } cfa_how;
117 /* The PC described by the current frame state. */
118 void *pc;
120 /* The information we care about from the CIE/FDE. */
121 _Unwind_Personality_Fn personality;
122 _Unwind_Sword data_align;
123 _Unwind_Word code_align;
124 unsigned char retaddr_column;
125 unsigned char fde_encoding;
126 unsigned char lsda_encoding;
127 unsigned char saw_z;
128 void *eh_ptr;
129 } _Unwind_FrameState;
131 /* Read unaligned data from the instruction buffer. */
133 union unaligned
135 void *p;
136 unsigned u2 __attribute__ ((mode (HI)));
137 unsigned u4 __attribute__ ((mode (SI)));
138 unsigned u8 __attribute__ ((mode (DI)));
139 signed s2 __attribute__ ((mode (HI)));
140 signed s4 __attribute__ ((mode (SI)));
141 signed s8 __attribute__ ((mode (DI)));
142 } __attribute__ ((packed));
144 static inline void *
145 read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
147 static inline int
148 read_1u (const void *p) { return *(const unsigned char *) p; }
150 static inline int
151 read_1s (const void *p) { return *(const signed char *) p; }
153 static inline int
154 read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
156 static inline int
157 read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
159 static inline unsigned int
160 read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
162 static inline int
163 read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
165 static inline unsigned long
166 read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
168 static inline unsigned long
169 read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
171 /* Get the value of register REG as saved in CONTEXT. */
173 inline _Unwind_Word
174 _Unwind_GetGR (struct _Unwind_Context *context, int index)
176 /* This will segfault if the register hasn't been saved. */
177 return * (_Unwind_Word *) context->reg[index];
180 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
182 inline void
183 _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
185 * (_Unwind_Word *) context->reg[index] = val;
188 /* Retrieve the return address for CONTEXT. */
190 inline _Unwind_Ptr
191 _Unwind_GetIP (struct _Unwind_Context *context)
193 return (_Unwind_Ptr) context->ra;
196 /* Overwrite the return address for CONTEXT with VAL. */
198 inline void
199 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
201 context->ra = (void *) val;
204 void *
205 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
207 return context->lsda;
210 _Unwind_Ptr
211 _Unwind_GetRegionStart (struct _Unwind_Context *context)
213 return (_Unwind_Ptr) context->bases.func;
216 void *
217 _Unwind_FindEnclosingFunction (void *pc)
219 struct dwarf_eh_bases bases;
220 struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases);
221 if (fde)
222 return bases.func;
223 else
224 return NULL;
227 #ifndef __ia64__
228 _Unwind_Ptr
229 _Unwind_GetDataRelBase (struct _Unwind_Context *context)
231 return (_Unwind_Ptr) context->bases.dbase;
234 _Unwind_Ptr
235 _Unwind_GetTextRelBase (struct _Unwind_Context *context)
237 return (_Unwind_Ptr) context->bases.tbase;
239 #endif
241 /* Extract any interesting information from the CIE for the translation
242 unit F belongs to. Return a pointer to the byte after the augmentation,
243 or NULL if we encountered an undecipherable augmentation. */
245 static const unsigned char *
246 extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
247 _Unwind_FrameState *fs)
249 const unsigned char *aug = cie->augmentation;
250 const unsigned char *p = aug + strlen ((const char *) aug) + 1;
251 const unsigned char *ret = NULL;
252 _Unwind_Word utmp;
254 /* g++ v2 "eh" has pointer immediately following augmentation string,
255 so it must be handled first. */
256 if (aug[0] == 'e' && aug[1] == 'h')
258 fs->eh_ptr = read_pointer (p);
259 p += sizeof (void *);
260 aug += 2;
263 /* Immediately following the augmentation are the code and
264 data alignment and return address column. */
265 p = read_uleb128 (p, &fs->code_align);
266 p = read_sleb128 (p, &fs->data_align);
267 fs->retaddr_column = *p++;
268 fs->lsda_encoding = DW_EH_PE_omit;
270 /* If the augmentation starts with 'z', then a uleb128 immediately
271 follows containing the length of the augmentation field following
272 the size. */
273 if (*aug == 'z')
275 p = read_uleb128 (p, &utmp);
276 ret = p + utmp;
278 fs->saw_z = 1;
279 ++aug;
282 /* Iterate over recognized augmentation subsequences. */
283 while (*aug != '\0')
285 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
286 if (aug[0] == 'L')
288 fs->lsda_encoding = *p++;
289 aug += 1;
292 /* "R" indicates a byte indicating how FDE addresses are encoded. */
293 else if (aug[0] == 'R')
295 fs->fde_encoding = *p++;
296 aug += 1;
299 /* "P" indicates a personality routine in the CIE augmentation. */
300 else if (aug[0] == 'P')
302 _Unwind_Ptr personality;
303 p = read_encoded_value (context, *p, p + 1, &personality);
304 fs->personality = (_Unwind_Personality_Fn) personality;
305 aug += 1;
308 /* Otherwise we have an unknown augmentation string.
309 Bail unless we saw a 'z' prefix. */
310 else
311 return ret;
314 return ret ? ret : p;
317 #ifndef _LIBC
318 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
319 onto the stack to start. */
321 static _Unwind_Word
322 execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
323 struct _Unwind_Context *context, _Unwind_Word initial)
325 _Unwind_Word stack[64]; /* ??? Assume this is enough. */
326 int stack_elt;
328 stack[0] = initial;
329 stack_elt = 1;
331 while (op_ptr < op_end)
333 enum dwarf_location_atom op = *op_ptr++;
334 _Unwind_Word result, reg, utmp;
335 _Unwind_Sword offset, stmp;
337 switch (op)
339 case DW_OP_lit0:
340 case DW_OP_lit1:
341 case DW_OP_lit2:
342 case DW_OP_lit3:
343 case DW_OP_lit4:
344 case DW_OP_lit5:
345 case DW_OP_lit6:
346 case DW_OP_lit7:
347 case DW_OP_lit8:
348 case DW_OP_lit9:
349 case DW_OP_lit10:
350 case DW_OP_lit11:
351 case DW_OP_lit12:
352 case DW_OP_lit13:
353 case DW_OP_lit14:
354 case DW_OP_lit15:
355 case DW_OP_lit16:
356 case DW_OP_lit17:
357 case DW_OP_lit18:
358 case DW_OP_lit19:
359 case DW_OP_lit20:
360 case DW_OP_lit21:
361 case DW_OP_lit22:
362 case DW_OP_lit23:
363 case DW_OP_lit24:
364 case DW_OP_lit25:
365 case DW_OP_lit26:
366 case DW_OP_lit27:
367 case DW_OP_lit28:
368 case DW_OP_lit29:
369 case DW_OP_lit30:
370 case DW_OP_lit31:
371 result = op - DW_OP_lit0;
372 break;
374 case DW_OP_addr:
375 result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
376 op_ptr += sizeof (void *);
377 break;
379 case DW_OP_const1u:
380 result = read_1u (op_ptr);
381 op_ptr += 1;
382 break;
383 case DW_OP_const1s:
384 result = read_1s (op_ptr);
385 op_ptr += 1;
386 break;
387 case DW_OP_const2u:
388 result = read_2u (op_ptr);
389 op_ptr += 2;
390 break;
391 case DW_OP_const2s:
392 result = read_2s (op_ptr);
393 op_ptr += 2;
394 break;
395 case DW_OP_const4u:
396 result = read_4u (op_ptr);
397 op_ptr += 4;
398 break;
399 case DW_OP_const4s:
400 result = read_4s (op_ptr);
401 op_ptr += 4;
402 break;
403 case DW_OP_const8u:
404 result = read_8u (op_ptr);
405 op_ptr += 8;
406 break;
407 case DW_OP_const8s:
408 result = read_8s (op_ptr);
409 op_ptr += 8;
410 break;
411 case DW_OP_constu:
412 op_ptr = read_uleb128 (op_ptr, &result);
413 break;
414 case DW_OP_consts:
415 op_ptr = read_sleb128 (op_ptr, &stmp);
416 result = stmp;
417 break;
419 case DW_OP_reg0:
420 case DW_OP_reg1:
421 case DW_OP_reg2:
422 case DW_OP_reg3:
423 case DW_OP_reg4:
424 case DW_OP_reg5:
425 case DW_OP_reg6:
426 case DW_OP_reg7:
427 case DW_OP_reg8:
428 case DW_OP_reg9:
429 case DW_OP_reg10:
430 case DW_OP_reg11:
431 case DW_OP_reg12:
432 case DW_OP_reg13:
433 case DW_OP_reg14:
434 case DW_OP_reg15:
435 case DW_OP_reg16:
436 case DW_OP_reg17:
437 case DW_OP_reg18:
438 case DW_OP_reg19:
439 case DW_OP_reg20:
440 case DW_OP_reg21:
441 case DW_OP_reg22:
442 case DW_OP_reg23:
443 case DW_OP_reg24:
444 case DW_OP_reg25:
445 case DW_OP_reg26:
446 case DW_OP_reg27:
447 case DW_OP_reg28:
448 case DW_OP_reg29:
449 case DW_OP_reg30:
450 case DW_OP_reg31:
451 result = _Unwind_GetGR (context, op - DW_OP_reg0);
452 break;
453 case DW_OP_regx:
454 op_ptr = read_uleb128 (op_ptr, &reg);
455 result = _Unwind_GetGR (context, reg);
456 break;
458 case DW_OP_breg0:
459 case DW_OP_breg1:
460 case DW_OP_breg2:
461 case DW_OP_breg3:
462 case DW_OP_breg4:
463 case DW_OP_breg5:
464 case DW_OP_breg6:
465 case DW_OP_breg7:
466 case DW_OP_breg8:
467 case DW_OP_breg9:
468 case DW_OP_breg10:
469 case DW_OP_breg11:
470 case DW_OP_breg12:
471 case DW_OP_breg13:
472 case DW_OP_breg14:
473 case DW_OP_breg15:
474 case DW_OP_breg16:
475 case DW_OP_breg17:
476 case DW_OP_breg18:
477 case DW_OP_breg19:
478 case DW_OP_breg20:
479 case DW_OP_breg21:
480 case DW_OP_breg22:
481 case DW_OP_breg23:
482 case DW_OP_breg24:
483 case DW_OP_breg25:
484 case DW_OP_breg26:
485 case DW_OP_breg27:
486 case DW_OP_breg28:
487 case DW_OP_breg29:
488 case DW_OP_breg30:
489 case DW_OP_breg31:
490 op_ptr = read_sleb128 (op_ptr, &offset);
491 result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
492 break;
493 case DW_OP_bregx:
494 op_ptr = read_uleb128 (op_ptr, &reg);
495 op_ptr = read_sleb128 (op_ptr, &offset);
496 result = _Unwind_GetGR (context, reg) + offset;
497 break;
499 case DW_OP_dup:
500 if (stack_elt < 1)
501 abort ();
502 result = stack[stack_elt - 1];
503 break;
505 case DW_OP_drop:
506 if (--stack_elt < 0)
507 abort ();
508 goto no_push;
510 case DW_OP_pick:
511 offset = *op_ptr++;
512 if (offset >= stack_elt - 1)
513 abort ();
514 result = stack[stack_elt - 1 - offset];
515 break;
517 case DW_OP_over:
518 if (stack_elt < 2)
519 abort ();
520 result = stack[stack_elt - 2];
521 break;
523 case DW_OP_rot:
525 _Unwind_Word t1, t2, t3;
527 if (stack_elt < 3)
528 abort ();
529 t1 = stack[stack_elt - 1];
530 t2 = stack[stack_elt - 2];
531 t3 = stack[stack_elt - 3];
532 stack[stack_elt - 1] = t2;
533 stack[stack_elt - 2] = t3;
534 stack[stack_elt - 3] = t1;
535 goto no_push;
538 case DW_OP_deref:
539 case DW_OP_deref_size:
540 case DW_OP_abs:
541 case DW_OP_neg:
542 case DW_OP_not:
543 case DW_OP_plus_uconst:
544 /* Unary operations. */
545 if (--stack_elt < 0)
546 abort ();
547 result = stack[stack_elt];
549 switch (op)
551 case DW_OP_deref:
553 void *ptr = (void *) (_Unwind_Ptr) result;
554 result = (_Unwind_Ptr) read_pointer (ptr);
556 break;
558 case DW_OP_deref_size:
560 void *ptr = (void *) (_Unwind_Ptr) result;
561 switch (*op_ptr++)
563 case 1:
564 result = read_1u (ptr);
565 break;
566 case 2:
567 result = read_2u (ptr);
568 break;
569 case 4:
570 result = read_4u (ptr);
571 break;
572 case 8:
573 result = read_8u (ptr);
574 break;
575 default:
576 abort ();
579 break;
581 case DW_OP_abs:
582 if ((_Unwind_Sword) result < 0)
583 result = -result;
584 break;
585 case DW_OP_neg:
586 result = -result;
587 break;
588 case DW_OP_not:
589 result = ~result;
590 break;
591 case DW_OP_plus_uconst:
592 op_ptr = read_uleb128 (op_ptr, &utmp);
593 result += utmp;
594 break;
596 default:
597 abort ();
599 break;
601 case DW_OP_and:
602 case DW_OP_div:
603 case DW_OP_minus:
604 case DW_OP_mod:
605 case DW_OP_mul:
606 case DW_OP_or:
607 case DW_OP_plus:
608 case DW_OP_le:
609 case DW_OP_ge:
610 case DW_OP_eq:
611 case DW_OP_lt:
612 case DW_OP_gt:
613 case DW_OP_ne:
615 /* Binary operations. */
616 _Unwind_Word first, second;
617 if ((stack_elt -= 2) < 0)
618 abort ();
619 second = stack[stack_elt];
620 first = stack[stack_elt + 1];
622 switch (op)
624 case DW_OP_and:
625 result = second & first;
626 break;
627 case DW_OP_div:
628 result = (_Unwind_Sword) second / (_Unwind_Sword) first;
629 break;
630 case DW_OP_minus:
631 result = second - first;
632 break;
633 case DW_OP_mod:
634 result = (_Unwind_Sword) second % (_Unwind_Sword) first;
635 break;
636 case DW_OP_mul:
637 result = second * first;
638 break;
639 case DW_OP_or:
640 result = second | first;
641 break;
642 case DW_OP_plus:
643 result = second + first;
644 break;
645 case DW_OP_shl:
646 result = second << first;
647 break;
648 case DW_OP_shr:
649 result = second >> first;
650 break;
651 case DW_OP_shra:
652 result = (_Unwind_Sword) second >> first;
653 break;
654 case DW_OP_xor:
655 result = second ^ first;
656 break;
657 case DW_OP_le:
658 result = (_Unwind_Sword) first <= (_Unwind_Sword) second;
659 break;
660 case DW_OP_ge:
661 result = (_Unwind_Sword) first >= (_Unwind_Sword) second;
662 break;
663 case DW_OP_eq:
664 result = (_Unwind_Sword) first == (_Unwind_Sword) second;
665 break;
666 case DW_OP_lt:
667 result = (_Unwind_Sword) first < (_Unwind_Sword) second;
668 break;
669 case DW_OP_gt:
670 result = (_Unwind_Sword) first > (_Unwind_Sword) second;
671 break;
672 case DW_OP_ne:
673 result = (_Unwind_Sword) first != (_Unwind_Sword) second;
674 break;
676 default:
677 abort ();
680 break;
682 case DW_OP_skip:
683 offset = read_2s (op_ptr);
684 op_ptr += 2;
685 op_ptr += offset;
686 goto no_push;
688 case DW_OP_bra:
689 if (--stack_elt < 0)
690 abort ();
691 offset = read_2s (op_ptr);
692 op_ptr += 2;
693 if (stack[stack_elt] != 0)
694 op_ptr += offset;
695 goto no_push;
697 case DW_OP_nop:
698 goto no_push;
700 default:
701 abort ();
704 /* Most things push a result value. */
705 if ((size_t) stack_elt >= sizeof (stack) / sizeof (*stack))
706 abort ();
707 stack[stack_elt++] = result;
708 no_push:;
711 /* We were executing this program to get a value. It should be
712 at top of stack. */
713 if (--stack_elt < 0)
714 abort ();
715 return stack[stack_elt];
717 #endif
719 /* Decode DWARF 2 call frame information. Takes pointers the
720 instruction sequence to decode, current register information and
721 CIE info, and the PC range to evaluate. */
723 static void
724 execute_cfa_program (const unsigned char *insn_ptr,
725 const unsigned char *insn_end,
726 struct _Unwind_Context *context,
727 _Unwind_FrameState *fs)
729 struct frame_state_reg_info *unused_rs = NULL;
731 /* Don't allow remember/restore between CIE and FDE programs. */
732 fs->regs.prev = NULL;
734 /* The comparison with the return address uses < rather than <= because
735 we are only interested in the effects of code before the call; for a
736 noreturn function, the return address may point to unrelated code with
737 a different stack configuration that we are not interested in. We
738 assume that the call itself is unwind info-neutral; if not, or if
739 there are delay instructions that adjust the stack, these must be
740 reflected at the point immediately before the call insn. */
741 while (insn_ptr < insn_end && fs->pc < context->ra)
743 unsigned char insn = *insn_ptr++;
744 _Unwind_Word reg, utmp;
745 _Unwind_Sword offset, stmp;
747 if ((insn & 0xc0) == DW_CFA_advance_loc)
748 fs->pc += (insn & 0x3f) * fs->code_align;
749 else if ((insn & 0xc0) == DW_CFA_offset)
751 reg = insn & 0x3f;
752 insn_ptr = read_uleb128 (insn_ptr, &utmp);
753 offset = (_Unwind_Sword) utmp * fs->data_align;
754 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
755 fs->regs.reg[reg].loc.offset = offset;
757 else if ((insn & 0xc0) == DW_CFA_restore)
759 reg = insn & 0x3f;
760 fs->regs.reg[reg].how = REG_UNSAVED;
762 else switch (insn)
764 case DW_CFA_set_loc:
766 _Unwind_Ptr pc;
767 insn_ptr = read_encoded_value (context, fs->fde_encoding,
768 insn_ptr, &pc);
769 fs->pc = (void *) pc;
771 break;
773 case DW_CFA_advance_loc1:
774 fs->pc += read_1u (insn_ptr) * fs->code_align;
775 insn_ptr += 1;
776 break;
777 case DW_CFA_advance_loc2:
778 fs->pc += read_2u (insn_ptr) * fs->code_align;
779 insn_ptr += 2;
780 break;
781 case DW_CFA_advance_loc4:
782 fs->pc += read_4u (insn_ptr) * fs->code_align;
783 insn_ptr += 4;
784 break;
786 case DW_CFA_offset_extended:
787 insn_ptr = read_uleb128 (insn_ptr, &reg);
788 insn_ptr = read_uleb128 (insn_ptr, &utmp);
789 offset = (_Unwind_Sword) utmp * fs->data_align;
790 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
791 fs->regs.reg[reg].loc.offset = offset;
792 break;
794 case DW_CFA_restore_extended:
795 insn_ptr = read_uleb128 (insn_ptr, &reg);
796 fs->regs.reg[reg].how = REG_UNSAVED;
797 break;
799 case DW_CFA_undefined:
800 case DW_CFA_same_value:
801 insn_ptr = read_uleb128 (insn_ptr, &reg);
802 break;
804 case DW_CFA_nop:
805 break;
807 case DW_CFA_register:
809 _Unwind_Word reg2;
810 insn_ptr = read_uleb128 (insn_ptr, &reg);
811 insn_ptr = read_uleb128 (insn_ptr, &reg2);
812 fs->regs.reg[reg].how = REG_SAVED_REG;
813 fs->regs.reg[reg].loc.reg = reg2;
815 break;
817 case DW_CFA_remember_state:
819 struct frame_state_reg_info *new_rs;
820 if (unused_rs)
822 new_rs = unused_rs;
823 unused_rs = unused_rs->prev;
825 else
826 new_rs = __builtin_alloca (sizeof (struct frame_state_reg_info));
828 *new_rs = fs->regs;
829 fs->regs.prev = new_rs;
831 break;
833 case DW_CFA_restore_state:
835 struct frame_state_reg_info *old_rs = fs->regs.prev;
836 #ifdef _LIBC
837 if (old_rs == NULL)
838 __libc_fatal ("Invalid DWARF unwind data.\n");
839 else
840 #endif
842 fs->regs = *old_rs;
843 old_rs->prev = unused_rs;
844 unused_rs = old_rs;
847 break;
849 case DW_CFA_def_cfa:
850 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
851 insn_ptr = read_uleb128 (insn_ptr, &utmp);
852 fs->cfa_offset = utmp;
853 fs->cfa_how = CFA_REG_OFFSET;
854 break;
856 case DW_CFA_def_cfa_register:
857 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
858 fs->cfa_how = CFA_REG_OFFSET;
859 break;
861 case DW_CFA_def_cfa_offset:
862 insn_ptr = read_uleb128 (insn_ptr, &utmp);
863 fs->cfa_offset = utmp;
864 /* cfa_how deliberately not set. */
865 break;
867 case DW_CFA_def_cfa_expression:
868 fs->cfa_exp = insn_ptr;
869 fs->cfa_how = CFA_EXP;
870 insn_ptr = read_uleb128 (insn_ptr, &utmp);
871 insn_ptr += utmp;
872 break;
874 case DW_CFA_expression:
875 insn_ptr = read_uleb128 (insn_ptr, &reg);
876 fs->regs.reg[reg].how = REG_SAVED_EXP;
877 fs->regs.reg[reg].loc.exp = insn_ptr;
878 insn_ptr = read_uleb128 (insn_ptr, &utmp);
879 insn_ptr += utmp;
880 break;
882 /* From the 2.1 draft. */
883 case DW_CFA_offset_extended_sf:
884 insn_ptr = read_uleb128 (insn_ptr, &reg);
885 insn_ptr = read_sleb128 (insn_ptr, &stmp);
886 offset = stmp * fs->data_align;
887 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
888 fs->regs.reg[reg].loc.offset = offset;
889 break;
891 case DW_CFA_def_cfa_sf:
892 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
893 insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
894 fs->cfa_how = CFA_REG_OFFSET;
895 break;
897 case DW_CFA_def_cfa_offset_sf:
898 insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
899 /* cfa_how deliberately not set. */
900 break;
902 case DW_CFA_GNU_window_save:
903 /* ??? Hardcoded for SPARC register window configuration.
904 At least do not do anything for archs which explicitly
905 define a lower register number. */
906 #if DWARF_FRAME_REGISTERS >= 32
907 for (reg = 16; reg < 32; ++reg)
909 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
910 fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
912 #endif
913 break;
915 case DW_CFA_GNU_args_size:
916 insn_ptr = read_uleb128 (insn_ptr, &context->args_size);
917 break;
919 case DW_CFA_GNU_negative_offset_extended:
920 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
921 older PowerPC code. */
922 insn_ptr = read_uleb128 (insn_ptr, &reg);
923 insn_ptr = read_uleb128 (insn_ptr, &utmp);
924 offset = (_Unwind_Word) utmp * fs->data_align;
925 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
926 fs->regs.reg[reg].loc.offset = -offset;
927 break;
929 default:
930 abort ();
935 /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
936 its caller and decode it into FS. This function also sets the
937 args_size and lsda members of CONTEXT, as they are really information
938 about the caller's frame. */
940 static _Unwind_Reason_Code
941 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
943 struct dwarf_fde *fde;
944 struct dwarf_cie *cie;
945 const unsigned char *aug, *insn, *end;
947 memset (fs, 0, sizeof (*fs));
948 context->args_size = 0;
949 context->lsda = 0;
951 fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
952 if (fde == NULL)
954 /* Couldn't find frame unwind info for this function. Try a
955 target-specific fallback mechanism. This will necessarily
956 not provide a personality routine or LSDA. */
957 #ifdef MD_FALLBACK_FRAME_STATE_FOR
958 MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
959 return _URC_END_OF_STACK;
960 success:
961 return _URC_NO_REASON;
962 #else
963 return _URC_END_OF_STACK;
964 #endif
967 fs->pc = context->bases.func;
969 cie = get_cie (fde);
970 insn = extract_cie_info (cie, context, fs);
971 if (insn == NULL)
972 /* CIE contained unknown augmentation. */
973 return _URC_FATAL_PHASE1_ERROR;
975 /* First decode all the insns in the CIE. */
976 end = (unsigned char *) next_fde ((struct dwarf_fde *) cie);
977 execute_cfa_program (insn, end, context, fs);
979 /* Locate augmentation for the fde. */
980 aug = (unsigned char *) fde + sizeof (*fde);
981 aug += 2 * size_of_encoded_value (fs->fde_encoding);
982 insn = NULL;
983 if (fs->saw_z)
985 _Unwind_Word i;
986 aug = read_uleb128 (aug, &i);
987 insn = aug + i;
989 if (fs->lsda_encoding != DW_EH_PE_omit)
991 _Unwind_Ptr lsda;
992 aug = read_encoded_value (context, fs->lsda_encoding, aug, &lsda);
993 context->lsda = (void *) lsda;
996 /* Then the insns in the FDE up to our target PC. */
997 if (insn == NULL)
998 insn = aug;
999 end = (unsigned char *) next_fde (fde);
1000 execute_cfa_program (insn, end, context, fs);
1002 return _URC_NO_REASON;
1005 typedef struct frame_state
1007 void *cfa;
1008 void *eh_ptr;
1009 long cfa_offset;
1010 long args_size;
1011 long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1012 unsigned short cfa_reg;
1013 unsigned short retaddr_column;
1014 char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1015 } frame_state;
1017 #ifndef STATIC
1018 # define STATIC
1019 #endif
1021 STATIC
1022 struct frame_state * __frame_state_for (void *, struct frame_state *);
1024 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
1025 a given PC_TARGET. The caller should allocate a local variable of
1026 `struct frame_state' and pass its address to STATE_IN. */
1028 STATIC
1029 struct frame_state *
1030 __frame_state_for (void *pc_target, struct frame_state *state_in)
1032 struct _Unwind_Context context;
1033 _Unwind_FrameState fs;
1034 int reg;
1036 memset (&context, 0, sizeof (struct _Unwind_Context));
1037 context.ra = pc_target + 1;
1039 if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
1040 return 0;
1042 /* We have no way to pass a location expression for the CFA to our
1043 caller. It wouldn't understand it anyway. */
1044 if (fs.cfa_how == CFA_EXP)
1045 return 0;
1047 for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
1049 state_in->saved[reg] = fs.regs.reg[reg].how;
1050 switch (state_in->saved[reg])
1052 case REG_SAVED_REG:
1053 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
1054 break;
1055 case REG_SAVED_OFFSET:
1056 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
1057 break;
1058 default:
1059 state_in->reg_or_offset[reg] = 0;
1060 break;
1064 state_in->cfa_offset = fs.cfa_offset;
1065 state_in->cfa_reg = fs.cfa_reg;
1066 state_in->retaddr_column = fs.retaddr_column;
1067 state_in->args_size = context.args_size;
1068 state_in->eh_ptr = fs.eh_ptr;
1070 return state_in;
1073 #ifndef _LIBC
1075 static void
1076 uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1078 struct _Unwind_Context orig_context = *context;
1079 void *cfa;
1080 long i;
1082 #ifdef EH_RETURN_STACKADJ_RTX
1083 /* Special handling here: Many machines do not use a frame pointer,
1084 and track the CFA only through offsets from the stack pointer from
1085 one frame to the next. In this case, the stack pointer is never
1086 stored, so it has no saved address in the context. What we do
1087 have is the CFA from the previous stack frame.
1089 In very special situations (such as unwind info for signal return),
1090 there may be location expressions that use the stack pointer as well.
1092 Do this conditionally for one frame. This allows the unwind info
1093 for one frame to save a copy of the stack pointer from the previous
1094 frame, and be able to use much easier CFA mechanisms to do it.
1095 Always zap the saved stack pointer value for the next frame; carrying
1096 the value over from one frame to another doesn't make sense. */
1098 _Unwind_Word tmp_sp;
1100 if (!orig_context.reg[__builtin_dwarf_sp_column ()])
1102 tmp_sp = (_Unwind_Ptr) context->cfa;
1103 orig_context.reg[__builtin_dwarf_sp_column ()] = &tmp_sp;
1105 context->reg[__builtin_dwarf_sp_column ()] = NULL;
1106 #endif
1108 /* Compute this frame's CFA. */
1109 switch (fs->cfa_how)
1111 case CFA_REG_OFFSET:
1112 cfa = (void *) (_Unwind_Ptr) _Unwind_GetGR (&orig_context, fs->cfa_reg);
1113 cfa += fs->cfa_offset;
1114 break;
1116 case CFA_EXP:
1118 const unsigned char *exp = fs->cfa_exp;
1119 _Unwind_Word len;
1121 exp = read_uleb128 (exp, &len);
1122 cfa = (void *) (_Unwind_Ptr)
1123 execute_stack_op (exp, exp + len, &orig_context, 0);
1124 break;
1127 default:
1128 abort ();
1130 context->cfa = cfa;
1132 /* Compute the addresses of all registers saved in this frame. */
1133 for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
1134 switch (fs->regs.reg[i].how)
1136 case REG_UNSAVED:
1137 break;
1139 case REG_SAVED_OFFSET:
1140 context->reg[i] = cfa + fs->regs.reg[i].loc.offset;
1141 break;
1143 case REG_SAVED_REG:
1144 context->reg[i] = orig_context.reg[fs->regs.reg[i].loc.reg];
1145 break;
1147 case REG_SAVED_EXP:
1149 const unsigned char *exp = fs->regs.reg[i].loc.exp;
1150 _Unwind_Word len;
1151 _Unwind_Ptr val;
1153 exp = read_uleb128 (exp, &len);
1154 val = execute_stack_op (exp, exp + len, &orig_context,
1155 (_Unwind_Ptr) cfa);
1156 context->reg[i] = (void *) val;
1158 break;
1162 /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1163 of its caller. Update CONTEXT to refer to the caller as well. Note
1164 that the args_size and lsda members are not updated here, but later in
1165 uw_frame_state_for. */
1167 static void
1168 uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1170 uw_update_context_1 (context, fs);
1172 /* Compute the return address now, since the return address column
1173 can change from frame to frame. */
1174 context->ra = __builtin_extract_return_addr
1175 ((void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->retaddr_column));
1178 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1179 level will be the return address and the CFA. */
1181 #define uw_init_context(CONTEXT) \
1182 do \
1184 /* Do any necessary initialization to access arbitrary stack frames. \
1185 On the SPARC, this means flushing the register windows. */ \
1186 __builtin_unwind_init (); \
1187 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1188 __builtin_return_address (0)); \
1190 while (0)
1192 static void
1193 uw_init_context_1 (struct _Unwind_Context *context,
1194 void *outer_cfa, void *outer_ra)
1196 void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
1197 _Unwind_FrameState fs;
1198 _Unwind_Word sp_slot;
1200 memset (context, 0, sizeof (struct _Unwind_Context));
1201 context->ra = ra;
1203 if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
1204 abort ();
1206 /* Force the frame state to use the known cfa value. */
1207 sp_slot = (_Unwind_Ptr) outer_cfa;
1208 context->reg[__builtin_dwarf_sp_column ()] = &sp_slot;
1209 fs.cfa_how = CFA_REG_OFFSET;
1210 fs.cfa_reg = __builtin_dwarf_sp_column ();
1211 fs.cfa_offset = 0;
1213 uw_update_context_1 (context, &fs);
1215 /* If the return address column was saved in a register in the
1216 initialization context, then we can't see it in the given
1217 call frame data. So have the initialization context tell us. */
1218 context->ra = __builtin_extract_return_addr (outer_ra);
1222 /* Install TARGET into CURRENT so that we can return to it. This is a
1223 macro because __builtin_eh_return must be invoked in the context of
1224 our caller. */
1226 #define uw_install_context(CURRENT, TARGET) \
1227 do \
1229 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1230 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1231 __builtin_eh_return (offset, handler); \
1233 while (0)
1235 static inline void
1236 init_dwarf_reg_size_table (void)
1238 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
1241 static long
1242 uw_install_context_1 (struct _Unwind_Context *current,
1243 struct _Unwind_Context *target)
1245 long i;
1247 #if __GTHREADS
1249 static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
1250 if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
1251 || dwarf_reg_size_table[0] == 0)
1252 init_dwarf_reg_size_table ();
1254 #else
1255 if (dwarf_reg_size_table[0] == 0)
1256 init_dwarf_reg_size_table ();
1257 #endif
1259 for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
1261 void *c = current->reg[i];
1262 void *t = target->reg[i];
1263 if (t && c && t != c)
1264 memcpy (c, t, dwarf_reg_size_table[i]);
1267 #ifdef EH_RETURN_STACKADJ_RTX
1269 void *target_cfa;
1271 /* If the last frame records a saved stack pointer, use it. */
1272 if (target->reg[__builtin_dwarf_sp_column ()])
1273 target_cfa = (void *)(_Unwind_Ptr)
1274 _Unwind_GetGR (target, __builtin_dwarf_sp_column ());
1275 else
1276 target_cfa = target->cfa;
1278 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1279 if (STACK_GROWS_DOWNWARD)
1280 return target_cfa - current->cfa + target->args_size;
1281 else
1282 return current->cfa - target_cfa - target->args_size;
1284 #else
1285 return 0;
1286 #endif
1289 static inline _Unwind_Ptr
1290 uw_identify_context (struct _Unwind_Context *context)
1292 return _Unwind_GetIP (context);
1296 #include "unwind.inc"
1298 #endif /* _LIBC */