1/* DWARF2 exception handling and frame unwind runtime interface routines.
2 Copyright (C) 1997-2024 Free Software Foundation, Inc.
3
4 This file is part of the GNU C Library.
5
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.
10
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.
15
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/>. */
19
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
39
40
41
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
48
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
54
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
59
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. */
63struct _Unwind_Context
64{
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;
71};
72
73#ifndef _LIBC
74/* Byte size of every register managed by these routines. */
75static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS];
76#endif
77
78
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. */
82typedef struct
83{
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
87 {
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];
101
102 /* Used to implement DW_CFA_remember_state. */
103 struct frame_state_reg_info *prev;
104 } regs;
105
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;
116
117 /* The PC described by the current frame state. */
118 void *pc;
119
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;
130
131/* Read unaligned data from the instruction buffer. */
132
133union unaligned
134{
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));
143
144static inline void *
145read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
146
147static inline int
148read_1u (const void *p) { return *(const unsigned char *) p; }
149
150static inline int
151read_1s (const void *p) { return *(const signed char *) p; }
152
153static inline int
154read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
155
156static inline int
157read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
158
159static inline unsigned int
160read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
161
162static inline int
163read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
164
165static inline unsigned long
166read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
167
168static inline unsigned long
169read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
170
171/* Get the value of register REG as saved in CONTEXT. */
172
173inline _Unwind_Word
174_Unwind_GetGR (struct _Unwind_Context *context, int index)
175{
176 /* This will segfault if the register hasn't been saved. */
177 return * (_Unwind_Word *) context->reg[index];
178}
179
180/* Overwrite the saved value for register REG in CONTEXT with VAL. */
181
182inline void
183_Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
184{
185 * (_Unwind_Word *) context->reg[index] = val;
186}
187
188/* Retrieve the return address for CONTEXT. */
189
190inline _Unwind_Ptr
191_Unwind_GetIP (struct _Unwind_Context *context)
192{
193 return (_Unwind_Ptr) context->ra;
194}
195
196/* Overwrite the return address for CONTEXT with VAL. */
197
198inline void
199_Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
200{
201 context->ra = (void *) val;
202}
203
204void *
205_Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
206{
207 return context->lsda;
208}
209
210_Unwind_Ptr
211_Unwind_GetRegionStart (struct _Unwind_Context *context)
212{
213 return (_Unwind_Ptr) context->bases.func;
214}
215
216void *
217_Unwind_FindEnclosingFunction (void *pc)
218{
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;
225}
226
227_Unwind_Ptr
228_Unwind_GetDataRelBase (struct _Unwind_Context *context)
229{
230 return (_Unwind_Ptr) context->bases.dbase;
231}
232
233_Unwind_Ptr
234_Unwind_GetTextRelBase (struct _Unwind_Context *context)
235{
236 return (_Unwind_Ptr) context->bases.tbase;
237}
238
239/* Extract any interesting information from the CIE for the translation
240 unit F belongs to. Return a pointer to the byte after the augmentation,
241 or NULL if we encountered an undecipherable augmentation. */
242
243static const unsigned char *
244extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
245 _Unwind_FrameState *fs)
246{
247 const unsigned char *aug = cie->augmentation;
248 const unsigned char *p = aug + strlen ((const char *) aug) + 1;
249 const unsigned char *ret = NULL;
250 _Unwind_Word utmp;
251
252 /* g++ v2 "eh" has pointer immediately following augmentation string,
253 so it must be handled first. */
254 if (aug[0] == 'e' && aug[1] == 'h')
255 {
256 fs->eh_ptr = read_pointer (p);
257 p += sizeof (void *);
258 aug += 2;
259 }
260
261 /* Immediately following the augmentation are the code and
262 data alignment and return address column. */
263 p = read_uleb128 (p, val: &fs->code_align);
264 p = read_sleb128 (p, val: &fs->data_align);
265 fs->retaddr_column = *p++;
266 fs->lsda_encoding = DW_EH_PE_omit;
267
268 /* If the augmentation starts with 'z', then a uleb128 immediately
269 follows containing the length of the augmentation field following
270 the size. */
271 if (*aug == 'z')
272 {
273 p = read_uleb128 (p, val: &utmp);
274 ret = p + utmp;
275
276 fs->saw_z = 1;
277 ++aug;
278 }
279
280 /* Iterate over recognized augmentation subsequences. */
281 while (*aug != '\0')
282 {
283 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
284 if (aug[0] == 'L')
285 {
286 fs->lsda_encoding = *p++;
287 aug += 1;
288 }
289
290 /* "R" indicates a byte indicating how FDE addresses are encoded. */
291 else if (aug[0] == 'R')
292 {
293 fs->fde_encoding = *p++;
294 aug += 1;
295 }
296
297 /* "P" indicates a personality routine in the CIE augmentation. */
298 else if (aug[0] == 'P')
299 {
300 _Unwind_Ptr personality;
301 p = read_encoded_value (context, encoding: *p, p: p + 1, val: &personality);
302 fs->personality = (_Unwind_Personality_Fn) personality;
303 aug += 1;
304 }
305
306 /* Otherwise we have an unknown augmentation string.
307 Bail unless we saw a 'z' prefix. */
308 else
309 return ret;
310 }
311
312 return ret ? ret : p;
313}
314
315#ifndef _LIBC
316/* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
317 onto the stack to start. */
318
319static _Unwind_Word
320execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
321 struct _Unwind_Context *context, _Unwind_Word initial)
322{
323 _Unwind_Word stack[64]; /* ??? Assume this is enough. */
324 int stack_elt;
325
326 stack[0] = initial;
327 stack_elt = 1;
328
329 while (op_ptr < op_end)
330 {
331 enum dwarf_location_atom op = *op_ptr++;
332 _Unwind_Word result, reg, utmp;
333 _Unwind_Sword offset, stmp;
334
335 switch (op)
336 {
337 case DW_OP_lit0:
338 case DW_OP_lit1:
339 case DW_OP_lit2:
340 case DW_OP_lit3:
341 case DW_OP_lit4:
342 case DW_OP_lit5:
343 case DW_OP_lit6:
344 case DW_OP_lit7:
345 case DW_OP_lit8:
346 case DW_OP_lit9:
347 case DW_OP_lit10:
348 case DW_OP_lit11:
349 case DW_OP_lit12:
350 case DW_OP_lit13:
351 case DW_OP_lit14:
352 case DW_OP_lit15:
353 case DW_OP_lit16:
354 case DW_OP_lit17:
355 case DW_OP_lit18:
356 case DW_OP_lit19:
357 case DW_OP_lit20:
358 case DW_OP_lit21:
359 case DW_OP_lit22:
360 case DW_OP_lit23:
361 case DW_OP_lit24:
362 case DW_OP_lit25:
363 case DW_OP_lit26:
364 case DW_OP_lit27:
365 case DW_OP_lit28:
366 case DW_OP_lit29:
367 case DW_OP_lit30:
368 case DW_OP_lit31:
369 result = op - DW_OP_lit0;
370 break;
371
372 case DW_OP_addr:
373 result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
374 op_ptr += sizeof (void *);
375 break;
376
377 case DW_OP_const1u:
378 result = read_1u (op_ptr);
379 op_ptr += 1;
380 break;
381 case DW_OP_const1s:
382 result = read_1s (op_ptr);
383 op_ptr += 1;
384 break;
385 case DW_OP_const2u:
386 result = read_2u (op_ptr);
387 op_ptr += 2;
388 break;
389 case DW_OP_const2s:
390 result = read_2s (op_ptr);
391 op_ptr += 2;
392 break;
393 case DW_OP_const4u:
394 result = read_4u (op_ptr);
395 op_ptr += 4;
396 break;
397 case DW_OP_const4s:
398 result = read_4s (op_ptr);
399 op_ptr += 4;
400 break;
401 case DW_OP_const8u:
402 result = read_8u (op_ptr);
403 op_ptr += 8;
404 break;
405 case DW_OP_const8s:
406 result = read_8s (op_ptr);
407 op_ptr += 8;
408 break;
409 case DW_OP_constu:
410 op_ptr = read_uleb128 (op_ptr, &result);
411 break;
412 case DW_OP_consts:
413 op_ptr = read_sleb128 (op_ptr, &stmp);
414 result = stmp;
415 break;
416
417 case DW_OP_reg0:
418 case DW_OP_reg1:
419 case DW_OP_reg2:
420 case DW_OP_reg3:
421 case DW_OP_reg4:
422 case DW_OP_reg5:
423 case DW_OP_reg6:
424 case DW_OP_reg7:
425 case DW_OP_reg8:
426 case DW_OP_reg9:
427 case DW_OP_reg10:
428 case DW_OP_reg11:
429 case DW_OP_reg12:
430 case DW_OP_reg13:
431 case DW_OP_reg14:
432 case DW_OP_reg15:
433 case DW_OP_reg16:
434 case DW_OP_reg17:
435 case DW_OP_reg18:
436 case DW_OP_reg19:
437 case DW_OP_reg20:
438 case DW_OP_reg21:
439 case DW_OP_reg22:
440 case DW_OP_reg23:
441 case DW_OP_reg24:
442 case DW_OP_reg25:
443 case DW_OP_reg26:
444 case DW_OP_reg27:
445 case DW_OP_reg28:
446 case DW_OP_reg29:
447 case DW_OP_reg30:
448 case DW_OP_reg31:
449 result = _Unwind_GetGR (context, op - DW_OP_reg0);
450 break;
451 case DW_OP_regx:
452 op_ptr = read_uleb128 (op_ptr, &reg);
453 result = _Unwind_GetGR (context, reg);
454 break;
455
456 case DW_OP_breg0:
457 case DW_OP_breg1:
458 case DW_OP_breg2:
459 case DW_OP_breg3:
460 case DW_OP_breg4:
461 case DW_OP_breg5:
462 case DW_OP_breg6:
463 case DW_OP_breg7:
464 case DW_OP_breg8:
465 case DW_OP_breg9:
466 case DW_OP_breg10:
467 case DW_OP_breg11:
468 case DW_OP_breg12:
469 case DW_OP_breg13:
470 case DW_OP_breg14:
471 case DW_OP_breg15:
472 case DW_OP_breg16:
473 case DW_OP_breg17:
474 case DW_OP_breg18:
475 case DW_OP_breg19:
476 case DW_OP_breg20:
477 case DW_OP_breg21:
478 case DW_OP_breg22:
479 case DW_OP_breg23:
480 case DW_OP_breg24:
481 case DW_OP_breg25:
482 case DW_OP_breg26:
483 case DW_OP_breg27:
484 case DW_OP_breg28:
485 case DW_OP_breg29:
486 case DW_OP_breg30:
487 case DW_OP_breg31:
488 op_ptr = read_sleb128 (op_ptr, &offset);
489 result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
490 break;
491 case DW_OP_bregx:
492 op_ptr = read_uleb128 (op_ptr, &reg);
493 op_ptr = read_sleb128 (op_ptr, &offset);
494 result = _Unwind_GetGR (context, reg) + offset;
495 break;
496
497 case DW_OP_dup:
498 if (stack_elt < 1)
499 abort ();
500 result = stack[stack_elt - 1];
501 break;
502
503 case DW_OP_drop:
504 if (--stack_elt < 0)
505 abort ();
506 goto no_push;
507
508 case DW_OP_pick:
509 offset = *op_ptr++;
510 if (offset >= stack_elt - 1)
511 abort ();
512 result = stack[stack_elt - 1 - offset];
513 break;
514
515 case DW_OP_over:
516 if (stack_elt < 2)
517 abort ();
518 result = stack[stack_elt - 2];
519 break;
520
521 case DW_OP_rot:
522 {
523 _Unwind_Word t1, t2, t3;
524
525 if (stack_elt < 3)
526 abort ();
527 t1 = stack[stack_elt - 1];
528 t2 = stack[stack_elt - 2];
529 t3 = stack[stack_elt - 3];
530 stack[stack_elt - 1] = t2;
531 stack[stack_elt - 2] = t3;
532 stack[stack_elt - 3] = t1;
533 goto no_push;
534 }
535
536 case DW_OP_deref:
537 case DW_OP_deref_size:
538 case DW_OP_abs:
539 case DW_OP_neg:
540 case DW_OP_not:
541 case DW_OP_plus_uconst:
542 /* Unary operations. */
543 if (--stack_elt < 0)
544 abort ();
545 result = stack[stack_elt];
546
547 switch (op)
548 {
549 case DW_OP_deref:
550 {
551 void *ptr = (void *) (_Unwind_Ptr) result;
552 result = (_Unwind_Ptr) read_pointer (ptr);
553 }
554 break;
555
556 case DW_OP_deref_size:
557 {
558 void *ptr = (void *) (_Unwind_Ptr) result;
559 switch (*op_ptr++)
560 {
561 case 1:
562 result = read_1u (ptr);
563 break;
564 case 2:
565 result = read_2u (ptr);
566 break;
567 case 4:
568 result = read_4u (ptr);
569 break;
570 case 8:
571 result = read_8u (ptr);
572 break;
573 default:
574 abort ();
575 }
576 }
577 break;
578
579 case DW_OP_abs:
580 if ((_Unwind_Sword) result < 0)
581 result = -result;
582 break;
583 case DW_OP_neg:
584 result = -result;
585 break;
586 case DW_OP_not:
587 result = ~result;
588 break;
589 case DW_OP_plus_uconst:
590 op_ptr = read_uleb128 (op_ptr, &utmp);
591 result += utmp;
592 break;
593
594 default:
595 abort ();
596 }
597 break;
598
599 case DW_OP_and:
600 case DW_OP_div:
601 case DW_OP_minus:
602 case DW_OP_mod:
603 case DW_OP_mul:
604 case DW_OP_or:
605 case DW_OP_plus:
606 case DW_OP_le:
607 case DW_OP_ge:
608 case DW_OP_eq:
609 case DW_OP_lt:
610 case DW_OP_gt:
611 case DW_OP_ne:
612 {
613 /* Binary operations. */
614 _Unwind_Word first, second;
615 if ((stack_elt -= 2) < 0)
616 abort ();
617 second = stack[stack_elt];
618 first = stack[stack_elt + 1];
619
620 switch (op)
621 {
622 case DW_OP_and:
623 result = second & first;
624 break;
625 case DW_OP_div:
626 result = (_Unwind_Sword) second / (_Unwind_Sword) first;
627 break;
628 case DW_OP_minus:
629 result = second - first;
630 break;
631 case DW_OP_mod:
632 result = (_Unwind_Sword) second % (_Unwind_Sword) first;
633 break;
634 case DW_OP_mul:
635 result = second * first;
636 break;
637 case DW_OP_or:
638 result = second | first;
639 break;
640 case DW_OP_plus:
641 result = second + first;
642 break;
643 case DW_OP_shl:
644 result = second << first;
645 break;
646 case DW_OP_shr:
647 result = second >> first;
648 break;
649 case DW_OP_shra:
650 result = (_Unwind_Sword) second >> first;
651 break;
652 case DW_OP_xor:
653 result = second ^ first;
654 break;
655 case DW_OP_le:
656 result = (_Unwind_Sword) first <= (_Unwind_Sword) second;
657 break;
658 case DW_OP_ge:
659 result = (_Unwind_Sword) first >= (_Unwind_Sword) second;
660 break;
661 case DW_OP_eq:
662 result = (_Unwind_Sword) first == (_Unwind_Sword) second;
663 break;
664 case DW_OP_lt:
665 result = (_Unwind_Sword) first < (_Unwind_Sword) second;
666 break;
667 case DW_OP_gt:
668 result = (_Unwind_Sword) first > (_Unwind_Sword) second;
669 break;
670 case DW_OP_ne:
671 result = (_Unwind_Sword) first != (_Unwind_Sword) second;
672 break;
673
674 default:
675 abort ();
676 }
677 }
678 break;
679
680 case DW_OP_skip:
681 offset = read_2s (op_ptr);
682 op_ptr += 2;
683 op_ptr += offset;
684 goto no_push;
685
686 case DW_OP_bra:
687 if (--stack_elt < 0)
688 abort ();
689 offset = read_2s (op_ptr);
690 op_ptr += 2;
691 if (stack[stack_elt] != 0)
692 op_ptr += offset;
693 goto no_push;
694
695 case DW_OP_nop:
696 goto no_push;
697
698 default:
699 abort ();
700 }
701
702 /* Most things push a result value. */
703 if ((size_t) stack_elt >= sizeof (stack) / sizeof (*stack))
704 abort ();
705 stack[stack_elt++] = result;
706 no_push:;
707 }
708
709 /* We were executing this program to get a value. It should be
710 at top of stack. */
711 if (--stack_elt < 0)
712 abort ();
713 return stack[stack_elt];
714}
715#endif
716
717/* Decode DWARF 2 call frame information. Takes pointers the
718 instruction sequence to decode, current register information and
719 CIE info, and the PC range to evaluate. */
720
721static void
722execute_cfa_program (const unsigned char *insn_ptr,
723 const unsigned char *insn_end,
724 struct _Unwind_Context *context,
725 _Unwind_FrameState *fs)
726{
727 struct frame_state_reg_info *unused_rs = NULL;
728
729 /* Don't allow remember/restore between CIE and FDE programs. */
730 fs->regs.prev = NULL;
731
732 /* The comparison with the return address uses < rather than <= because
733 we are only interested in the effects of code before the call; for a
734 noreturn function, the return address may point to unrelated code with
735 a different stack configuration that we are not interested in. We
736 assume that the call itself is unwind info-neutral; if not, or if
737 there are delay instructions that adjust the stack, these must be
738 reflected at the point immediately before the call insn. */
739 while (insn_ptr < insn_end && fs->pc < context->ra)
740 {
741 unsigned char insn = *insn_ptr++;
742 _Unwind_Word reg, utmp;
743 _Unwind_Sword offset, stmp;
744
745 if ((insn & 0xc0) == DW_CFA_advance_loc)
746 fs->pc += (insn & 0x3f) * fs->code_align;
747 else if ((insn & 0xc0) == DW_CFA_offset)
748 {
749 reg = insn & 0x3f;
750 insn_ptr = read_uleb128 (p: insn_ptr, val: &utmp);
751 offset = (_Unwind_Sword) utmp * fs->data_align;
752 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
753 fs->regs.reg[reg].loc.offset = offset;
754 }
755 else if ((insn & 0xc0) == DW_CFA_restore)
756 {
757 reg = insn & 0x3f;
758 fs->regs.reg[reg].how = REG_UNSAVED;
759 }
760 else switch (insn)
761 {
762 case DW_CFA_set_loc:
763 {
764 _Unwind_Ptr pc;
765 insn_ptr = read_encoded_value (context, encoding: fs->fde_encoding,
766 p: insn_ptr, val: &pc);
767 fs->pc = (void *) pc;
768 }
769 break;
770
771 case DW_CFA_advance_loc1:
772 fs->pc += read_1u (p: insn_ptr) * fs->code_align;
773 insn_ptr += 1;
774 break;
775 case DW_CFA_advance_loc2:
776 fs->pc += read_2u (p: insn_ptr) * fs->code_align;
777 insn_ptr += 2;
778 break;
779 case DW_CFA_advance_loc4:
780 fs->pc += read_4u (p: insn_ptr) * fs->code_align;
781 insn_ptr += 4;
782 break;
783
784 case DW_CFA_offset_extended:
785 insn_ptr = read_uleb128 (p: insn_ptr, val: &reg);
786 insn_ptr = read_uleb128 (p: insn_ptr, val: &utmp);
787 offset = (_Unwind_Sword) utmp * fs->data_align;
788 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
789 fs->regs.reg[reg].loc.offset = offset;
790 break;
791
792 case DW_CFA_restore_extended:
793 insn_ptr = read_uleb128 (p: insn_ptr, val: &reg);
794 fs->regs.reg[reg].how = REG_UNSAVED;
795 break;
796
797 case DW_CFA_undefined:
798 case DW_CFA_same_value:
799 insn_ptr = read_uleb128 (p: insn_ptr, val: &reg);
800 break;
801
802 case DW_CFA_nop:
803 break;
804
805 case DW_CFA_register:
806 {
807 _Unwind_Word reg2;
808 insn_ptr = read_uleb128 (p: insn_ptr, val: &reg);
809 insn_ptr = read_uleb128 (p: insn_ptr, val: &reg2);
810 fs->regs.reg[reg].how = REG_SAVED_REG;
811 fs->regs.reg[reg].loc.reg = reg2;
812 }
813 break;
814
815 case DW_CFA_remember_state:
816 {
817 struct frame_state_reg_info *new_rs;
818 if (unused_rs)
819 {
820 new_rs = unused_rs;
821 unused_rs = unused_rs->prev;
822 }
823 else
824 new_rs = __builtin_alloca (sizeof (struct frame_state_reg_info));
825
826 *new_rs = fs->regs;
827 fs->regs.prev = new_rs;
828 }
829 break;
830
831 case DW_CFA_restore_state:
832 {
833 struct frame_state_reg_info *old_rs = fs->regs.prev;
834#ifdef _LIBC
835 if (old_rs == NULL)
836 __libc_fatal ("Invalid DWARF unwind data.\n");
837 else
838#endif
839 {
840 fs->regs = *old_rs;
841 old_rs->prev = unused_rs;
842 unused_rs = old_rs;
843 }
844 }
845 break;
846
847 case DW_CFA_def_cfa:
848 insn_ptr = read_uleb128 (p: insn_ptr, val: &fs->cfa_reg);
849 insn_ptr = read_uleb128 (p: insn_ptr, val: &utmp);
850 fs->cfa_offset = utmp;
851 fs->cfa_how = CFA_REG_OFFSET;
852 break;
853
854 case DW_CFA_def_cfa_register:
855 insn_ptr = read_uleb128 (p: insn_ptr, val: &fs->cfa_reg);
856 fs->cfa_how = CFA_REG_OFFSET;
857 break;
858
859 case DW_CFA_def_cfa_offset:
860 insn_ptr = read_uleb128 (p: insn_ptr, val: &utmp);
861 fs->cfa_offset = utmp;
862 /* cfa_how deliberately not set. */
863 break;
864
865 case DW_CFA_def_cfa_expression:
866 fs->cfa_exp = insn_ptr;
867 fs->cfa_how = CFA_EXP;
868 insn_ptr = read_uleb128 (p: insn_ptr, val: &utmp);
869 insn_ptr += utmp;
870 break;
871
872 case DW_CFA_expression:
873 insn_ptr = read_uleb128 (p: insn_ptr, val: &reg);
874 fs->regs.reg[reg].how = REG_SAVED_EXP;
875 fs->regs.reg[reg].loc.exp = insn_ptr;
876 insn_ptr = read_uleb128 (p: insn_ptr, val: &utmp);
877 insn_ptr += utmp;
878 break;
879
880 /* From the 2.1 draft. */
881 case DW_CFA_offset_extended_sf:
882 insn_ptr = read_uleb128 (p: insn_ptr, val: &reg);
883 insn_ptr = read_sleb128 (p: insn_ptr, val: &stmp);
884 offset = stmp * fs->data_align;
885 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
886 fs->regs.reg[reg].loc.offset = offset;
887 break;
888
889 case DW_CFA_def_cfa_sf:
890 insn_ptr = read_uleb128 (p: insn_ptr, val: &fs->cfa_reg);
891 insn_ptr = read_sleb128 (p: insn_ptr, val: &fs->cfa_offset);
892 fs->cfa_how = CFA_REG_OFFSET;
893 break;
894
895 case DW_CFA_def_cfa_offset_sf:
896 insn_ptr = read_sleb128 (p: insn_ptr, val: &fs->cfa_offset);
897 /* cfa_how deliberately not set. */
898 break;
899
900 case DW_CFA_GNU_window_save:
901 /* ??? Hardcoded for SPARC register window configuration.
902 At least do not do anything for archs which explicitly
903 define a lower register number. */
904#if DWARF_FRAME_REGISTERS >= 32
905 for (reg = 16; reg < 32; ++reg)
906 {
907 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
908 fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
909 }
910#endif
911 break;
912
913 case DW_CFA_GNU_args_size:
914 insn_ptr = read_uleb128 (p: insn_ptr, val: &context->args_size);
915 break;
916
917 case DW_CFA_GNU_negative_offset_extended:
918 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
919 older PowerPC code. */
920 insn_ptr = read_uleb128 (p: insn_ptr, val: &reg);
921 insn_ptr = read_uleb128 (p: insn_ptr, val: &utmp);
922 offset = (_Unwind_Word) utmp * fs->data_align;
923 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
924 fs->regs.reg[reg].loc.offset = -offset;
925 break;
926
927 default:
928 abort ();
929 }
930 }
931}
932
933/* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
934 its caller and decode it into FS. This function also sets the
935 args_size and lsda members of CONTEXT, as they are really information
936 about the caller's frame. */
937
938static _Unwind_Reason_Code
939uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
940{
941 struct dwarf_fde *fde;
942 struct dwarf_cie *cie;
943 const unsigned char *aug, *insn, *end;
944
945 memset (fs, 0, sizeof (*fs));
946 context->args_size = 0;
947 context->lsda = 0;
948
949 fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
950 if (fde == NULL)
951 {
952 /* Couldn't find frame unwind info for this function. Try a
953 target-specific fallback mechanism. This will necessarily
954 not provide a personality routine or LSDA. */
955#ifdef MD_FALLBACK_FRAME_STATE_FOR
956 MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
957 return _URC_END_OF_STACK;
958 success:
959 return _URC_NO_REASON;
960#else
961 return _URC_END_OF_STACK;
962#endif
963 }
964
965 fs->pc = context->bases.func;
966
967 cie = get_cie (f: fde);
968 insn = extract_cie_info (cie, context, fs);
969 if (insn == NULL)
970 /* CIE contained unknown augmentation. */
971 return _URC_FATAL_PHASE1_ERROR;
972
973 /* First decode all the insns in the CIE. */
974 end = (unsigned char *) next_fde (f: (struct dwarf_fde *) cie);
975 execute_cfa_program (insn_ptr: insn, insn_end: end, context, fs);
976
977 /* Locate augmentation for the fde. */
978 aug = (unsigned char *) fde + sizeof (*fde);
979 aug += 2 * size_of_encoded_value (encoding: fs->fde_encoding);
980 insn = NULL;
981 if (fs->saw_z)
982 {
983 _Unwind_Word i;
984 aug = read_uleb128 (p: aug, val: &i);
985 insn = aug + i;
986 }
987 if (fs->lsda_encoding != DW_EH_PE_omit)
988 {
989 _Unwind_Ptr lsda;
990 aug = read_encoded_value (context, encoding: fs->lsda_encoding, p: aug, val: &lsda);
991 context->lsda = (void *) lsda;
992 }
993
994 /* Then the insns in the FDE up to our target PC. */
995 if (insn == NULL)
996 insn = aug;
997 end = (unsigned char *) next_fde (f: fde);
998 execute_cfa_program (insn_ptr: insn, insn_end: end, context, fs);
999
1000 return _URC_NO_REASON;
1001}
1002
1003typedef struct frame_state
1004{
1005 void *cfa;
1006 void *eh_ptr;
1007 long cfa_offset;
1008 long args_size;
1009 long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1010 unsigned short cfa_reg;
1011 unsigned short retaddr_column;
1012 char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1013} frame_state;
1014
1015#ifndef STATIC
1016# define STATIC
1017#endif
1018
1019STATIC
1020struct frame_state * __frame_state_for (void *, struct frame_state *);
1021
1022/* Called from pre-G++ 3.0 __throw to find the registers to restore for
1023 a given PC_TARGET. The caller should allocate a local variable of
1024 `struct frame_state' and pass its address to STATE_IN. */
1025
1026STATIC
1027struct frame_state *
1028__frame_state_for (void *pc_target, struct frame_state *state_in)
1029{
1030 struct _Unwind_Context context;
1031 _Unwind_FrameState fs;
1032 int reg;
1033
1034 memset (&context, 0, sizeof (struct _Unwind_Context));
1035 context.ra = pc_target + 1;
1036
1037 if (uw_frame_state_for (context: &context, fs: &fs) != _URC_NO_REASON)
1038 return 0;
1039
1040 /* We have no way to pass a location expression for the CFA to our
1041 caller. It wouldn't understand it anyway. */
1042 if (fs.cfa_how == CFA_EXP)
1043 return 0;
1044
1045 for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
1046 {
1047 state_in->saved[reg] = fs.regs.reg[reg].how;
1048 switch (state_in->saved[reg])
1049 {
1050 case REG_SAVED_REG:
1051 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
1052 break;
1053 case REG_SAVED_OFFSET:
1054 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
1055 break;
1056 default:
1057 state_in->reg_or_offset[reg] = 0;
1058 break;
1059 }
1060 }
1061
1062 state_in->cfa_offset = fs.cfa_offset;
1063 state_in->cfa_reg = fs.cfa_reg;
1064 state_in->retaddr_column = fs.retaddr_column;
1065 state_in->args_size = context.args_size;
1066 state_in->eh_ptr = fs.eh_ptr;
1067
1068 return state_in;
1069}
1070
1071#ifndef _LIBC
1072
1073static void
1074uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1075{
1076 struct _Unwind_Context orig_context = *context;
1077 void *cfa;
1078 long i;
1079
1080#ifdef EH_RETURN_STACKADJ_RTX
1081 /* Special handling here: Many machines do not use a frame pointer,
1082 and track the CFA only through offsets from the stack pointer from
1083 one frame to the next. In this case, the stack pointer is never
1084 stored, so it has no saved address in the context. What we do
1085 have is the CFA from the previous stack frame.
1086
1087 In very special situations (such as unwind info for signal return),
1088 there may be location expressions that use the stack pointer as well.
1089
1090 Do this conditionally for one frame. This allows the unwind info
1091 for one frame to save a copy of the stack pointer from the previous
1092 frame, and be able to use much easier CFA mechanisms to do it.
1093 Always zap the saved stack pointer value for the next frame; carrying
1094 the value over from one frame to another doesn't make sense. */
1095
1096 _Unwind_Word tmp_sp;
1097
1098 if (!orig_context.reg[__builtin_dwarf_sp_column ()])
1099 {
1100 tmp_sp = (_Unwind_Ptr) context->cfa;
1101 orig_context.reg[__builtin_dwarf_sp_column ()] = &tmp_sp;
1102 }
1103 context->reg[__builtin_dwarf_sp_column ()] = NULL;
1104#endif
1105
1106 /* Compute this frame's CFA. */
1107 switch (fs->cfa_how)
1108 {
1109 case CFA_REG_OFFSET:
1110 cfa = (void *) (_Unwind_Ptr) _Unwind_GetGR (&orig_context, fs->cfa_reg);
1111 cfa += fs->cfa_offset;
1112 break;
1113
1114 case CFA_EXP:
1115 {
1116 const unsigned char *exp = fs->cfa_exp;
1117 _Unwind_Word len;
1118
1119 exp = read_uleb128 (exp, &len);
1120 cfa = (void *) (_Unwind_Ptr)
1121 execute_stack_op (exp, exp + len, &orig_context, 0);
1122 break;
1123 }
1124
1125 default:
1126 abort ();
1127 }
1128 context->cfa = cfa;
1129
1130 /* Compute the addresses of all registers saved in this frame. */
1131 for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
1132 switch (fs->regs.reg[i].how)
1133 {
1134 case REG_UNSAVED:
1135 break;
1136
1137 case REG_SAVED_OFFSET:
1138 context->reg[i] = cfa + fs->regs.reg[i].loc.offset;
1139 break;
1140
1141 case REG_SAVED_REG:
1142 context->reg[i] = orig_context.reg[fs->regs.reg[i].loc.reg];
1143 break;
1144
1145 case REG_SAVED_EXP:
1146 {
1147 const unsigned char *exp = fs->regs.reg[i].loc.exp;
1148 _Unwind_Word len;
1149 _Unwind_Ptr val;
1150
1151 exp = read_uleb128 (exp, &len);
1152 val = execute_stack_op (exp, exp + len, &orig_context,
1153 (_Unwind_Ptr) cfa);
1154 context->reg[i] = (void *) val;
1155 }
1156 break;
1157 }
1158}
1159
1160/* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1161 of its caller. Update CONTEXT to refer to the caller as well. Note
1162 that the args_size and lsda members are not updated here, but later in
1163 uw_frame_state_for. */
1164
1165static void
1166uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1167{
1168 uw_update_context_1 (context, fs);
1169
1170 /* Compute the return address now, since the return address column
1171 can change from frame to frame. */
1172 context->ra = __builtin_extract_return_addr
1173 ((void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->retaddr_column));
1174}
1175
1176/* Fill in CONTEXT for top-of-stack. The only valid registers at this
1177 level will be the return address and the CFA. */
1178
1179#define uw_init_context(CONTEXT) \
1180 do \
1181 { \
1182 /* Do any necessary initialization to access arbitrary stack frames. \
1183 On the SPARC, this means flushing the register windows. */ \
1184 __builtin_unwind_init (); \
1185 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1186 __builtin_return_address (0)); \
1187 } \
1188 while (0)
1189
1190static void
1191uw_init_context_1 (struct _Unwind_Context *context,
1192 void *outer_cfa, void *outer_ra)
1193{
1194 void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
1195 _Unwind_FrameState fs;
1196 _Unwind_Word sp_slot;
1197
1198 memset (context, 0, sizeof (struct _Unwind_Context));
1199 context->ra = ra;
1200
1201 if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
1202 abort ();
1203
1204 /* Force the frame state to use the known cfa value. */
1205 sp_slot = (_Unwind_Ptr) outer_cfa;
1206 context->reg[__builtin_dwarf_sp_column ()] = &sp_slot;
1207 fs.cfa_how = CFA_REG_OFFSET;
1208 fs.cfa_reg = __builtin_dwarf_sp_column ();
1209 fs.cfa_offset = 0;
1210
1211 uw_update_context_1 (context, &fs);
1212
1213 /* If the return address column was saved in a register in the
1214 initialization context, then we can't see it in the given
1215 call frame data. So have the initialization context tell us. */
1216 context->ra = __builtin_extract_return_addr (outer_ra);
1217}
1218
1219
1220/* Install TARGET into CURRENT so that we can return to it. This is a
1221 macro because __builtin_eh_return must be invoked in the context of
1222 our caller. */
1223
1224#define uw_install_context(CURRENT, TARGET) \
1225 do \
1226 { \
1227 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1228 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1229 __builtin_eh_return (offset, handler); \
1230 } \
1231 while (0)
1232
1233static inline void
1234init_dwarf_reg_size_table (void)
1235{
1236 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
1237}
1238
1239static long
1240uw_install_context_1 (struct _Unwind_Context *current,
1241 struct _Unwind_Context *target)
1242{
1243 long i;
1244
1245#if __GTHREADS
1246 {
1247 static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
1248 if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
1249 || dwarf_reg_size_table[0] == 0)
1250 init_dwarf_reg_size_table ();
1251 }
1252#else
1253 if (dwarf_reg_size_table[0] == 0)
1254 init_dwarf_reg_size_table ();
1255#endif
1256
1257 for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
1258 {
1259 void *c = current->reg[i];
1260 void *t = target->reg[i];
1261 if (t && c && t != c)
1262 memcpy (c, t, dwarf_reg_size_table[i]);
1263 }
1264
1265#ifdef EH_RETURN_STACKADJ_RTX
1266 {
1267 void *target_cfa;
1268
1269 /* If the last frame records a saved stack pointer, use it. */
1270 if (target->reg[__builtin_dwarf_sp_column ()])
1271 target_cfa = (void *)(_Unwind_Ptr)
1272 _Unwind_GetGR (target, __builtin_dwarf_sp_column ());
1273 else
1274 target_cfa = target->cfa;
1275
1276 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1277 if (STACK_GROWS_DOWNWARD)
1278 return target_cfa - current->cfa + target->args_size;
1279 else
1280 return current->cfa - target_cfa - target->args_size;
1281 }
1282#else
1283 return 0;
1284#endif
1285}
1286
1287static inline _Unwind_Ptr
1288uw_identify_context (struct _Unwind_Context *context)
1289{
1290 return _Unwind_GetIP (context);
1291}
1292
1293
1294#include "unwind.inc"
1295
1296#endif /* _LIBC */
1297

source code of glibc/sysdeps/generic/unwind-dw2.c