Subversion Repositories Kolibri OS

Rev

Rev 4383 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4383 Rev 5963
Line 1... Line 1...
1
/* DWARF2 exception handling and frame unwind runtime interface routines.
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.
2
   Copyright (C) 1997-2013 Free Software Foundation, Inc.
Line 4... Line 3...
4
 
3
 
Line 5... Line 4...
5
   This file is part of GCC.
4
   This file is part of GCC.
6
 
5
 
Line 53... Line 52...
53
 
52
 
54
#ifndef DWARF_REG_TO_UNWIND_COLUMN
53
#ifndef DWARF_REG_TO_UNWIND_COLUMN
55
#define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
54
#define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
Line -... Line 55...
-
 
55
#endif
-
 
56
 
-
 
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
56
#endif
122
#endif
57
 
123
 
58
/* This is the register and unwind state for a particular frame.  This
124
/* 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
125
   provides the information necessary to unwind up past a frame and return
60
   to its caller.  */
126
   to its caller.  */
61
struct _Unwind_Context
127
struct _Unwind_Context
62
{
128
{
63
  void *reg[DWARF_FRAME_REGISTERS+1];
129
  _Unwind_Context_Reg_Val reg[DWARF_FRAME_REGISTERS+1];
64
  void *cfa;
130
  void *cfa;
65
  void *ra;
131
  void *ra;
66
  void *lsda;
132
  void *lsda;
Line 141... Line 207...
141
}
207
}
Line 142... Line 208...
142
 
208
 
143
static inline _Unwind_Word
209
static inline _Unwind_Word
144
_Unwind_IsExtendedContext (struct _Unwind_Context *context)
210
_Unwind_IsExtendedContext (struct _Unwind_Context *context)
-
 
211
{
145
{
212
  return (ASSUME_EXTENDED_UNWIND_CONTEXT
146
  return context->flags & EXTENDED_CONTEXT_BIT;
213
	  || (context->flags & EXTENDED_CONTEXT_BIT));
147
}
214
}
148

215

Line 149... Line 216...
149
/* Get the value of register INDEX as saved in CONTEXT.  */
216
/* Get the value of register INDEX as saved in CONTEXT.  */
150
 
217
 
