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