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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [unwind-dw2.c] - Blame information for rev 862

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

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

powered by: WebSVN 2.1.0

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