OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgcc/] [unwind-dw2.c] - Blame information for rev 841

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.