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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [unwind-dw2.c] - Blame information for rev 20

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

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

powered by: WebSVN 2.1.0

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