151
inline _Unwind_Word
218
inline _Unwind_Word
152
_Unwind_GetGR (struct _Unwind_Context *context, int index)
219
_Unwind_GetGR (struct _Unwind_Context *context, int index)
153
{
220
{
Line 154... Line 221...
154
  int size;
221
  int size;
155
  void *ptr;
222
  _Unwind_Context_Reg_Val val;
156
 
223
 
157
#ifdef DWARF_ZERO_REG
224
#ifdef DWARF_ZERO_REG
Line 158... Line 225...
158
  if (index == DWARF_ZERO_REG)
225
  if (index == DWARF_ZERO_REG)
159
    return 0;
226
    return 0;
160
#endif
227
#endif
161
 
228
 
Line 162... Line 229...
162
  index = DWARF_REG_TO_UNWIND_COLUMN (index);
229
  index = DWARF_REG_TO_UNWIND_COLUMN (index);
163
  gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
230
  gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
Line 164... Line 231...
164
  size = dwarf_reg_size_table[index];
231
  size = dwarf_reg_size_table[index];
165
  ptr = context->reg[index];
232
  val = context->reg[index];
166
 
233
 
167
  if (_Unwind_IsExtendedContext (context) && context->by_value[index])
234
  if (_Unwind_IsExtendedContext (context) && context->by_value[index])
168
    return (_Unwind_Word) (_Unwind_Internal_Ptr) ptr;
235
    return _Unwind_Get_Unwind_Word (val);
169
 
236
 
170
  /* This will segfault if the register hasn't been saved.  */
237
  /* This will segfault if the register hasn't been saved.  */
171
  if (size == sizeof(_Unwind_Ptr))
238
  if (size == sizeof(_Unwind_Ptr))
172
    return * (_Unwind_Ptr *) ptr;
239
    return * (_Unwind_Ptr *) (_Unwind_Internal_Ptr) val;
Line 173... Line 240...
173
  else
240
  else
174
    {
241
    {
Line 203... Line 270...
203
  gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
270
  gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
204
  size = dwarf_reg_size_table[index];
271
  size = dwarf_reg_size_table[index];
Line 205... Line 272...
205
 
272
 
206
  if (_Unwind_IsExtendedContext (context) && context->by_value[index])
273
  if (_Unwind_IsExtendedContext (context) && context->by_value[index])
207
    {
274
    {
208
      context->reg[index] = (void *) (_Unwind_Internal_Ptr) val;
275
      context->reg[index] = _Unwind_Get_Unwind_Context_Reg_Val (val);
209
      return;
276
      return;
Line 210... Line 277...
210
    }
277
    }
Line 211... Line 278...
211
 
278
 
212
  ptr = context->reg[index];
279
  ptr = (void *) (_Unwind_Internal_Ptr) context->reg[index];
213
 
280
 
214
  if (size == sizeof(_Unwind_Ptr))
281
  if (size == sizeof(_Unwind_Ptr))
Line 226... Line 293...
226
_Unwind_GetGRPtr (struct _Unwind_Context *context, int index)
293
_Unwind_GetGRPtr (struct _Unwind_Context *context, int index)
227
{
294
{
228
  index = DWARF_REG_TO_UNWIND_COLUMN (index);
295
  index = DWARF_REG_TO_UNWIND_COLUMN (index);
229
  if (_Unwind_IsExtendedContext (context) && context->by_value[index])
296
  if (_Unwind_IsExtendedContext (context) && context->by_value[index])
230
    return &context->reg[index];
297
    return &context->reg[index];
231
  return context->reg[index];
298
  return (void *) (_Unwind_Internal_Ptr) context->reg[index];
232
}
299
}
Line 233... Line 300...
233
 
300
 
Line 234... Line 301...
234
/* Set the pointer to a register INDEX as saved in CONTEXT.  */
301
/* Set the pointer to a register INDEX as saved in CONTEXT.  */
235
 
302
 
236
static inline void
303
static inline void
237
_Unwind_SetGRPtr (struct _Unwind_Context *context, int index, void *p)
304
_Unwind_SetGRPtr (struct _Unwind_Context *context, int index, void *p)
238
{
305
{
239
  index = DWARF_REG_TO_UNWIND_COLUMN (index);
306
  index = DWARF_REG_TO_UNWIND_COLUMN (index);
240
  if (_Unwind_IsExtendedContext (context))
307
  if (_Unwind_IsExtendedContext (context))
241
    context->by_value[index] = 0;
308
    context->by_value[index] = 0;
Line 242... Line 309...
242
  context->reg[index] = p;
309
  context->reg[index] = (_Unwind_Context_Reg_Val) (_Unwind_Internal_Ptr) p;
Line 243... Line 310...
243
}
310
}
244
 
311
 
245
/* Overwrite the saved value for register INDEX in CONTEXT with VAL.  */
312
/* Overwrite the saved value for register INDEX in CONTEXT with VAL.  */
246
 
313
 
247
static inline void
314
static inline void
248
_Unwind_SetGRValue (struct _Unwind_Context *context, int index,
315
_Unwind_SetGRValue (struct _Unwind_Context *context, int index,
-
 
316
		    _Unwind_Word val)
249
		    _Unwind_Word val)
317
{
Line 250... Line 318...
250
{
318
  index = DWARF_REG_TO_UNWIND_COLUMN (index);
251
  index = DWARF_REG_TO_UNWIND_COLUMN (index);
319
  gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
252
  gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
320
  /* Return column size may be smaller than _Unwind_Context_Reg_Val.  */
Line 253... Line 321...
253
  gcc_assert (dwarf_reg_size_table[index] == sizeof (_Unwind_Ptr));
321
  gcc_assert (dwarf_reg_size_table[index] <= sizeof (_Unwind_Context_Reg_Val));
254
 
322
 
Line 354... Line 422...
354
      fs->eh_ptr = read_pointer (p);
422
      fs->eh_ptr = read_pointer (p);
355
      p += sizeof (void *);
423
      p += sizeof (void *);
356
      aug += 2;
424
      aug += 2;
357
    }
425
    }
Line -... Line 426...
-
 
426
 
-
 
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;
358
 
435
    }
359
  /* Immediately following the augmentation are the code and
436
  /* Immediately following this are the code and
360
     data alignment and return address column.  */
437
     data alignment and return address column.  */
361
  p = read_uleb128 (p, &utmp);
438
  p = read_uleb128 (p, &utmp);
362
  fs->code_align = (_Unwind_Word)utmp;
439
  fs->code_align = (_Unwind_Word)utmp;
363
  p = read_sleb128 (p, &stmp);
440
  p = read_sleb128 (p, &stmp);
Line 886... Line 963...
886
      else if ((insn & 0xc0) == DW_CFA_offset)
963
      else if ((insn & 0xc0) == DW_CFA_offset)
887
	{
964
	{
888
	  reg = insn & 0x3f;
965
	  reg = insn & 0x3f;
889
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
966
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
890
	  offset = (_Unwind_Sword) utmp * fs->data_align;
967
	  offset = (_Unwind_Sword) utmp * fs->data_align;
891
	  fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
968
	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
-
 
969
	  if (UNWIND_COLUMN_IN_RANGE (reg))
-
 
970
	    {
892
	    = REG_SAVED_OFFSET;
971
	      fs->regs.reg[reg].how = REG_SAVED_OFFSET;
893
	  fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
972
	      fs->regs.reg[reg].loc.offset = offset;
-
 
973
	    }
894
	}
974
	}
895
      else if ((insn & 0xc0) == DW_CFA_restore)
975
      else if ((insn & 0xc0) == DW_CFA_restore)
896
	{
976
	{
897
	  reg = insn & 0x3f;
977
	  reg = insn & 0x3f;
898
	  fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_UNSAVED;
978
	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
-
 
979
	  if (UNWIND_COLUMN_IN_RANGE (reg))
-
 
980
	    fs->regs.reg[reg].how = REG_UNSAVED;
899
	}
981
	}
900
      else switch (insn)
982
      else switch (insn)
901
	{
983
	{
902
	case DW_CFA_set_loc:
984
	case DW_CFA_set_loc:
903
	  {
985
	  {
Line 924... Line 1006...
924
 
1006
 
925
	case DW_CFA_offset_extended:
1007
	case DW_CFA_offset_extended:
926
	  insn_ptr = read_uleb128 (insn_ptr, ®);
1008
	  insn_ptr = read_uleb128 (insn_ptr, ®);
927
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
1009
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
928
	  offset = (_Unwind_Sword) utmp * fs->data_align;
1010
	  offset = (_Unwind_Sword) utmp * fs->data_align;
-
 
1011
	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
-
 
1012
	  if (UNWIND_COLUMN_IN_RANGE (reg))
929
	  fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
1013
	    {
930
	    = REG_SAVED_OFFSET;
1014
	      fs->regs.reg[reg].how = REG_SAVED_OFFSET;
-
 
1015
	      fs->regs.reg[reg].loc.offset = offset;
931
	  fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
1016
	    }
Line 932... Line 1017...
932
	  break;
1017
	  break;
933
 
1018
 
934
	case DW_CFA_restore_extended:
1019
	case DW_CFA_restore_extended:
935
	  insn_ptr = read_uleb128 (insn_ptr, ®);
1020
	  insn_ptr = read_uleb128 (insn_ptr, ®);
936
	  /* FIXME, this is wrong; the CIE might have said that the
1021
	  /* FIXME, this is wrong; the CIE might have said that the
-
 
1022
	     register was saved somewhere.  */
-
 
1023
	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
937
	     register was saved somewhere.  */
1024
	  if (UNWIND_COLUMN_IN_RANGE (reg))
Line 938... Line 1025...
938
	  fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED;
1025
	    fs->regs.reg[reg].how = REG_UNSAVED;
939
	  break;
1026
	  break;
940
 
1027
 
-
 
1028
	case DW_CFA_same_value:
-
 
1029
	  insn_ptr = read_uleb128 (insn_ptr, ®);
941
	case DW_CFA_same_value:
1030
	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
Line 942... Line 1031...
942
	  insn_ptr = read_uleb128 (insn_ptr, ®);
1031
	  if (UNWIND_COLUMN_IN_RANGE (reg))
943
	  fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED;
1032
	    fs->regs.reg[reg].how = REG_UNSAVED;
-
 
1033
	  break;
-
 
1034
 
944
	  break;
1035
	case DW_CFA_undefined:
945
 
1036
	  insn_ptr = read_uleb128 (insn_ptr, ®);
Line 946... Line 1037...
946
	case DW_CFA_undefined:
1037
	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
947
	  insn_ptr = read_uleb128 (insn_ptr, ®);
1038
	  if (UNWIND_COLUMN_IN_RANGE (reg))
Line 948... Line 1039...
948
	  fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNDEFINED;
1039
	    fs->regs.reg[reg].how = REG_UNDEFINED;
949
	  break;
1040
	  break;
950
 
1041
 
951
	case DW_CFA_nop:
1042
	case DW_CFA_nop:
952
	  break;
1043
	  break;
953
 
1044
 
954
	case DW_CFA_register:
1045
	case DW_CFA_register:
-
 
1046
	  {
-
 
1047
	    _uleb128_t reg2;
955
	  {
1048
	    insn_ptr = read_uleb128 (insn_ptr, ®);
-
 
1049
	    insn_ptr = read_uleb128 (insn_ptr, ®2);
956
	    _uleb128_t reg2;
1050
	    reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
957
	    insn_ptr = read_uleb128 (insn_ptr, ®);
1051
	    if (UNWIND_COLUMN_IN_RANGE (reg))
Line 958... Line 1052...
958
	    insn_ptr = read_uleb128 (insn_ptr, ®2);
1052
	      {
959
	    fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_REG;
1053
	        fs->regs.reg[reg].how = REG_SAVED_REG;
Line 1014... Line 1108...
1014
	  insn_ptr += utmp;
1108
	  insn_ptr += utmp;
1015
	  break;
1109
	  break;
Line 1016... Line 1110...
1016
 
1110
 
1017
	case DW_CFA_expression:
1111
	case DW_CFA_expression:
1018
	  insn_ptr = read_uleb128 (insn_ptr, ®);
1112
	  insn_ptr = read_uleb128 (insn_ptr, ®);
-
 
1113
	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
-
 
1114
	  if (UNWIND_COLUMN_IN_RANGE (reg))
-
 
1115
	    {
1019
	  fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_EXP;
1116
	      fs->regs.reg[reg].how = REG_SAVED_EXP;
-
 
1117
	      fs->regs.reg[reg].loc.exp = insn_ptr;
1020
	  fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.exp = insn_ptr;
1118
	    }
1021
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
1119
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
1022
	  insn_ptr += utmp;
1120
	  insn_ptr += utmp;
Line 1023... Line 1121...
1023
	  break;
1121
	  break;
1024
 
1122
 
1025
	  /* Dwarf3.  */
1123
	  /* Dwarf3.  */
1026
	case DW_CFA_offset_extended_sf:
1124
	case DW_CFA_offset_extended_sf:
1027
	  insn_ptr = read_uleb128 (insn_ptr, ®);
1125
	  insn_ptr = read_uleb128 (insn_ptr, ®);
1028
	  insn_ptr = read_sleb128 (insn_ptr, &stmp);
1126
	  insn_ptr = read_sleb128 (insn_ptr, &stmp);
-
 
1127
	  offset = stmp * fs->data_align;
-
 
1128
	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1029
	  offset = stmp * fs->data_align;
1129
	  if (UNWIND_COLUMN_IN_RANGE (reg))
1030
	  fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
1130
	    {
-
 
1131
	      fs->regs.reg[reg].how = REG_SAVED_OFFSET;
1031
	    = REG_SAVED_OFFSET;
1132
	      fs->regs.reg[reg].loc.offset = offset;
Line 1032... Line 1133...
1032
	  fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
1133
	    }
1033
	  break;
1134
	  break;
1034
 
1135
 
Line 1050... Line 1151...
1050
 
1151
 
1051
	case DW_CFA_val_offset:
1152
	case DW_CFA_val_offset:
1052
	  insn_ptr = read_uleb128 (insn_ptr, ®);
1153
	  insn_ptr = read_uleb128 (insn_ptr, ®);
1053
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
1154
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
1054
	  offset = (_Unwind_Sword) utmp * fs->data_align;
1155
	  offset = (_Unwind_Sword) utmp * fs->data_align;
-
 
1156
	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
-
 
1157
	  if (UNWIND_COLUMN_IN_RANGE (reg))
1055
	  fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
1158
	    {
1056
	    = REG_SAVED_VAL_OFFSET;
1159
	      fs->regs.reg[reg].how = REG_SAVED_VAL_OFFSET;
-
 
1160
	      fs->regs.reg[reg].loc.offset = offset;
1057
	  fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
1161
	    }
Line 1058... Line 1162...
1058
	  break;
1162
	  break;
1059
 
1163
 
1060
	case DW_CFA_val_offset_sf:
1164
	case DW_CFA_val_offset_sf:
1061
	  insn_ptr = read_uleb128 (insn_ptr, ®);
1165
	  insn_ptr = read_uleb128 (insn_ptr, ®);
1062
	  insn_ptr = read_sleb128 (insn_ptr, &stmp);
1166
	  insn_ptr = read_sleb128 (insn_ptr, &stmp);
-
 
1167
	  offset = stmp * fs->data_align;
-
 
1168
	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1063
	  offset = stmp * fs->data_align;
1169
	  if (UNWIND_COLUMN_IN_RANGE (reg))
1064
	  fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
1170
	    {
-
 
1171
	      fs->regs.reg[reg].how = REG_SAVED_VAL_OFFSET;
1065
	    = REG_SAVED_VAL_OFFSET;
1172
	      fs->regs.reg[reg].loc.offset = offset;
Line 1066... Line 1173...
1066
	  fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
1173
	    }
1067
	  break;
1174
	  break;
1068
 
1175
 
-
 
1176
	case DW_CFA_val_expression:
-
 
1177
	  insn_ptr = read_uleb128 (insn_ptr, ®);
1069
	case DW_CFA_val_expression:
1178
	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1070
	  insn_ptr = read_uleb128 (insn_ptr, ®);
1179
	  if (UNWIND_COLUMN_IN_RANGE (reg))
-
 
1180
	    {
1071
	  fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
1181
	      fs->regs.reg[reg].how = REG_SAVED_VAL_EXP;
1072
	    = REG_SAVED_VAL_EXP;
1182
	      fs->regs.reg[reg].loc.exp = insn_ptr;
1073
	  fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.exp = insn_ptr;
1183
	    }
Line 1074... Line 1184...
1074
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
1184
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
1075
	  insn_ptr += utmp;
1185
	  insn_ptr += utmp;
-
 
1186
	  break;
1076
	  break;
1187
 
1077
 
1188
	case DW_CFA_GNU_window_save:
1078
	case DW_CFA_GNU_window_save:
1189
	  /* ??? Hardcoded for SPARC register window configuration.  */
1079
	  /* ??? Hardcoded for SPARC register window configuration.  */
1190
	  if (DWARF_FRAME_REGISTERS >= 32)
1080
	  for (reg = 16; reg < 32; ++reg)
1191
	    for (reg = 16; reg < 32; ++reg)
Line 1093... Line 1204...
1093
	  /* Obsoleted by DW_CFA_offset_extended_sf, but used by
1204
	  /* Obsoleted by DW_CFA_offset_extended_sf, but used by
1094
	     older PowerPC code.  */
1205
	     older PowerPC code.  */
1095
	  insn_ptr = read_uleb128 (insn_ptr, ®);
1206
	  insn_ptr = read_uleb128 (insn_ptr, ®);
1096
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
1207
	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
1097
	  offset = (_Unwind_Word) utmp * fs->data_align;
1208
	  offset = (_Unwind_Word) utmp * fs->data_align;
1098
	  fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
1209
	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
-
 
1210
	  if (UNWIND_COLUMN_IN_RANGE (reg))
-
 
1211
	    {
1099
	    = REG_SAVED_OFFSET;
1212
	      fs->regs.reg[reg].how = REG_SAVED_OFFSET;
1100
	  fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = -offset;
1213
	      fs->regs.reg[reg].loc.offset = -offset;
-
 
1214
	    }
1101
	  break;
1215
	  break;
Line 1102... Line 1216...
1102
 
1216
 
1103
	default:
1217
	default:
1104
	  gcc_unreachable ();
1218
	  gcc_unreachable ();
Line 1202... Line 1316...
1202
  struct _Unwind_Context context;
1316
  struct _Unwind_Context context;
1203
  _Unwind_FrameState fs;
1317
  _Unwind_FrameState fs;
1204
  int reg;
1318
  int reg;
Line 1205... Line 1319...
1205
 
1319
 
-
 
1320
  memset (&context, 0, sizeof (struct _Unwind_Context));
1206
  memset (&context, 0, sizeof (struct _Unwind_Context));
1321
  if (!ASSUME_EXTENDED_UNWIND_CONTEXT)
1207
  context.flags = EXTENDED_CONTEXT_BIT;
1322
    context.flags = EXTENDED_CONTEXT_BIT;
Line 1208... Line 1323...
1208
  context.ra = pc_target + 1;
1323
  context.ra = pc_target + 1;
1209
 
1324
 
Line 1440... Line 1555...
1440
  _Unwind_SpTmp sp_slot;
1555
  _Unwind_SpTmp sp_slot;
1441
  _Unwind_Reason_Code code;
1556
  _Unwind_Reason_Code code;
Line 1442... Line 1557...
1442
 
1557
 
1443
  memset (context, 0, sizeof (struct _Unwind_Context));
1558
  memset (context, 0, sizeof (struct _Unwind_Context));
-
 
1559
  context->ra = ra;
1444
  context->ra = ra;
1560
  if (!ASSUME_EXTENDED_UNWIND_CONTEXT)
Line 1445... Line 1561...
1445
  context->flags = EXTENDED_CONTEXT_BIT;
1561
    context->flags = EXTENDED_CONTEXT_BIT;
1446
 
1562
 
Line 1482... Line 1598...
1482
   transferred.  */
1598
   transferred.  */
1483
static void
1599
static void
1484
_Unwind_DebugHook (void *cfa __attribute__ ((__unused__)),
1600
_Unwind_DebugHook (void *cfa __attribute__ ((__unused__)),
1485
		   void *handler __attribute__ ((__unused__)))
1601
		   void *handler __attribute__ ((__unused__)))
1486
{
1602
{
-
 
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
1487
  asm ("");
1608
  asm ("");
-
 
1609
#endif
1488
}
1610
}
Line 1489... Line 1611...
1489
 
1611
 
1490
/* Install TARGET into CURRENT so that we can return to it.  This is a
1612
/* 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
1613
   macro because __builtin_eh_return must be invoked in the context of
Line 1513... Line 1635...
1513
  if (!_Unwind_GetGRPtr (target, __builtin_dwarf_sp_column ()))
1635
  if (!_Unwind_GetGRPtr (target, __builtin_dwarf_sp_column ()))
1514
    _Unwind_SetSpColumn (target, target->cfa, &sp_slot);
1636
    _Unwind_SetSpColumn (target, target->cfa, &sp_slot);
Line 1515... Line 1637...
1515
 
1637
 
1516
  for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
1638
  for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
1517
    {
1639
    {
1518
      void *c = current->reg[i];
1640
      void *c = (void *) (_Unwind_Internal_Ptr) current->reg[i];
Line 1519... Line 1641...
1519
      void *t = target->reg[i];
1641
      void *t = (void *) (_Unwind_Internal_Ptr)target->reg[i];
1520
 
1642
 
1521
      gcc_assert (current->by_value[i] == 0);
1643
      gcc_assert (current->by_value[i] == 0);
1522
      if (target->by_value[i] && c)
1644
      if (target->by_value[i] && c)