Mercurial > hg > CbC > CbC_gcc
comparison gcc/unwind-dw2.c @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | 3bfb6c00c1e0 |
children | b7f97abdc517 |
comparison
equal
deleted
inserted
replaced
52:c156f1bd5cd9 | 55:77e2b8dfacca |
---|---|
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, | 2 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, |
3 2008, 2009, 2010 Free Software Foundation, Inc. | 3 2008, 2009 Free Software Foundation, Inc. |
4 | 4 |
5 This file is part of GCC. | 5 This file is part of GCC. |
6 | 6 |
7 GCC is free software; you can redistribute it and/or modify it | 7 GCC is free software; you can redistribute it and/or modify it |
8 under the terms of the GNU General Public License as published by | 8 under the terms of the GNU General Public License as published by |
402 | 402 |
403 /* "P" indicates a personality routine in the CIE augmentation. */ | 403 /* "P" indicates a personality routine in the CIE augmentation. */ |
404 else if (aug[0] == 'P') | 404 else if (aug[0] == 'P') |
405 { | 405 { |
406 _Unwind_Ptr personality; | 406 _Unwind_Ptr personality; |
407 | 407 |
408 p = read_encoded_value (context, *p, p + 1, &personality); | 408 p = read_encoded_value (context, *p, p + 1, &personality); |
409 fs->personality = (_Unwind_Personality_Fn) personality; | 409 fs->personality = (_Unwind_Personality_Fn) personality; |
410 aug += 1; | 410 aug += 1; |
411 } | 411 } |
412 | 412 |
670 case DW_OP_not: | 670 case DW_OP_not: |
671 case DW_OP_plus_uconst: | 671 case DW_OP_plus_uconst: |
672 /* Unary operations. */ | 672 /* Unary operations. */ |
673 gcc_assert (stack_elt); | 673 gcc_assert (stack_elt); |
674 stack_elt -= 1; | 674 stack_elt -= 1; |
675 | 675 |
676 result = stack[stack_elt]; | 676 result = stack[stack_elt]; |
677 | 677 |
678 switch (op) | 678 switch (op) |
679 { | 679 { |
680 case DW_OP_deref: | 680 case DW_OP_deref: |
747 { | 747 { |
748 /* Binary operations. */ | 748 /* Binary operations. */ |
749 _Unwind_Word first, second; | 749 _Unwind_Word first, second; |
750 gcc_assert (stack_elt >= 2); | 750 gcc_assert (stack_elt >= 2); |
751 stack_elt -= 2; | 751 stack_elt -= 2; |
752 | 752 |
753 second = stack[stack_elt]; | 753 second = stack[stack_elt]; |
754 first = stack[stack_elt + 1]; | 754 first = stack[stack_elt + 1]; |
755 | 755 |
756 switch (op) | 756 switch (op) |
757 { | 757 { |
763 break; | 763 break; |
764 case DW_OP_minus: | 764 case DW_OP_minus: |
765 result = second - first; | 765 result = second - first; |
766 break; | 766 break; |
767 case DW_OP_mod: | 767 case DW_OP_mod: |
768 result = second % first; | 768 result = (_Unwind_Sword) second % (_Unwind_Sword) first; |
769 break; | 769 break; |
770 case DW_OP_mul: | 770 case DW_OP_mul: |
771 result = second * first; | 771 result = second * first; |
772 break; | 772 break; |
773 case DW_OP_or: | 773 case DW_OP_or: |
820 goto no_push; | 820 goto no_push; |
821 | 821 |
822 case DW_OP_bra: | 822 case DW_OP_bra: |
823 gcc_assert (stack_elt); | 823 gcc_assert (stack_elt); |
824 stack_elt -= 1; | 824 stack_elt -= 1; |
825 | 825 |
826 offset = read_2s (op_ptr); | 826 offset = read_2s (op_ptr); |
827 op_ptr += 2; | 827 op_ptr += 2; |
828 if (stack[stack_elt] != 0) | 828 if (stack[stack_elt] != 0) |
829 op_ptr += offset; | 829 op_ptr += offset; |
830 goto no_push; | 830 goto no_push; |
900 else switch (insn) | 900 else switch (insn) |
901 { | 901 { |
902 case DW_CFA_set_loc: | 902 case DW_CFA_set_loc: |
903 { | 903 { |
904 _Unwind_Ptr pc; | 904 _Unwind_Ptr pc; |
905 | 905 |
906 insn_ptr = read_encoded_value (context, fs->fde_encoding, | 906 insn_ptr = read_encoded_value (context, fs->fde_encoding, |
907 insn_ptr, &pc); | 907 insn_ptr, &pc); |
908 fs->pc = (void *) pc; | 908 fs->pc = (void *) pc; |
909 } | 909 } |
910 break; | 910 break; |
1162 insn = aug + i; | 1162 insn = aug + i; |
1163 } | 1163 } |
1164 if (fs->lsda_encoding != DW_EH_PE_omit) | 1164 if (fs->lsda_encoding != DW_EH_PE_omit) |
1165 { | 1165 { |
1166 _Unwind_Ptr lsda; | 1166 _Unwind_Ptr lsda; |
1167 | 1167 |
1168 aug = read_encoded_value (context, fs->lsda_encoding, aug, &lsda); | 1168 aug = read_encoded_value (context, fs->lsda_encoding, aug, &lsda); |
1169 context->lsda = (void *) lsda; | 1169 context->lsda = (void *) lsda; |
1170 } | 1170 } |
1171 | 1171 |
1172 /* Then the insns in the FDE up to our target PC. */ | 1172 /* Then the insns in the FDE up to our target PC. */ |
1246 static inline void | 1246 static inline void |
1247 _Unwind_SetSpColumn (struct _Unwind_Context *context, void *cfa, | 1247 _Unwind_SetSpColumn (struct _Unwind_Context *context, void *cfa, |
1248 _Unwind_SpTmp *tmp_sp) | 1248 _Unwind_SpTmp *tmp_sp) |
1249 { | 1249 { |
1250 int size = dwarf_reg_size_table[__builtin_dwarf_sp_column ()]; | 1250 int size = dwarf_reg_size_table[__builtin_dwarf_sp_column ()]; |
1251 | 1251 |
1252 if (size == sizeof(_Unwind_Ptr)) | 1252 if (size == sizeof(_Unwind_Ptr)) |
1253 tmp_sp->ptr = (_Unwind_Ptr) cfa; | 1253 tmp_sp->ptr = (_Unwind_Ptr) cfa; |
1254 else | 1254 else |
1255 { | 1255 { |
1256 gcc_assert (size == sizeof(_Unwind_Word)); | 1256 gcc_assert (size == sizeof(_Unwind_Word)); |
1429 init_dwarf_reg_size_table (void) | 1429 init_dwarf_reg_size_table (void) |
1430 { | 1430 { |
1431 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table); | 1431 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table); |
1432 } | 1432 } |
1433 | 1433 |
1434 static void | 1434 static void __attribute__((noinline)) |
1435 uw_init_context_1 (struct _Unwind_Context *context, | 1435 uw_init_context_1 (struct _Unwind_Context *context, |
1436 void *outer_cfa, void *outer_ra) | 1436 void *outer_cfa, void *outer_ra) |
1437 { | 1437 { |
1438 void *ra = __builtin_extract_return_addr (__builtin_return_address (0)); | 1438 void *ra = __builtin_extract_return_addr (__builtin_return_address (0)); |
1439 _Unwind_FrameState fs; | 1439 _Unwind_FrameState fs; |
1471 initialization context, then we can't see it in the given | 1471 initialization context, then we can't see it in the given |
1472 call frame data. So have the initialization context tell us. */ | 1472 call frame data. So have the initialization context tell us. */ |
1473 context->ra = __builtin_extract_return_addr (outer_ra); | 1473 context->ra = __builtin_extract_return_addr (outer_ra); |
1474 } | 1474 } |
1475 | 1475 |
1476 static void _Unwind_DebugHook (void *, void *) __attribute__ ((__noinline__)); | |
1477 | |
1478 /* This function is called during unwinding. It is intended as a hook | |
1479 for a debugger to intercept exceptions. CFA is the CFA of the | |
1480 target frame. HANDLER is the PC to which control will be | |
1481 transferred. */ | |
1482 static void | |
1483 _Unwind_DebugHook (void *cfa __attribute__ ((__unused__)), | |
1484 void *handler __attribute__ ((__unused__))) | |
1485 { | |
1486 asm (""); | |
1487 } | |
1476 | 1488 |
1477 /* Install TARGET into CURRENT so that we can return to it. This is a | 1489 /* Install TARGET into CURRENT so that we can return to it. This is a |
1478 macro because __builtin_eh_return must be invoked in the context of | 1490 macro because __builtin_eh_return must be invoked in the context of |
1479 our caller. */ | 1491 our caller. */ |
1480 | 1492 |
1481 #define uw_install_context(CURRENT, TARGET) \ | 1493 #define uw_install_context(CURRENT, TARGET) \ |
1482 do \ | 1494 do \ |
1483 { \ | 1495 { \ |
1484 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \ | 1496 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \ |
1485 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \ | 1497 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \ |
1486 __builtin_eh_return (offset, handler); \ | 1498 _Unwind_DebugHook ((TARGET)->cfa, handler); \ |
1487 } \ | 1499 __builtin_eh_return (offset, handler); \ |
1500 } \ | |
1488 while (0) | 1501 while (0) |
1489 | 1502 |
1490 static long | 1503 static long |
1491 uw_install_context_1 (struct _Unwind_Context *current, | 1504 uw_install_context_1 (struct _Unwind_Context *current, |
1492 struct _Unwind_Context *target) | 1505 struct _Unwind_Context *target) |
1544 } | 1557 } |
1545 | 1558 |
1546 static inline _Unwind_Ptr | 1559 static inline _Unwind_Ptr |
1547 uw_identify_context (struct _Unwind_Context *context) | 1560 uw_identify_context (struct _Unwind_Context *context) |
1548 { | 1561 { |
1549 return _Unwind_GetCFA (context); | 1562 /* The CFA is not sufficient to disambiguate the context of a function |
1563 interrupted by a signal before establishing its frame and the context | |
1564 of the signal itself. */ | |
1565 if (STACK_GROWS_DOWNWARD) | |
1566 return _Unwind_GetCFA (context) - _Unwind_IsSignalFrame (context); | |
1567 else | |
1568 return _Unwind_GetCFA (context) + _Unwind_IsSignalFrame (context); | |
1550 } | 1569 } |
1551 | 1570 |
1552 | 1571 |
1553 #include "unwind.inc" | 1572 #include "unwind.inc" |
1554 | 1573 |