Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/ia64/unwind-ia64.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 | a06113de4d67 |
children |
comparison
equal
deleted
inserted
replaced
52:c156f1bd5cd9 | 55:77e2b8dfacca |
---|---|
39 /* This isn't thread safe, but nice for occasional tests. */ | 39 /* This isn't thread safe, but nice for occasional tests. */ |
40 #undef ENABLE_MALLOC_CHECKING | 40 #undef ENABLE_MALLOC_CHECKING |
41 | 41 |
42 #ifndef __USING_SJLJ_EXCEPTIONS__ | 42 #ifndef __USING_SJLJ_EXCEPTIONS__ |
43 | 43 |
44 #define UNW_VER(x) ((x) >> 48) | 44 |
45 #define UNW_FLAG_MASK 0x0000ffff00000000 | 45 /* By default, assume personality routine interface compatibility with |
46 #define UNW_FLAG_OSMASK 0x0000f00000000000 | 46 our expectations. */ |
47 #define UNW_FLAG_EHANDLER(x) ((x) & 0x0000000100000000L) | 47 #ifndef MD_UNW_COMPATIBLE_PERSONALITY_P |
48 #define UNW_FLAG_UHANDLER(x) ((x) & 0x0000000200000000L) | 48 #define MD_UNW_COMPATIBLE_PERSONALITY_P(HEADER) 1 |
49 #define UNW_LENGTH(x) ((x) & 0x00000000ffffffffL) | 49 #endif |
50 | 50 |
51 enum unw_application_register | 51 enum unw_application_register |
52 { | 52 { |
53 UNW_AR_BSP, | 53 UNW_AR_BSP, |
54 UNW_AR_BSPSTORE, | 54 UNW_AR_BSPSTORE, |
202 Appears to be write-only? */ | 202 Appears to be write-only? */ |
203 unsigned long *bspstore_loc; | 203 unsigned long *bspstore_loc; |
204 unsigned long *pfs_loc; /* Save location for pfs in current | 204 unsigned long *pfs_loc; /* Save location for pfs in current |
205 (corr. to sp) frame. Target | 205 (corr. to sp) frame. Target |
206 contains cfm for caller. */ | 206 contains cfm for caller. */ |
207 unsigned long *signal_pfs_loc;/* Save location for pfs in current | |
208 signal frame. Target contains | |
209 pfs for caller. */ | |
207 unsigned long *pri_unat_loc; | 210 unsigned long *pri_unat_loc; |
208 unsigned long *unat_loc; | 211 unsigned long *unat_loc; |
209 unsigned long *lc_loc; | 212 unsigned long *lc_loc; |
210 unsigned long *fpsr_loc; | 213 unsigned long *fpsr_loc; |
211 | 214 |
437 static enum unw_register_index __attribute__((const)) | 440 static enum unw_register_index __attribute__((const)) |
438 decode_abreg (unsigned char abreg, int memory) | 441 decode_abreg (unsigned char abreg, int memory) |
439 { | 442 { |
440 switch (abreg) | 443 switch (abreg) |
441 { | 444 { |
445 #if TARGET_ABI_OPEN_VMS | |
446 /* OpenVMS Calling Standard specifies R3 - R31. */ | |
447 case 0x03 ... 0x1f: return UNW_REG_R2 + (abreg - 0x02); | |
448 #else | |
449 /* Standard Intel ABI specifies GR 4 - 7. */ | |
442 case 0x04 ... 0x07: return UNW_REG_R4 + (abreg - 0x04); | 450 case 0x04 ... 0x07: return UNW_REG_R4 + (abreg - 0x04); |
451 #endif | |
443 case 0x22 ... 0x25: return UNW_REG_F2 + (abreg - 0x22); | 452 case 0x22 ... 0x25: return UNW_REG_F2 + (abreg - 0x22); |
444 case 0x30 ... 0x3f: return UNW_REG_F16 + (abreg - 0x30); | 453 case 0x30 ... 0x3f: return UNW_REG_F16 + (abreg - 0x30); |
445 case 0x41 ... 0x45: return UNW_REG_B1 + (abreg - 0x41); | 454 case 0x41 ... 0x45: return UNW_REG_B1 + (abreg - 0x41); |
446 case 0x60: return UNW_REG_PR; | 455 case 0x60: return UNW_REG_PR; |
447 case 0x61: return UNW_REG_PSP; | 456 case 0x61: return UNW_REG_PSP; |
1728 } | 1737 } |
1729 | 1738 |
1730 void * | 1739 void * |
1731 _Unwind_FindEnclosingFunction (void *pc) | 1740 _Unwind_FindEnclosingFunction (void *pc) |
1732 { | 1741 { |
1733 struct unw_table_entry *ent; | 1742 struct unw_table_entry *entp, ent; |
1734 unsigned long segment_base, gp; | 1743 unsigned long segment_base, gp; |
1735 | 1744 |
1736 ent = _Unwind_FindTableEntry (pc, &segment_base, &gp); | 1745 entp = _Unwind_FindTableEntry (pc, &segment_base, &gp, &ent); |
1737 if (ent == NULL) | 1746 if (entp == NULL) |
1738 return NULL; | 1747 return NULL; |
1739 else | 1748 else |
1740 return (void *)(segment_base + ent->start_offset); | 1749 return (void *)(segment_base + entp->start_offset); |
1741 } | 1750 } |
1742 | 1751 |
1743 /* Get the value of the CFA as saved in CONTEXT. In GCC/Dwarf2 parlance, | 1752 /* Get the value of the CFA as saved in CONTEXT. In GCC/Dwarf2 parlance, |
1744 the CFA is the value of the stack pointer on entry; In IA-64 unwind | 1753 the CFA is the value of the stack pointer on entry; In IA-64 unwind |
1745 parlance, this is the PSP. */ | 1754 parlance, this is the PSP. */ |
1763 #endif | 1772 #endif |
1764 | 1773 |
1765 static _Unwind_Reason_Code | 1774 static _Unwind_Reason_Code |
1766 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs) | 1775 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs) |
1767 { | 1776 { |
1768 struct unw_table_entry *ent; | 1777 struct unw_table_entry *entp, ent; |
1769 unsigned long *unw, header, length; | 1778 unsigned long *unw, header, length; |
1770 unsigned char *insn, *insn_end; | 1779 unsigned char *insn, *insn_end; |
1771 unsigned long segment_base; | 1780 unsigned long segment_base; |
1772 struct unw_reg_info *r; | 1781 struct unw_reg_info *r; |
1773 | 1782 |
1774 memset (fs, 0, sizeof (*fs)); | 1783 memset (fs, 0, sizeof (*fs)); |
1775 for (r = fs->curr.reg; r < fs->curr.reg + UNW_NUM_REGS; ++r) | 1784 for (r = fs->curr.reg; r < fs->curr.reg + UNW_NUM_REGS; ++r) |
1776 r->when = UNW_WHEN_NEVER; | 1785 r->when = UNW_WHEN_NEVER; |
1777 context->lsda = 0; | 1786 context->lsda = 0; |
1778 | 1787 |
1779 ent = _Unwind_FindTableEntry ((void *) context->rp, | 1788 entp = _Unwind_FindTableEntry ((void *) context->rp, |
1780 &segment_base, &context->gp); | 1789 &segment_base, &context->gp, &ent); |
1781 if (ent == NULL) | 1790 if (entp == NULL) |
1782 { | 1791 { |
1783 /* Couldn't find unwind info for this function. Try an | 1792 /* Couldn't find unwind info for this function. Try an |
1784 os-specific fallback mechanism. This will necessarily | 1793 os-specific fallback mechanism. This will necessarily |
1785 not provide a personality routine or LSDA. */ | 1794 not provide a personality routine or LSDA. */ |
1786 #ifdef MD_FALLBACK_FRAME_STATE_FOR | 1795 #ifdef MD_FALLBACK_FRAME_STATE_FOR |
1787 if (MD_FALLBACK_FRAME_STATE_FOR (context, fs) == _URC_NO_REASON) | 1796 if (MD_FALLBACK_FRAME_STATE_FOR (context, fs) == _URC_NO_REASON) |
1788 return _URC_NO_REASON; | 1797 return _URC_NO_REASON; |
1798 #endif | |
1789 | 1799 |
1790 /* [SCRA 11.4.1] A leaf function with no memory stack, no exception | 1800 /* [SCRA 11.4.1] A leaf function with no memory stack, no exception |
1791 handlers, and which keeps the return value in B0 does not need | 1801 handlers, and which keeps the return value in B0 does not need |
1792 an unwind table entry. | 1802 an unwind table entry. |
1793 | 1803 |
1794 This can only happen in the frame after unwinding through a signal | 1804 This can only happen in the frame after unwinding through a signal |
1795 handler. Avoid infinite looping by requiring that B0 != RP. | 1805 handler. Avoid infinite looping by requiring that B0 != RP. |
1796 RP == 0 terminates the chain. */ | 1806 RP == 0 terminates the chain. */ |
1797 if (context->br_loc[0] && *context->br_loc[0] != context->rp | 1807 if (context->br_loc[0] |
1808 && *context->br_loc[0] != context->rp | |
1798 && context->rp != 0) | 1809 && context->rp != 0) |
1799 { | 1810 goto skip_unwind_info; |
1800 fs->curr.reg[UNW_REG_RP].where = UNW_WHERE_BR; | 1811 |
1801 fs->curr.reg[UNW_REG_RP].when = -1; | |
1802 fs->curr.reg[UNW_REG_RP].val = 0; | |
1803 return _URC_NO_REASON; | |
1804 } | |
1805 #endif | |
1806 return _URC_END_OF_STACK; | 1812 return _URC_END_OF_STACK; |
1807 } | 1813 } |
1808 | 1814 |
1809 context->region_start = ent->start_offset + segment_base; | 1815 context->region_start = entp->start_offset + segment_base; |
1810 fs->when_target = ((context->rp & -16) - context->region_start) / 16 * 3 | 1816 fs->when_target = ((context->rp & -16) - context->region_start) / 16 * 3 |
1811 + (context->rp & 15); | 1817 + (context->rp & 15); |
1812 | 1818 |
1813 unw = (unsigned long *) (ent->info_offset + segment_base); | 1819 unw = (unsigned long *) (entp->info_offset + segment_base); |
1814 header = *unw; | 1820 header = *unw; |
1815 length = UNW_LENGTH (header); | 1821 length = UNW_LENGTH (header); |
1816 | 1822 |
1817 /* ??? Perhaps check UNW_VER / UNW_FLAG_OSMASK. */ | 1823 /* Some operating systems use the personality routine slot in way not |
1818 | 1824 compatible with what we expect. For instance, OpenVMS uses this slot to |
1819 if (UNW_FLAG_EHANDLER (header) | UNW_FLAG_UHANDLER (header)) | 1825 designate "condition handlers" with very different arguments than what we |
1826 would be providing. Such cases are typically identified from OS specific | |
1827 bits in the unwind information block header, and checked by the target | |
1828 MD_UNW_COMPATIBLE_PERSONALITY_P macro. | |
1829 | |
1830 We just pretend there is no personality from our standpoint in such | |
1831 situations, and expect GCC not to set the identifying bits itself so that | |
1832 compatible personalities for GCC compiled code are called. | |
1833 | |
1834 Of course, this raises the question of what combinations of native/GCC | |
1835 calls can be expected to behave properly exception handling-wise. We are | |
1836 not to provide a magic answer here, merely to prevent crashes assuming | |
1837 users know what they are doing. | |
1838 | |
1839 ??? Perhaps check UNW_VER / UNW_FLAG_OSMASK as well. */ | |
1840 | |
1841 if (MD_UNW_COMPATIBLE_PERSONALITY_P (header) | |
1842 && (UNW_FLAG_EHANDLER (header) | UNW_FLAG_UHANDLER (header))) | |
1820 { | 1843 { |
1821 fs->personality = | 1844 fs->personality = |
1822 *(_Unwind_Personality_Fn *) (unw[length + 1] + context->gp); | 1845 *(_Unwind_Personality_Fn *) (unw[length + 1] + context->gp); |
1823 context->lsda = unw + length + 2; | 1846 context->lsda = unw + length + 2; |
1824 } | 1847 } |
1848 if ((r->where == UNW_WHERE_PSPREL && r->val <= 0x10) | 1871 if ((r->where == UNW_WHERE_PSPREL && r->val <= 0x10) |
1849 || r->where == UNW_WHERE_SPREL) | 1872 || r->where == UNW_WHERE_SPREL) |
1850 r->where = UNW_WHERE_NONE; | 1873 r->where = UNW_WHERE_NONE; |
1851 } | 1874 } |
1852 | 1875 |
1853 /* If RP did't get saved, generate entry for the return link register. */ | 1876 skip_unwind_info: |
1877 /* If RP didn't get saved, generate entry for the return link register. */ | |
1854 if (fs->curr.reg[UNW_REG_RP].when >= fs->when_target) | 1878 if (fs->curr.reg[UNW_REG_RP].when >= fs->when_target) |
1855 { | 1879 { |
1856 fs->curr.reg[UNW_REG_RP].where = UNW_WHERE_BR; | 1880 fs->curr.reg[UNW_REG_RP].where = UNW_WHERE_BR; |
1857 fs->curr.reg[UNW_REG_RP].when = -1; | 1881 fs->curr.reg[UNW_REG_RP].when = -1; |
1858 fs->curr.reg[UNW_REG_RP].val = fs->return_link_reg; | 1882 fs->curr.reg[UNW_REG_RP].val = fs->return_link_reg; |
1883 } | |
1884 | |
1885 /* There is a subtlety for the frame after unwinding through a signal | |
1886 handler: should we restore the cfm as usual or the pfs? We can't | |
1887 restore both because we use br.ret to resume execution of user code. | |
1888 For other frames the procedure is by definition non-leaf so the pfs | |
1889 is saved and restored and thus effectively dead in the body; only | |
1890 the cfm need therefore be restored. | |
1891 | |
1892 Here we have 2 cases: | |
1893 - either the pfs is saved and restored and thus effectively dead | |
1894 like in regular frames; then we do nothing special and restore | |
1895 the cfm. | |
1896 - or the pfs is not saved and thus live; but in that case the | |
1897 procedure is necessarily leaf so the cfm is effectively dead | |
1898 and we restore the pfs. */ | |
1899 if (context->signal_pfs_loc) | |
1900 { | |
1901 if (fs->curr.reg[UNW_REG_PFS].when >= fs->when_target) | |
1902 context->pfs_loc = context->signal_pfs_loc; | |
1903 context->signal_pfs_loc = NULL; | |
1859 } | 1904 } |
1860 | 1905 |
1861 return _URC_NO_REASON; | 1906 return _URC_NO_REASON; |
1862 } | 1907 } |
1863 | 1908 |
2079 should try to make that work again. */ \ | 2124 should try to make that work again. */ \ |
2080 __builtin_unwind_init(); \ | 2125 __builtin_unwind_init(); \ |
2081 uw_init_context_1 (CONTEXT, __builtin_ia64_bsp ()); \ | 2126 uw_init_context_1 (CONTEXT, __builtin_ia64_bsp ()); \ |
2082 } while (0) | 2127 } while (0) |
2083 | 2128 |
2084 static void | 2129 static void __attribute__((noinline)) |
2085 uw_init_context_1 (struct _Unwind_Context *context, void *bsp) | 2130 uw_init_context_1 (struct _Unwind_Context *context, void *bsp) |
2086 { | 2131 { |
2087 void *rp = __builtin_extract_return_addr (__builtin_return_address (0)); | 2132 void *rp = __builtin_extract_return_addr (__builtin_return_address (0)); |
2088 /* Set psp to the caller's stack pointer. */ | 2133 /* Set psp to the caller's stack pointer. */ |
2089 void *psp = __builtin_dwarf_cfa () - 16; | 2134 void *psp = __builtin_dwarf_cfa () - 16; |