1/* DWARF2 exception handling and frame unwind runtime interface routines.
2 Copyright (C) 1997-2022 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#ifndef __ia64__
228_Unwind_Ptr
229_Unwind_GetDataRelBase (struct _Unwind_Context *context)
230{
231 return (_Unwind_Ptr) context->bases.dbase;
232}
233
234_Unwind_Ptr
235_Unwind_GetTextRelBase (struct _Unwind_Context *context)
236{
237 return (_Unwind_Ptr) context->bases.tbase;
238}
239#endif
240
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. */
244
245static const unsigned char *
246extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
247 _Unwind_FrameState *fs)
248{
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;
253
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')
257 {
258 fs->eh_ptr = read_pointer (p);
259 p += sizeof (void *);
260 aug += 2;
261 }
262
263 /* Immediately following the augmentation are the code and
264 data alignment and return address column. */
265 p = read_uleb128 (p, val: &fs->code_align);
266 p = read_sleb128 (p, val: &fs->data_align);
267 fs->retaddr_column = *p++;
268 fs->lsda_encoding = DW_EH_PE_omit;
269
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')
274 {
275 p = read_uleb128 (p, val: &utmp);
276 ret = p + utmp;
277
278 fs->saw_z = 1;
279 ++aug;
280 }
281
282 /* Iterate over recognized augmentation subsequences. */
283 while (*aug != '\0')
284 {
285 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
286 if (aug[0] == 'L')
287 {
288 fs->lsda_encoding = *p++;
289 aug += 1;
290 }
291
292 /* "R" indicates a byte indicating how FDE addresses are encoded. */
293 else if (aug[0] == 'R')
294 {
295 fs->fde_encoding = *p++;
296 aug += 1;
297 }
298
299 /* "P" indicates a personality routine in the CIE augmentation. */
300 else if (aug[0] == 'P')
301 {
302 _Unwind_Ptr personality;
303 p = read_encoded_value (context, encoding: *p, p: p + 1, val: &personality);
304 fs->personality = (_Unwind_Personality_Fn) personality;
305 aug += 1;
306 }
307
308 /* Otherwise we have an unknown augmentation string.
309 Bail unless we saw a 'z' prefix. */
310 else
311 return ret;
312 }
313
314 return ret ? ret : p;
315}
316
317#ifndef _LIBC
318/* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
319 onto the stack to start. */
320
321static _Unwind_Word
322execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
323 struct _Unwind_Context *context, _Unwind_Word initial)
324{
325 _Unwind_Word stack[64]; /* ??? Assume this is enough. */
326 int stack_elt;
327
328 stack[0] = initial;
329 stack_elt = 1;
330
331 while (op_ptr < op_end)
332 {
333 enum dwarf_location_atom op = *op_ptr++;
334 _Unwind_Word result, reg, utmp;
335 _Unwind_Sword offset, stmp;
336
337 switch (op)
338 {
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;
373
374 case DW_OP_addr:
375 result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
376 op_ptr += sizeof (void *);
377 break;
378
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;
418
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;
457
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;
498
499 case DW_OP_dup:
500 if (stack_elt < 1)
501 abort ();
502 result = stack[stack_elt - 1];
503 break;
504
505 case DW_OP_drop:
506 if (--stack_elt < 0)
507 abort ();
508 goto no_push;
509
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;
516
517 case DW_OP_over:
518 if (stack_elt < 2)
519 abort ();
520 result = stack[stack_elt - 2];
521 break;
522
523 case DW_OP_rot:
524 {
525 _Unwind_Word t1, t2, t3;
526
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;
536 }
537
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];
548
549 switch (op)
550 {
551 case DW_OP_deref:
552 {
553 void *ptr = (void *) (_Unwind_Ptr) result;
554 result = (_Unwind_Ptr) read_pointer (ptr);
555 }
556 break;
557
558 case DW_OP_deref_size:
559 {
560 void *ptr = (void *) (_Unwind_Ptr) result;
561 switch (*op_ptr++)
562 {
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 ();
577 }
578 }
579 break;
580
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;
595
596 default:
597 abort ();
598 }
599 break;
600
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:
614 {
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];
621
622 switch (op)
623 {
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;
675
676 default:
677 abort ();
678 }
679 }
680 break;
681
682 case DW_OP_skip:
683 offset = read_2s (op_ptr);
684 op_ptr += 2;
685 op_ptr += offset;
686 goto no_push;
687
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;
696
697 case DW_OP_nop:
698 goto no_push;
699
700 default:
701 abort ();
702 }
703
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:;
709 }
710
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];
716}
717#endif
718
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. */
722
723static void
724execute_cfa_program (const unsigned char *insn_ptr,
725 const unsigned char *insn_end,
726 struct _Unwind_Context *context,
727 _Unwind_FrameState *fs)
728{
729 struct frame_state_reg_info *unused_rs = NULL;
730
731 /* Don't allow remember/restore between CIE and FDE programs. */
732 fs->regs.prev = NULL;
733
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)
742 {
743 unsigned char insn = *insn_ptr++;
744 _Unwind_Word reg, utmp;
745 _Unwind_Sword offset, stmp;
746
747 if ((insn & 0xc0) == DW_CFA_advance_loc)
748 fs->pc += (insn & 0x3f) * fs->code_align;
749 else if ((insn & 0xc0) == DW_CFA_offset)
750 {
751 reg = insn & 0x3f;
752 insn_ptr = read_uleb128 (p: insn_ptr, val: &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;
756 }
757 else if ((insn & 0xc0) == DW_CFA_restore)
758 {
759 reg = insn & 0x3f;
760 fs->regs.reg[reg].how = REG_UNSAVED;
761 }
762 else switch (insn)
763 {
764 case DW_CFA_set_loc:
765 {
766 _Unwind_Ptr pc;
767 insn_ptr = read_encoded_value (context, encoding: fs->fde_encoding,
768 p: insn_ptr, val: &pc);
769 fs->pc = (void *) pc;
770 }
771 break;
772
773 case DW_CFA_advance_loc1:
774 fs->pc += read_1u (p: insn_ptr) * fs->code_align;
775 insn_ptr += 1;
776 break;
777 case DW_CFA_advance_loc2:
778 fs->pc += read_2u (p: insn_ptr) * fs->code_align;
779 insn_ptr += 2;
780 break;
781 case DW_CFA_advance_loc4:
782 fs->pc += read_4u (p: insn_ptr) * fs->code_align;
783 insn_ptr += 4;
784 break;
785
786 case DW_CFA_offset_extended:
787 insn_ptr = read_uleb128 (p: insn_ptr, val: &reg);
788 insn_ptr = read_uleb128 (p: insn_ptr, val: &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;
793
794 case DW_CFA_restore_extended:
795 insn_ptr = read_uleb128 (p: insn_ptr, val: &reg);
796 fs->regs.reg[reg].how = REG_UNSAVED;
797 break;
798
799 case DW_CFA_undefined:
800 case DW_CFA_same_value:
801 insn_ptr = read_uleb128 (p: insn_ptr, val: &reg);
802 break;
803
804 case DW_CFA_nop:
805 break;
806
807 case DW_CFA_register:
808 {
809 _Unwind_Word reg2;
810 insn_ptr = read_uleb128 (p: insn_ptr, val: &reg);
811 insn_ptr = read_uleb128 (p: insn_ptr, val: &reg2);
812 fs->regs.reg[reg].how = REG_SAVED_REG;
813 fs->regs.reg[reg].loc.reg = reg2;
814 }
815 break;
816
817 case DW_CFA_remember_state:
818 {
819 struct frame_state_reg_info *new_rs;
820 if (unused_rs)
821 {
822 new_rs = unused_rs;
823 unused_rs = unused_rs->prev;
824 }
825 else
826 new_rs = __builtin_alloca (sizeof (struct frame_state_reg_info));
827
828 *new_rs = fs->regs;
829 fs->regs.prev = new_rs;
830 }
831 break;
832
833 case DW_CFA_restore_state:
834 {
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
841 {
842 fs->regs = *old_rs;
843 old_rs->prev = unused_rs;
844 unused_rs = old_rs;
845 }
846 }
847 break;
848
849 case DW_CFA_def_cfa:
850 insn_ptr = read_uleb128 (p: insn_ptr, val: &fs->cfa_reg);
851 insn_ptr = read_uleb128 (p: insn_ptr, val: &utmp);
852 fs->cfa_offset = utmp;
853 fs->cfa_how = CFA_REG_OFFSET;
854 break;
855
856 case DW_CFA_def_cfa_register:
857 insn_ptr = read_uleb128 (p: insn_ptr, val: &fs->cfa_reg);
858 fs->cfa_how = CFA_REG_OFFSET;
859 break;
860
861 case DW_CFA_def_cfa_offset:
862 insn_ptr = read_uleb128 (p: insn_ptr, val: &utmp);
863 fs->cfa_offset = utmp;
864 /* cfa_how deliberately not set. */
865 break;
866
867 case DW_CFA_def_cfa_expression:
868 fs->cfa_exp = insn_ptr;
869 fs->cfa_how = CFA_EXP;
870 insn_ptr = read_uleb128 (p: insn_ptr, val: &utmp);
871 insn_ptr += utmp;
872 break;
873
874 case DW_CFA_expression:
875 insn_ptr = read_uleb128 (p: insn_ptr, val: &reg);
876 fs->regs.reg[reg].how = REG_SAVED_EXP;
877 fs->regs.reg[reg].loc.exp = insn_ptr;
878 insn_ptr = read_uleb128 (p: insn_ptr, val: &utmp);
879 insn_ptr += utmp;
880 break;
881
882 /* From the 2.1 draft. */
883 case DW_CFA_offset_extended_sf:
884 insn_ptr = read_uleb128 (p: insn_ptr, val: &reg);
885 insn_ptr = read_sleb128 (p: insn_ptr, val: &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;
890
891 case DW_CFA_def_cfa_sf:
892 insn_ptr = read_uleb128 (p: insn_ptr, val: &fs->cfa_reg);
893 insn_ptr = read_sleb128 (p: insn_ptr, val: &fs->cfa_offset);
894 fs->cfa_how = CFA_REG_OFFSET;
895 break;
896
897 case DW_CFA_def_cfa_offset_sf:
898 insn_ptr = read_sleb128 (p: insn_ptr, val: &fs->cfa_offset);
899 /* cfa_how deliberately not set. */
900 break;
901
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)
908 {
909 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
910 fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
911 }
912#endif
913 break;
914
915 case DW_CFA_GNU_args_size:
916 insn_ptr = read_uleb128 (p: insn_ptr, val: &context->args_size);
917 break;
918
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 (p: insn_ptr, val: &reg);
923 insn_ptr = read_uleb128 (p: insn_ptr, val: &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;
928
929 default:
930 abort ();
931 }
932 }
933}
934
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. */
939
940static _Unwind_Reason_Code
941uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
942{
943 struct dwarf_fde *fde;
944 struct dwarf_cie *cie;
945 const unsigned char *aug, *insn, *end;
946
947 memset (fs, 0, sizeof (*fs));
948 context->args_size = 0;
949 context->lsda = 0;
950
951 fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
952 if (fde == NULL)
953 {
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
965 }
966
967 fs->pc = context->bases.func;
968
969 cie = get_cie (f: fde);
970 insn = extract_cie_info (cie, context, fs);
971 if (insn == NULL)
972 /* CIE contained unknown augmentation. */
973 return _URC_FATAL_PHASE1_ERROR;
974
975 /* First decode all the insns in the CIE. */
976 end = (unsigned char *) next_fde (f: (struct dwarf_fde *) cie);
977 execute_cfa_program (insn_ptr: insn, insn_end: end, context, fs);
978
979 /* Locate augmentation for the fde. */
980 aug = (unsigned char *) fde + sizeof (*fde);
981 aug += 2 * size_of_encoded_value (encoding: fs->fde_encoding);
982 insn = NULL;
983 if (fs->saw_z)
984 {
985 _Unwind_Word i;
986 aug = read_uleb128 (p: aug, val: &i);
987 insn = aug + i;
988 }
989 if (fs->lsda_encoding != DW_EH_PE_omit)
990 {
991 _Unwind_Ptr lsda;
992 aug = read_encoded_value (context, encoding: fs->lsda_encoding, p: aug, val: &lsda);
993 context->lsda = (void *) lsda;
994 }
995
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 (f: fde);
1000 execute_cfa_program (insn_ptr: insn, insn_end: end, context, fs);
1001
1002 return _URC_NO_REASON;
1003}
1004
1005typedef struct frame_state
1006{
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;
1016
1017#ifndef STATIC
1018# define STATIC
1019#endif
1020
1021STATIC
1022struct frame_state * __frame_state_for (void *, struct frame_state *);
1023
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. */
1027
1028STATIC
1029struct frame_state *
1030__frame_state_for (void *pc_target, struct frame_state *state_in)
1031{
1032 struct _Unwind_Context context;
1033 _Unwind_FrameState fs;
1034 int reg;
1035
1036 memset (&context, 0, sizeof (struct _Unwind_Context));
1037 context.ra = pc_target + 1;
1038
1039 if (uw_frame_state_for (context: &context, fs: &fs) != _URC_NO_REASON)
1040 return 0;
1041
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;
1046
1047 for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
1048 {
1049 state_in->saved[reg] = fs.regs.reg[reg].how;
1050 switch (state_in->saved[reg])
1051 {
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;
1061 }
1062 }
1063
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;
1069
1070 return state_in;
1071}
1072
1073#ifndef _LIBC
1074
1075static void
1076uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1077{
1078 struct _Unwind_Context orig_context = *context;
1079 void *cfa;
1080 long i;
1081
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.
1088
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.
1091
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. */
1097
1098 _Unwind_Word tmp_sp;
1099
1100 if (!orig_context.reg[__builtin_dwarf_sp_column ()])
1101 {
1102 tmp_sp = (_Unwind_Ptr) context->cfa;
1103 orig_context.reg[__builtin_dwarf_sp_column ()] = &tmp_sp;
1104 }
1105 context->reg[__builtin_dwarf_sp_column ()] = NULL;
1106#endif
1107
1108 /* Compute this frame's CFA. */
1109 switch (fs->cfa_how)
1110 {
1111 case CFA_REG_OFFSET:
1112 cfa = (void *) (_Unwind_Ptr) _Unwind_GetGR (&orig_context, fs->cfa_reg);
1113 cfa += fs->cfa_offset;
1114 break;
1115
1116 case CFA_EXP:
1117 {
1118 const unsigned char *exp = fs->cfa_exp;
1119 _Unwind_Word len;
1120
1121 exp = read_uleb128 (exp, &len);
1122 cfa = (void *) (_Unwind_Ptr)
1123 execute_stack_op (exp, exp + len, &orig_context, 0);
1124 break;
1125 }
1126
1127 default:
1128 abort ();
1129 }
1130 context->cfa = cfa;
1131
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)
1135 {
1136 case REG_UNSAVED:
1137 break;
1138
1139 case REG_SAVED_OFFSET:
1140 context->reg[i] = cfa + fs->regs.reg[i].loc.offset;
1141 break;
1142
1143 case REG_SAVED_REG:
1144 context->reg[i] = orig_context.reg[fs->regs.reg[i].loc.reg];
1145 break;
1146
1147 case REG_SAVED_EXP:
1148 {
1149 const unsigned char *exp = fs->regs.reg[i].loc.exp;
1150 _Unwind_Word len;
1151 _Unwind_Ptr val;
1152
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;
1157 }
1158 break;
1159 }
1160}
1161
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. */
1166
1167static void
1168uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1169{
1170 uw_update_context_1 (context, fs);
1171
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));
1176}
1177
1178/* Fill in CONTEXT for top-of-stack. The only valid registers at this
1179 level will be the return address and the CFA. */
1180
1181#define uw_init_context(CONTEXT) \
1182 do \
1183 { \
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)); \
1189 } \
1190 while (0)
1191
1192static void
1193uw_init_context_1 (struct _Unwind_Context *context,
1194 void *outer_cfa, void *outer_ra)
1195{
1196 void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
1197 _Unwind_FrameState fs;
1198 _Unwind_Word sp_slot;
1199
1200 memset (context, 0, sizeof (struct _Unwind_Context));
1201 context->ra = ra;
1202
1203 if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
1204 abort ();
1205
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;
1212
1213 uw_update_context_1 (context, &fs);
1214
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);
1219}
1220
1221
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. */
1225
1226#define uw_install_context(CURRENT, TARGET) \
1227 do \
1228 { \
1229 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1230 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1231 __builtin_eh_return (offset, handler); \
1232 } \
1233 while (0)
1234
1235static inline void
1236init_dwarf_reg_size_table (void)
1237{
1238 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
1239}
1240
1241static long
1242uw_install_context_1 (struct _Unwind_Context *current,
1243 struct _Unwind_Context *target)
1244{
1245 long i;
1246
1247#if __GTHREADS
1248 {
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 ();
1253 }
1254#else
1255 if (dwarf_reg_size_table[0] == 0)
1256 init_dwarf_reg_size_table ();
1257#endif
1258
1259 for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
1260 {
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]);
1265 }
1266
1267#ifdef EH_RETURN_STACKADJ_RTX
1268 {
1269 void *target_cfa;
1270
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;
1277
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;
1283 }
1284#else
1285 return 0;
1286#endif
1287}
1288
1289static inline _Unwind_Ptr
1290uw_identify_context (struct _Unwind_Context *context)
1291{
1292 return _Unwind_GetIP (context);
1293}
1294
1295
1296#include "unwind.inc"
1297
1298#endif /* _LIBC */
1299

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