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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgcc/] [config/] [cr16/] [unwind-cr16.c] - Blame information for rev 734

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

powered by: WebSVN 2.1.0

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