Subversion Repositories Kolibri OS

Rev

Rev 4383 | Details | Compare with Previous | Last modification | View Log | RSS feed

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