00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "tconfig.h"
00032 #include "tsystem.h"
00033 #include "coretypes.h"
00034 #include "tm.h"
00035 #include "dwarf2.h"
00036 #include "unwind.h"
00037 #ifdef __USING_SJLJ_EXCEPTIONS__
00038 # define NO_SIZE_OF_ENCODED_VALUE
00039 #endif
00040 #include "unwind-pe.h"
00041 #include "unwind-dw2-fde.h"
00042 #include "gthr.h"
00043 #include "unwind-dw2.h"
00044
00045 #ifndef __USING_SJLJ_EXCEPTIONS__
00046
00047 #ifndef STACK_GROWS_DOWNWARD
00048 #define STACK_GROWS_DOWNWARD 0
00049 #else
00050 #undef STACK_GROWS_DOWNWARD
00051 #define STACK_GROWS_DOWNWARD 1
00052 #endif
00053
00054
00055 #ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
00056 #define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
00057 #endif
00058
00059 #ifndef DWARF_REG_TO_UNWIND_COLUMN
00060 #define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
00061 #endif
00062
00063
00064
00065
00066 struct _Unwind_Context
00067 {
00068 void *reg[DWARF_FRAME_REGISTERS+1];
00069 void *cfa;
00070 void *ra;
00071 void *lsda;
00072 struct dwarf_eh_bases bases;
00073
00074 #define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1)
00075
00076 #define EXTENDED_CONTEXT_BIT ((~(_Unwind_Word) 0 >> 2) + 1)
00077 _Unwind_Word flags;
00078
00079
00080 _Unwind_Word version;
00081 _Unwind_Word args_size;
00082 char by_value[DWARF_FRAME_REGISTERS+1];
00083 };
00084
00085
00086 static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS+1];
00087
00088
00089
00090
00091 union unaligned
00092 {
00093 void *p;
00094 unsigned u2 __attribute__ ((mode (HI)));
00095 unsigned u4 __attribute__ ((mode (SI)));
00096 unsigned u8 __attribute__ ((mode (DI)));
00097 signed s2 __attribute__ ((mode (HI)));
00098 signed s4 __attribute__ ((mode (SI)));
00099 signed s8 __attribute__ ((mode (DI)));
00100 } __attribute__ ((packed));
00101
00102 static void uw_update_context (struct _Unwind_Context *, _Unwind_FrameState *);
00103 static _Unwind_Reason_Code uw_frame_state_for (struct _Unwind_Context *,
00104 _Unwind_FrameState *);
00105
00106 static inline void *
00107 read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
00108
00109 static inline int
00110 read_1u (const void *p) { return *(const unsigned char *) p; }
00111
00112 static inline int
00113 read_1s (const void *p) { return *(const signed char *) p; }
00114
00115 static inline int
00116 read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
00117
00118 static inline int
00119 read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
00120
00121 static inline unsigned int
00122 read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
00123
00124 static inline int
00125 read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
00126
00127 static inline unsigned long
00128 read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
00129
00130 static inline unsigned long
00131 read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
00132
00133 static inline _Unwind_Word
00134 _Unwind_IsSignalFrame (struct _Unwind_Context *context)
00135 {
00136 return (context->flags & SIGNAL_FRAME_BIT) ? 1 : 0;
00137 }
00138
00139 static inline void
00140 _Unwind_SetSignalFrame (struct _Unwind_Context *context, int val)
00141 {
00142 if (val)
00143 context->flags |= SIGNAL_FRAME_BIT;
00144 else
00145 context->flags &= ~SIGNAL_FRAME_BIT;
00146 }
00147
00148 static inline _Unwind_Word
00149 _Unwind_IsExtendedContext (struct _Unwind_Context *context)
00150 {
00151 return context->flags & EXTENDED_CONTEXT_BIT;
00152 }
00153
00154
00155
00156 inline _Unwind_Word
00157 _Unwind_GetGR (struct _Unwind_Context *context, int index)
00158 {
00159 int size;
00160 void *ptr;
00161
00162 #ifdef DWARF_ZERO_REG
00163 if (index == DWARF_ZERO_REG)
00164 return 0;
00165 #endif
00166
00167 index = DWARF_REG_TO_UNWIND_COLUMN (index);
00168 gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
00169 size = dwarf_reg_size_table[index];
00170 ptr = context->reg[index];
00171
00172 if (_Unwind_IsExtendedContext (context) && context->by_value[index])
00173 return (_Unwind_Word) (_Unwind_Internal_Ptr) ptr;
00174
00175
00176 if (size == sizeof(_Unwind_Ptr))
00177 return * (_Unwind_Ptr *) ptr;
00178 else
00179 {
00180 gcc_assert (size == sizeof(_Unwind_Word));
00181 return * (_Unwind_Word *) ptr;
00182 }
00183 }
00184
00185 static inline void *
00186 _Unwind_GetPtr (struct _Unwind_Context *context, int index)
00187 {
00188 return (void *)(_Unwind_Ptr) _Unwind_GetGR (context, index);
00189 }
00190
00191
00192
00193 _Unwind_Word
00194 _Unwind_GetCFA (struct _Unwind_Context *context)
00195 {
00196 return (_Unwind_Ptr) context->cfa;
00197 }
00198
00199
00200
00201 inline void
00202 _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
00203 {
00204 int size;
00205 void *ptr;
00206
00207 index = DWARF_REG_TO_UNWIND_COLUMN (index);
00208 gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
00209 size = dwarf_reg_size_table[index];
00210
00211 if (_Unwind_IsExtendedContext (context) && context->by_value[index])
00212 {
00213 context->reg[index] = (void *) (_Unwind_Internal_Ptr) val;
00214 return;
00215 }
00216
00217 ptr = context->reg[index];
00218
00219 if (size == sizeof(_Unwind_Ptr))
00220 * (_Unwind_Ptr *) ptr = val;
00221 else
00222 {
00223 gcc_assert (size == sizeof(_Unwind_Word));
00224 * (_Unwind_Word *) ptr = val;
00225 }
00226 }
00227
00228
00229
00230 static inline void *
00231 _Unwind_GetGRPtr (struct _Unwind_Context *context, int index)
00232 {
00233 index = DWARF_REG_TO_UNWIND_COLUMN (index);
00234 if (_Unwind_IsExtendedContext (context) && context->by_value[index])
00235 return &context->reg[index];
00236 return context->reg[index];
00237 }
00238
00239
00240
00241 static inline void
00242 _Unwind_SetGRPtr (struct _Unwind_Context *context, int index, void *p)
00243 {
00244 index = DWARF_REG_TO_UNWIND_COLUMN (index);
00245 if (_Unwind_IsExtendedContext (context))
00246 context->by_value[index] = 0;
00247 context->reg[index] = p;
00248 }
00249
00250
00251
00252 static inline void
00253 _Unwind_SetGRValue (struct _Unwind_Context *context, int index,
00254 _Unwind_Word val)
00255 {
00256 index = DWARF_REG_TO_UNWIND_COLUMN (index);
00257 gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
00258 gcc_assert (dwarf_reg_size_table[index] == sizeof (_Unwind_Ptr));
00259
00260 context->by_value[index] = 1;
00261 context->reg[index] = (void *) (_Unwind_Internal_Ptr) val;
00262 }
00263
00264
00265
00266
00267 static inline int
00268 _Unwind_GRByValue (struct _Unwind_Context *context, int index)
00269 {
00270 index = DWARF_REG_TO_UNWIND_COLUMN (index);
00271 return context->by_value[index];
00272 }
00273
00274
00275
00276 inline _Unwind_Ptr
00277 _Unwind_GetIP (struct _Unwind_Context *context)
00278 {
00279 return (_Unwind_Ptr) context->ra;
00280 }
00281
00282
00283
00284
00285 inline _Unwind_Ptr
00286 _Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
00287 {
00288 *ip_before_insn = _Unwind_IsSignalFrame (context);
00289 return (_Unwind_Ptr) context->ra;
00290 }
00291
00292
00293
00294 inline void
00295 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
00296 {
00297 context->ra = (void *) val;
00298 }
00299
00300 void *
00301 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
00302 {
00303 return context->lsda;
00304 }
00305
00306 _Unwind_Ptr
00307 _Unwind_GetRegionStart (struct _Unwind_Context *context)
00308 {
00309 return (_Unwind_Ptr) context->bases.func;
00310 }
00311
00312 void *
00313 _Unwind_FindEnclosingFunction (void *pc)
00314 {
00315 struct dwarf_eh_bases bases;
00316 const struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases);
00317 if (fde)
00318 return bases.func;
00319 else
00320 return NULL;
00321 }
00322
00323 #ifndef __ia64__
00324 _Unwind_Ptr
00325 _Unwind_GetDataRelBase (struct _Unwind_Context *context)
00326 {
00327 return (_Unwind_Ptr) context->bases.dbase;
00328 }
00329
00330 _Unwind_Ptr
00331 _Unwind_GetTextRelBase (struct _Unwind_Context *context)
00332 {
00333 return (_Unwind_Ptr) context->bases.tbase;
00334 }
00335 #endif
00336
00337 #ifdef MD_UNWIND_SUPPORT
00338 #include MD_UNWIND_SUPPORT
00339 #endif
00340
00341
00342
00343
00344
00345 static const unsigned char *
00346 extract_cie_info (const struct dwarf_cie *cie, struct _Unwind_Context *context,
00347 _Unwind_FrameState *fs)
00348 {
00349 const unsigned char *aug = cie->augmentation;
00350 const unsigned char *p = aug + strlen ((const char *)aug) + 1;
00351 const unsigned char *ret = NULL;
00352 _Unwind_Word utmp;
00353
00354
00355
00356 if (aug[0] == 'e' && aug[1] == 'h')
00357 {
00358 fs->eh_ptr = read_pointer (p);
00359 p += sizeof (void *);
00360 aug += 2;
00361 }
00362
00363
00364
00365 p = read_uleb128 (p, &fs->code_align);
00366 p = read_sleb128 (p, &fs->data_align);
00367 if (cie->version == 1)
00368 fs->retaddr_column = *p++;
00369 else
00370 p = read_uleb128 (p, &fs->retaddr_column);
00371 fs->lsda_encoding = DW_EH_PE_omit;
00372
00373
00374
00375
00376 if (*aug == 'z')
00377 {
00378 p = read_uleb128 (p, &utmp);
00379 ret = p + utmp;
00380
00381 fs->saw_z = 1;
00382 ++aug;
00383 }
00384
00385
00386 while (*aug != '\0')
00387 {
00388
00389 if (aug[0] == 'L')
00390 {
00391 fs->lsda_encoding = *p++;
00392 aug += 1;
00393 }
00394
00395
00396 else if (aug[0] == 'R')
00397 {
00398 fs->fde_encoding = *p++;
00399 aug += 1;
00400 }
00401
00402
00403 else if (aug[0] == 'P')
00404 {
00405 _Unwind_Ptr personality;
00406
00407 p = read_encoded_value (context, *p, p + 1, &personality);
00408 fs->personality = (_Unwind_Personality_Fn) personality;
00409 aug += 1;
00410 }
00411
00412
00413 else if (aug[0] == 'S')
00414 {
00415 fs->signal_frame = 1;
00416 aug += 1;
00417 }
00418
00419
00420
00421 else
00422 return ret;
00423 }
00424
00425 return ret ? ret : p;
00426 }
00427
00428
00429
00430
00431
00432 static _Unwind_Word
00433 execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
00434 struct _Unwind_Context *context, _Unwind_Word initial)
00435 {
00436 _Unwind_Word stack[64];
00437 int stack_elt;
00438
00439 stack[0] = initial;
00440 stack_elt = 1;
00441
00442 while (op_ptr < op_end)
00443 {
00444 enum dwarf_location_atom op = *op_ptr++;
00445 _Unwind_Word result, reg, utmp;
00446 _Unwind_Sword offset, stmp;
00447
00448 switch (op)
00449 {
00450 case DW_OP_lit0:
00451 case DW_OP_lit1:
00452 case DW_OP_lit2:
00453 case DW_OP_lit3:
00454 case DW_OP_lit4:
00455 case DW_OP_lit5:
00456 case DW_OP_lit6:
00457 case DW_OP_lit7:
00458 case DW_OP_lit8:
00459 case DW_OP_lit9:
00460 case DW_OP_lit10:
00461 case DW_OP_lit11:
00462 case DW_OP_lit12:
00463 case DW_OP_lit13:
00464 case DW_OP_lit14:
00465 case DW_OP_lit15:
00466 case DW_OP_lit16:
00467 case DW_OP_lit17:
00468 case DW_OP_lit18:
00469 case DW_OP_lit19:
00470 case DW_OP_lit20:
00471 case DW_OP_lit21:
00472 case DW_OP_lit22:
00473 case DW_OP_lit23:
00474 case DW_OP_lit24:
00475 case DW_OP_lit25:
00476 case DW_OP_lit26:
00477 case DW_OP_lit27:
00478 case DW_OP_lit28:
00479 case DW_OP_lit29:
00480 case DW_OP_lit30:
00481 case DW_OP_lit31:
00482 result = op - DW_OP_lit0;
00483 break;
00484
00485 case DW_OP_addr:
00486 result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
00487 op_ptr += sizeof (void *);
00488 break;
00489
00490 case DW_OP_const1u:
00491 result = read_1u (op_ptr);
00492 op_ptr += 1;
00493 break;
00494 case DW_OP_const1s:
00495 result = read_1s (op_ptr);
00496 op_ptr += 1;
00497 break;
00498 case DW_OP_const2u:
00499 result = read_2u (op_ptr);
00500 op_ptr += 2;
00501 break;
00502 case DW_OP_const2s:
00503 result = read_2s (op_ptr);
00504 op_ptr += 2;
00505 break;
00506 case DW_OP_const4u:
00507 result = read_4u (op_ptr);
00508 op_ptr += 4;
00509 break;
00510 case DW_OP_const4s:
00511 result = read_4s (op_ptr);
00512 op_ptr += 4;
00513 break;
00514 case DW_OP_const8u:
00515 result = read_8u (op_ptr);
00516 op_ptr += 8;
00517 break;
00518 case DW_OP_const8s:
00519 result = read_8s (op_ptr);
00520 op_ptr += 8;
00521 break;
00522 case DW_OP_constu:
00523 op_ptr = read_uleb128 (op_ptr, &result);
00524 break;
00525 case DW_OP_consts:
00526 op_ptr = read_sleb128 (op_ptr, &stmp);
00527 result = stmp;
00528 break;
00529
00530 case DW_OP_reg0:
00531 case DW_OP_reg1:
00532 case DW_OP_reg2:
00533 case DW_OP_reg3:
00534 case DW_OP_reg4:
00535 case DW_OP_reg5:
00536 case DW_OP_reg6:
00537 case DW_OP_reg7:
00538 case DW_OP_reg8:
00539 case DW_OP_reg9:
00540 case DW_OP_reg10:
00541 case DW_OP_reg11:
00542 case DW_OP_reg12:
00543 case DW_OP_reg13:
00544 case DW_OP_reg14:
00545 case DW_OP_reg15:
00546 case DW_OP_reg16:
00547 case DW_OP_reg17:
00548 case DW_OP_reg18:
00549 case DW_OP_reg19:
00550 case DW_OP_reg20:
00551 case DW_OP_reg21:
00552 case DW_OP_reg22:
00553 case DW_OP_reg23:
00554 case DW_OP_reg24:
00555 case DW_OP_reg25:
00556 case DW_OP_reg26:
00557 case DW_OP_reg27:
00558 case DW_OP_reg28:
00559 case DW_OP_reg29:
00560 case DW_OP_reg30:
00561 case DW_OP_reg31:
00562 result = _Unwind_GetGR (context, op - DW_OP_reg0);
00563 break;
00564 case DW_OP_regx:
00565 op_ptr = read_uleb128 (op_ptr, ®);
00566 result = _Unwind_GetGR (context, reg);
00567 break;
00568
00569 case DW_OP_breg0:
00570 case DW_OP_breg1:
00571 case DW_OP_breg2:
00572 case DW_OP_breg3:
00573 case DW_OP_breg4:
00574 case DW_OP_breg5:
00575 case DW_OP_breg6:
00576 case DW_OP_breg7:
00577 case DW_OP_breg8:
00578 case DW_OP_breg9:
00579 case DW_OP_breg10:
00580 case DW_OP_breg11:
00581 case DW_OP_breg12:
00582 case DW_OP_breg13:
00583 case DW_OP_breg14:
00584 case DW_OP_breg15:
00585 case DW_OP_breg16:
00586 case DW_OP_breg17:
00587 case DW_OP_breg18:
00588 case DW_OP_breg19:
00589 case DW_OP_breg20:
00590 case DW_OP_breg21:
00591 case DW_OP_breg22:
00592 case DW_OP_breg23:
00593 case DW_OP_breg24:
00594 case DW_OP_breg25:
00595 case DW_OP_breg26:
00596 case DW_OP_breg27:
00597 case DW_OP_breg28:
00598 case DW_OP_breg29:
00599 case DW_OP_breg30:
00600 case DW_OP_breg31:
00601 op_ptr = read_sleb128 (op_ptr, &offset);
00602 result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
00603 break;
00604 case DW_OP_bregx:
00605 op_ptr = read_uleb128 (op_ptr, ®);
00606 op_ptr = read_sleb128 (op_ptr, &offset);
00607 result = _Unwind_GetGR (context, reg) + offset;
00608 break;
00609
00610 case DW_OP_dup:
00611 gcc_assert (stack_elt);
00612 result = stack[stack_elt - 1];
00613 break;
00614
00615 case DW_OP_drop:
00616 gcc_assert (stack_elt);
00617 stack_elt -= 1;
00618 goto no_push;
00619
00620 case DW_OP_pick:
00621 offset = *op_ptr++;
00622 gcc_assert (offset < stack_elt - 1);
00623 result = stack[stack_elt - 1 - offset];
00624 break;
00625
00626 case DW_OP_over:
00627 gcc_assert (stack_elt >= 2);
00628 result = stack[stack_elt - 2];
00629 break;
00630
00631 case DW_OP_swap:
00632 {
00633 _Unwind_Word t;
00634 gcc_assert (stack_elt >= 2);
00635 t = stack[stack_elt - 1];
00636 stack[stack_elt - 1] = stack[stack_elt - 2];
00637 stack[stack_elt - 2] = t;
00638 goto no_push;
00639 }
00640
00641 case DW_OP_rot:
00642 {
00643 _Unwind_Word t1, t2, t3;
00644
00645 gcc_assert (stack_elt >= 3);
00646 t1 = stack[stack_elt - 1];
00647 t2 = stack[stack_elt - 2];
00648 t3 = stack[stack_elt - 3];
00649 stack[stack_elt - 1] = t2;
00650 stack[stack_elt - 2] = t3;
00651 stack[stack_elt - 3] = t1;
00652 goto no_push;
00653 }
00654
00655 case DW_OP_deref:
00656 case DW_OP_deref_size:
00657 case DW_OP_abs:
00658 case DW_OP_neg:
00659 case DW_OP_not:
00660 case DW_OP_plus_uconst:
00661
00662 gcc_assert (stack_elt);
00663 stack_elt -= 1;
00664
00665 result = stack[stack_elt];
00666
00667 switch (op)
00668 {
00669 case DW_OP_deref:
00670 {
00671 void *ptr = (void *) (_Unwind_Ptr) result;
00672 result = (_Unwind_Ptr) read_pointer (ptr);
00673 }
00674 break;
00675
00676 case DW_OP_deref_size:
00677 {
00678 void *ptr = (void *) (_Unwind_Ptr) result;
00679 switch (*op_ptr++)
00680 {
00681 case 1:
00682 result = read_1u (ptr);
00683 break;
00684 case 2:
00685 result = read_2u (ptr);
00686 break;
00687 case 4:
00688 result = read_4u (ptr);
00689 break;
00690 case 8:
00691 result = read_8u (ptr);
00692 break;
00693 default:
00694 gcc_unreachable ();
00695 }
00696 }
00697 break;
00698
00699 case DW_OP_abs:
00700 if ((_Unwind_Sword) result < 0)
00701 result = -result;
00702 break;
00703 case DW_OP_neg:
00704 result = -result;
00705 break;
00706 case DW_OP_not:
00707 result = ~result;
00708 break;
00709 case DW_OP_plus_uconst:
00710 op_ptr = read_uleb128 (op_ptr, &utmp);
00711 result += utmp;
00712 break;
00713
00714 default:
00715 gcc_unreachable ();
00716 }
00717 break;
00718
00719 case DW_OP_and:
00720 case DW_OP_div:
00721 case DW_OP_minus:
00722 case DW_OP_mod:
00723 case DW_OP_mul:
00724 case DW_OP_or:
00725 case DW_OP_plus:
00726 case DW_OP_shl:
00727 case DW_OP_shr:
00728 case DW_OP_shra:
00729 case DW_OP_xor:
00730 case DW_OP_le:
00731 case DW_OP_ge:
00732 case DW_OP_eq:
00733 case DW_OP_lt:
00734 case DW_OP_gt:
00735 case DW_OP_ne:
00736 {
00737
00738 _Unwind_Word first, second;
00739 gcc_assert (stack_elt >= 2);
00740 stack_elt -= 2;
00741
00742 second = stack[stack_elt];
00743 first = stack[stack_elt + 1];
00744
00745 switch (op)
00746 {
00747 case DW_OP_and:
00748 result = second & first;
00749 break;
00750 case DW_OP_div:
00751 result = (_Unwind_Sword) second / (_Unwind_Sword) first;
00752 break;
00753 case DW_OP_minus:
00754 result = second - first;
00755 break;
00756 case DW_OP_mod:
00757 result = (_Unwind_Sword) second % (_Unwind_Sword) first;
00758 break;
00759 case DW_OP_mul:
00760 result = second * first;
00761 break;
00762 case DW_OP_or:
00763 result = second | first;
00764 break;
00765 case DW_OP_plus:
00766 result = second + first;
00767 break;
00768 case DW_OP_shl:
00769 result = second << first;
00770 break;
00771 case DW_OP_shr:
00772 result = second >> first;
00773 break;
00774 case DW_OP_shra:
00775 result = (_Unwind_Sword) second >> first;
00776 break;
00777 case DW_OP_xor:
00778 result = second ^ first;
00779 break;
00780 case DW_OP_le:
00781 result = (_Unwind_Sword) first <= (_Unwind_Sword) second;
00782 break;
00783 case DW_OP_ge:
00784 result = (_Unwind_Sword) first >= (_Unwind_Sword) second;
00785 break;
00786 case DW_OP_eq:
00787 result = (_Unwind_Sword) first == (_Unwind_Sword) second;
00788 break;
00789 case DW_OP_lt:
00790 result = (_Unwind_Sword) first < (_Unwind_Sword) second;
00791 break;
00792 case DW_OP_gt:
00793 result = (_Unwind_Sword) first > (_Unwind_Sword) second;
00794 break;
00795 case DW_OP_ne:
00796 result = (_Unwind_Sword) first != (_Unwind_Sword) second;
00797 break;
00798
00799 default:
00800 gcc_unreachable ();
00801 }
00802 }
00803 break;
00804
00805 case DW_OP_skip:
00806 offset = read_2s (op_ptr);
00807 op_ptr += 2;
00808 op_ptr += offset;
00809 goto no_push;
00810
00811 case DW_OP_bra:
00812 gcc_assert (stack_elt);
00813 stack_elt -= 1;
00814
00815 offset = read_2s (op_ptr);
00816 op_ptr += 2;
00817 if (stack[stack_elt] != 0)
00818 op_ptr += offset;
00819 goto no_push;
00820
00821 case DW_OP_nop:
00822 goto no_push;
00823
00824 default:
00825 gcc_unreachable ();
00826 }
00827
00828
00829 gcc_assert ((size_t) stack_elt < sizeof(stack)/sizeof(*stack));
00830 stack[stack_elt++] = result;
00831 no_push:;
00832 }
00833
00834
00835
00836 gcc_assert (stack_elt);
00837 stack_elt -= 1;
00838 return stack[stack_elt];
00839 }
00840
00841
00842
00843
00844
00845
00846 static void
00847 execute_cfa_program (const unsigned char *insn_ptr,
00848 const unsigned char *insn_end,
00849 struct _Unwind_Context *context,
00850 _Unwind_FrameState *fs)
00851 {
00852 struct frame_state_reg_info *unused_rs = NULL;
00853
00854
00855 fs->regs.prev = NULL;
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866 while (insn_ptr < insn_end
00867 && fs->pc < context->ra + _Unwind_IsSignalFrame (context))
00868 {
00869 unsigned char insn = *insn_ptr++;
00870 _Unwind_Word reg, utmp;
00871 _Unwind_Sword offset, stmp;
00872
00873 if ((insn & 0xc0) == DW_CFA_advance_loc)
00874 fs->pc += (insn & 0x3f) * fs->code_align;
00875 else if ((insn & 0xc0) == DW_CFA_offset)
00876 {
00877 reg = insn & 0x3f;
00878 insn_ptr = read_uleb128 (insn_ptr, &utmp);
00879 offset = (_Unwind_Sword) utmp * fs->data_align;
00880 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
00881 = REG_SAVED_OFFSET;
00882 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
00883 }
00884 else if ((insn & 0xc0) == DW_CFA_restore)
00885 {
00886 reg = insn & 0x3f;
00887 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_UNSAVED;
00888 }
00889 else switch (insn)
00890 {
00891 case DW_CFA_set_loc:
00892 {
00893 _Unwind_Ptr pc;
00894
00895 insn_ptr = read_encoded_value (context, fs->fde_encoding,
00896 insn_ptr, &pc);
00897 fs->pc = (void *) pc;
00898 }
00899 break;
00900
00901 case DW_CFA_advance_loc1:
00902 fs->pc += read_1u (insn_ptr) * fs->code_align;
00903 insn_ptr += 1;
00904 break;
00905 case DW_CFA_advance_loc2:
00906 fs->pc += read_2u (insn_ptr) * fs->code_align;
00907 insn_ptr += 2;
00908 break;
00909 case DW_CFA_advance_loc4:
00910 fs->pc += read_4u (insn_ptr) * fs->code_align;
00911 insn_ptr += 4;
00912 break;
00913
00914 case DW_CFA_offset_extended:
00915 insn_ptr = read_uleb128 (insn_ptr, ®);
00916 insn_ptr = read_uleb128 (insn_ptr, &utmp);
00917 offset = (_Unwind_Sword) utmp * fs->data_align;
00918 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
00919 = REG_SAVED_OFFSET;
00920 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
00921 break;
00922
00923 case DW_CFA_restore_extended:
00924 insn_ptr = read_uleb128 (insn_ptr, ®);
00925
00926
00927 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED;
00928 break;
00929
00930 case DW_CFA_undefined:
00931 case DW_CFA_same_value:
00932 insn_ptr = read_uleb128 (insn_ptr, ®);
00933 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED;
00934 break;
00935
00936 case DW_CFA_nop:
00937 break;
00938
00939 case DW_CFA_register:
00940 {
00941 _Unwind_Word reg2;
00942 insn_ptr = read_uleb128 (insn_ptr, ®);
00943 insn_ptr = read_uleb128 (insn_ptr, ®2);
00944 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_REG;
00945 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.reg = reg2;
00946 }
00947 break;
00948
00949 case DW_CFA_remember_state:
00950 {
00951 struct frame_state_reg_info *new_rs;
00952 if (unused_rs)
00953 {
00954 new_rs = unused_rs;
00955 unused_rs = unused_rs->prev;
00956 }
00957 else
00958 new_rs = alloca (sizeof (struct frame_state_reg_info));
00959
00960 *new_rs = fs->regs;
00961 fs->regs.prev = new_rs;
00962 }
00963 break;
00964
00965 case DW_CFA_restore_state:
00966 {
00967 struct frame_state_reg_info *old_rs = fs->regs.prev;
00968 fs->regs = *old_rs;
00969 old_rs->prev = unused_rs;
00970 unused_rs = old_rs;
00971 }
00972 break;
00973
00974 case DW_CFA_def_cfa:
00975 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
00976 insn_ptr = read_uleb128 (insn_ptr, &utmp);
00977 fs->cfa_offset = utmp;
00978 fs->cfa_how = CFA_REG_OFFSET;
00979 break;
00980
00981 case DW_CFA_def_cfa_register:
00982 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
00983 fs->cfa_how = CFA_REG_OFFSET;
00984 break;
00985
00986 case DW_CFA_def_cfa_offset:
00987 insn_ptr = read_uleb128 (insn_ptr, &utmp);
00988 fs->cfa_offset = utmp;
00989
00990 break;
00991
00992 case DW_CFA_def_cfa_expression:
00993 fs->cfa_exp = insn_ptr;
00994 fs->cfa_how = CFA_EXP;
00995 insn_ptr = read_uleb128 (insn_ptr, &utmp);
00996 insn_ptr += utmp;
00997 break;
00998
00999 case DW_CFA_expression:
01000 insn_ptr = read_uleb128 (insn_ptr, ®);
01001 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_EXP;
01002 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.exp = insn_ptr;
01003 insn_ptr = read_uleb128 (insn_ptr, &utmp);
01004 insn_ptr += utmp;
01005 break;
01006
01007
01008 case DW_CFA_offset_extended_sf:
01009 insn_ptr = read_uleb128 (insn_ptr, ®);
01010 insn_ptr = read_sleb128 (insn_ptr, &stmp);
01011 offset = stmp * fs->data_align;
01012 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
01013 = REG_SAVED_OFFSET;
01014 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
01015 break;
01016
01017 case DW_CFA_def_cfa_sf:
01018 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
01019 insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
01020 fs->cfa_how = CFA_REG_OFFSET;
01021 fs->cfa_offset *= fs->data_align;
01022 break;
01023
01024 case DW_CFA_def_cfa_offset_sf:
01025 insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
01026 fs->cfa_offset *= fs->data_align;
01027
01028 break;
01029
01030 case DW_CFA_val_offset:
01031 insn_ptr = read_uleb128 (insn_ptr, ®);
01032 insn_ptr = read_uleb128 (insn_ptr, &utmp);
01033 offset = (_Unwind_Sword) utmp * fs->data_align;
01034 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
01035 = REG_SAVED_VAL_OFFSET;
01036 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
01037 break;
01038
01039 case DW_CFA_val_offset_sf:
01040 insn_ptr = read_uleb128 (insn_ptr, ®);
01041 insn_ptr = read_sleb128 (insn_ptr, &stmp);
01042 offset = stmp * fs->data_align;
01043 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
01044 = REG_SAVED_VAL_OFFSET;
01045 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
01046 break;
01047
01048 case DW_CFA_val_expression:
01049 insn_ptr = read_uleb128 (insn_ptr, ®);
01050 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
01051 = REG_SAVED_VAL_EXP;
01052 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.exp = insn_ptr;
01053 insn_ptr = read_uleb128 (insn_ptr, &utmp);
01054 insn_ptr += utmp;
01055 break;
01056
01057 case DW_CFA_GNU_window_save:
01058
01059 for (reg = 16; reg < 32; ++reg)
01060 {
01061 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
01062 fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
01063 }
01064 break;
01065
01066 case DW_CFA_GNU_args_size:
01067 insn_ptr = read_uleb128 (insn_ptr, &context->args_size);
01068 break;
01069
01070 case DW_CFA_GNU_negative_offset_extended:
01071
01072
01073 insn_ptr = read_uleb128 (insn_ptr, ®);
01074 insn_ptr = read_uleb128 (insn_ptr, &utmp);
01075 offset = (_Unwind_Word) utmp * fs->data_align;
01076 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
01077 = REG_SAVED_OFFSET;
01078 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = -offset;
01079 break;
01080
01081 default:
01082 gcc_unreachable ();
01083 }
01084 }
01085 }
01086
01087
01088
01089
01090
01091
01092 static _Unwind_Reason_Code
01093 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
01094 {
01095 const struct dwarf_fde *fde;
01096 const struct dwarf_cie *cie;
01097 const unsigned char *aug, *insn, *end;
01098
01099 memset (fs, 0, sizeof (*fs));
01100 context->args_size = 0;
01101 context->lsda = 0;
01102
01103 if (context->ra == 0)
01104 return _URC_END_OF_STACK;
01105
01106 fde = _Unwind_Find_FDE (context->ra + _Unwind_IsSignalFrame (context) - 1,
01107 &context->bases);
01108 if (fde == NULL)
01109 {
01110 #ifdef MD_FALLBACK_FRAME_STATE_FOR
01111
01112
01113
01114 return MD_FALLBACK_FRAME_STATE_FOR (context, fs);
01115 #else
01116 return _URC_END_OF_STACK;
01117 #endif
01118 }
01119
01120 fs->pc = context->bases.func;
01121
01122 cie = get_cie (fde);
01123 insn = extract_cie_info (cie, context, fs);
01124 if (insn == NULL)
01125
01126 return _URC_FATAL_PHASE1_ERROR;
01127
01128
01129 end = (unsigned char *) next_fde ((struct dwarf_fde *) cie);
01130 execute_cfa_program (insn, end, context, fs);
01131
01132
01133 aug = (unsigned char *) fde + sizeof (*fde);
01134 aug += 2 * size_of_encoded_value (fs->fde_encoding);
01135 insn = NULL;
01136 if (fs->saw_z)
01137 {
01138 _Unwind_Word i;
01139 aug = read_uleb128 (aug, &i);
01140 insn = aug + i;
01141 }
01142 if (fs->lsda_encoding != DW_EH_PE_omit)
01143 {
01144 _Unwind_Ptr lsda;
01145
01146 aug = read_encoded_value (context, fs->lsda_encoding, aug, &lsda);
01147 context->lsda = (void *) lsda;
01148 }
01149
01150
01151 if (insn == NULL)
01152 insn = aug;
01153 end = (unsigned char *) next_fde (fde);
01154 execute_cfa_program (insn, end, context, fs);
01155
01156 return _URC_NO_REASON;
01157 }
01158
01159 typedef struct frame_state
01160 {
01161 void *cfa;
01162 void *eh_ptr;
01163 long cfa_offset;
01164 long args_size;
01165 long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
01166 unsigned short cfa_reg;
01167 unsigned short retaddr_column;
01168 char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
01169 } frame_state;
01170
01171 struct frame_state * __frame_state_for (void *, struct frame_state *);
01172
01173
01174
01175
01176
01177 struct frame_state *
01178 __frame_state_for (void *pc_target, struct frame_state *state_in)
01179 {
01180 struct _Unwind_Context context;
01181 _Unwind_FrameState fs;
01182 int reg;
01183
01184 memset (&context, 0, sizeof (struct _Unwind_Context));
01185 context.flags = EXTENDED_CONTEXT_BIT;
01186 context.ra = pc_target + 1;
01187
01188 if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
01189 return 0;
01190
01191
01192
01193 if (fs.cfa_how == CFA_EXP)
01194 return 0;
01195
01196 for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
01197 {
01198 state_in->saved[reg] = fs.regs.reg[reg].how;
01199 switch (state_in->saved[reg])
01200 {
01201 case REG_SAVED_REG:
01202 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
01203 break;
01204 case REG_SAVED_OFFSET:
01205 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
01206 break;
01207 default:
01208 state_in->reg_or_offset[reg] = 0;
01209 break;
01210 }
01211 }
01212
01213 state_in->cfa_offset = fs.cfa_offset;
01214 state_in->cfa_reg = fs.cfa_reg;
01215 state_in->retaddr_column = fs.retaddr_column;
01216 state_in->args_size = context.args_size;
01217 state_in->eh_ptr = fs.eh_ptr;
01218
01219 return state_in;
01220 }
01221
01222 typedef union { _Unwind_Ptr ptr; _Unwind_Word word; } _Unwind_SpTmp;
01223
01224 static inline void
01225 _Unwind_SetSpColumn (struct _Unwind_Context *context, void *cfa,
01226 _Unwind_SpTmp *tmp_sp)
01227 {
01228 int size = dwarf_reg_size_table[__builtin_dwarf_sp_column ()];
01229
01230 if (size == sizeof(_Unwind_Ptr))
01231 tmp_sp->ptr = (_Unwind_Ptr) cfa;
01232 else
01233 {
01234 gcc_assert (size == sizeof(_Unwind_Word));
01235 tmp_sp->word = (_Unwind_Ptr) cfa;
01236 }
01237 _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), tmp_sp);
01238 }
01239
01240 static void
01241 uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
01242 {
01243 struct _Unwind_Context orig_context = *context;
01244 void *cfa;
01245 long i;
01246
01247 #ifdef EH_RETURN_STACKADJ_RTX
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263 _Unwind_SpTmp tmp_sp;
01264
01265 if (!_Unwind_GetGRPtr (&orig_context, __builtin_dwarf_sp_column ()))
01266 _Unwind_SetSpColumn (&orig_context, context->cfa, &tmp_sp);
01267 _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), NULL);
01268 #endif
01269
01270
01271 switch (fs->cfa_how)
01272 {
01273 case CFA_REG_OFFSET:
01274 cfa = _Unwind_GetPtr (&orig_context, fs->cfa_reg);
01275 cfa += fs->cfa_offset;
01276 break;
01277
01278 case CFA_EXP:
01279 {
01280 const unsigned char *exp = fs->cfa_exp;
01281 _Unwind_Word len;
01282
01283 exp = read_uleb128 (exp, &len);
01284 cfa = (void *) (_Unwind_Ptr)
01285 execute_stack_op (exp, exp + len, &orig_context, 0);
01286 break;
01287 }
01288
01289 default:
01290 gcc_unreachable ();
01291 }
01292 context->cfa = cfa;
01293
01294
01295 for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
01296 switch (fs->regs.reg[i].how)
01297 {
01298 case REG_UNSAVED:
01299 break;
01300
01301 case REG_SAVED_OFFSET:
01302 _Unwind_SetGRPtr (context, i,
01303 (void *) (cfa + fs->regs.reg[i].loc.offset));
01304 break;
01305
01306 case REG_SAVED_REG:
01307 if (_Unwind_GRByValue (&orig_context, fs->regs.reg[i].loc.reg))
01308 _Unwind_SetGRValue (context, i,
01309 _Unwind_GetGR (&orig_context,
01310 fs->regs.reg[i].loc.reg));
01311 else
01312 _Unwind_SetGRPtr (context, i,
01313 _Unwind_GetGRPtr (&orig_context,
01314 fs->regs.reg[i].loc.reg));
01315 break;
01316
01317 case REG_SAVED_EXP:
01318 {
01319 const unsigned char *exp = fs->regs.reg[i].loc.exp;
01320 _Unwind_Word len;
01321 _Unwind_Ptr val;
01322
01323 exp = read_uleb128 (exp, &len);
01324 val = execute_stack_op (exp, exp + len, &orig_context,
01325 (_Unwind_Ptr) cfa);
01326 _Unwind_SetGRPtr (context, i, (void *) val);
01327 }
01328 break;
01329
01330 case REG_SAVED_VAL_OFFSET:
01331 _Unwind_SetGRValue (context, i,
01332 (_Unwind_Internal_Ptr)
01333 (cfa + fs->regs.reg[i].loc.offset));
01334 break;
01335
01336 case REG_SAVED_VAL_EXP:
01337 {
01338 const unsigned char *exp = fs->regs.reg[i].loc.exp;
01339 _Unwind_Word len;
01340 _Unwind_Ptr val;
01341
01342 exp = read_uleb128 (exp, &len);
01343 val = execute_stack_op (exp, exp + len, &orig_context,
01344 (_Unwind_Ptr) cfa);
01345 _Unwind_SetGRValue (context, i, val);
01346 }
01347 break;
01348 }
01349
01350 _Unwind_SetSignalFrame (context, fs->signal_frame);
01351
01352 #ifdef MD_FROB_UPDATE_CONTEXT
01353 MD_FROB_UPDATE_CONTEXT (context, fs);
01354 #endif
01355 }
01356
01357
01358
01359
01360
01361
01362 static void
01363 uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
01364 {
01365 uw_update_context_1 (context, fs);
01366
01367
01368
01369 context->ra = __builtin_extract_return_addr
01370 (_Unwind_GetPtr (context, fs->retaddr_column));
01371 }
01372
01373 static void
01374 uw_advance_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
01375 {
01376 uw_update_context (context, fs);
01377 }
01378
01379
01380
01381
01382 #define uw_init_context(CONTEXT) \
01383 do \
01384 { \
01385
01386 \
01387 __builtin_unwind_init (); \
01388 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
01389 __builtin_return_address (0)); \
01390 } \
01391 while (0)
01392
01393 static inline void
01394 init_dwarf_reg_size_table (void)
01395 {
01396 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
01397 }
01398
01399 static void
01400 uw_init_context_1 (struct _Unwind_Context *context,
01401 void *outer_cfa, void *outer_ra)
01402 {
01403 void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
01404 _Unwind_FrameState fs;
01405 _Unwind_SpTmp sp_slot;
01406 _Unwind_Reason_Code code;
01407
01408 memset (context, 0, sizeof (struct _Unwind_Context));
01409 context->ra = ra;
01410 context->flags = EXTENDED_CONTEXT_BIT;
01411
01412 code = uw_frame_state_for (context, &fs);
01413 gcc_assert (code == _URC_NO_REASON);
01414
01415 #if __GTHREADS
01416 {
01417 static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
01418 if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
01419 || dwarf_reg_size_table[0] == 0)
01420 init_dwarf_reg_size_table ();
01421 }
01422 #else
01423 if (dwarf_reg_size_table[0] == 0)
01424 init_dwarf_reg_size_table ();
01425 #endif
01426
01427
01428 _Unwind_SetSpColumn (context, outer_cfa, &sp_slot);
01429 fs.cfa_how = CFA_REG_OFFSET;
01430 fs.cfa_reg = __builtin_dwarf_sp_column ();
01431 fs.cfa_offset = 0;
01432
01433 uw_update_context_1 (context, &fs);
01434
01435
01436
01437
01438 context->ra = __builtin_extract_return_addr (outer_ra);
01439 }
01440
01441
01442
01443
01444
01445
01446 #define uw_install_context(CURRENT, TARGET) \
01447 do \
01448 { \
01449 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
01450 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
01451 __builtin_eh_return (offset, handler); \
01452 } \
01453 while (0)
01454
01455 static long
01456 uw_install_context_1 (struct _Unwind_Context *current,
01457 struct _Unwind_Context *target)
01458 {
01459 long i;
01460 _Unwind_SpTmp sp_slot;
01461
01462
01463
01464 if (!_Unwind_GetGRPtr (target, __builtin_dwarf_sp_column ()))
01465 _Unwind_SetSpColumn (target, target->cfa, &sp_slot);
01466
01467 for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
01468 {
01469 void *c = current->reg[i];
01470 void *t = target->reg[i];
01471
01472 gcc_assert (current->by_value[i] == 0);
01473 if (target->by_value[i] && c)
01474 {
01475 _Unwind_Word w;
01476 _Unwind_Ptr p;
01477 if (dwarf_reg_size_table[i] == sizeof (_Unwind_Word))
01478 {
01479 w = (_Unwind_Internal_Ptr) t;
01480 memcpy (c, &w, sizeof (_Unwind_Word));
01481 }
01482 else
01483 {
01484 gcc_assert (dwarf_reg_size_table[i] == sizeof (_Unwind_Ptr));
01485 p = (_Unwind_Internal_Ptr) t;
01486 memcpy (c, &p, sizeof (_Unwind_Ptr));
01487 }
01488 }
01489 else if (t && c && t != c)
01490 memcpy (c, t, dwarf_reg_size_table[i]);
01491 }
01492
01493
01494
01495
01496 if (!_Unwind_GetGRPtr (current, __builtin_dwarf_sp_column ()))
01497 {
01498 void *target_cfa;
01499
01500 target_cfa = _Unwind_GetPtr (target, __builtin_dwarf_sp_column ());
01501
01502
01503 if (STACK_GROWS_DOWNWARD)
01504 return target_cfa - current->cfa + target->args_size;
01505 else
01506 return current->cfa - target_cfa - target->args_size;
01507 }
01508 return 0;
01509 }
01510
01511 static inline _Unwind_Ptr
01512 uw_identify_context (struct _Unwind_Context *context)
01513 {
01514 return _Unwind_GetIP (context);
01515 }
01516
01517
01518 #include "unwind.inc"
01519
01520 #if defined (USE_GAS_SYMVER) && defined (SHARED) && defined (USE_LIBUNWIND_EXCEPTIONS)
01521 alias (_Unwind_Backtrace);
01522 alias (_Unwind_DeleteException);
01523 alias (_Unwind_FindEnclosingFunction);
01524 alias (_Unwind_ForcedUnwind);
01525 alias (_Unwind_GetDataRelBase);
01526 alias (_Unwind_GetTextRelBase);
01527 alias (_Unwind_GetCFA);
01528 alias (_Unwind_GetGR);
01529 alias (_Unwind_GetIP);
01530 alias (_Unwind_GetLanguageSpecificData);
01531 alias (_Unwind_GetRegionStart);
01532 alias (_Unwind_RaiseException);
01533 alias (_Unwind_Resume);
01534 alias (_Unwind_Resume_or_Rethrow);
01535 alias (_Unwind_SetGR);
01536 alias (_Unwind_SetIP);
01537 #endif
01538
01539 #endif