Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4383 Serge 1
/* 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
   .  */
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, ®);
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, ®);
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, ®);
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, ®);
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, ®);
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, ®);
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, ®);
958
	    insn_ptr = read_uleb128 (insn_ptr, ®2);
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, ®);
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, ®);
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, ®);
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, ®);
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, ®);
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, ®);
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 */