Index: gcc/gcc/config/ia64/linux-unwind.h |
diff --git a/gcc/gcc/config/ia64/linux-unwind.h b/gcc/gcc/config/ia64/linux-unwind.h |
index e2bad480b7250690c8aef14c62bfeb52e416711b..93f762de5736aef3379bd9583706c983436603a6 100644 |
--- a/gcc/gcc/config/ia64/linux-unwind.h |
+++ b/gcc/gcc/config/ia64/linux-unwind.h |
@@ -23,7 +23,7 @@ |
<http://www.gnu.org/licenses/>. */ |
/* Do code reading to identify a signal frame, and set the frame |
- state data appropriately. See unwind-dw2.c for the structs. */ |
+ state data appropriately. See unwind-ia64.c for the structs. */ |
/* This works only for glibc-2.3 and later, because sigcontext is different |
in glibc-2.2.4. */ |
@@ -66,7 +66,7 @@ ia64_fallback_frame_state (struct _Unwind_Context *context, |
} |
context->fpsr_loc = &(sc->sc_ar_fpsr); |
- context->pfs_loc = &(sc->sc_ar_pfs); |
+ context->signal_pfs_loc = &(sc->sc_ar_pfs); |
context->lc_loc = &(sc->sc_ar_lc); |
context->unat_loc = &(sc->sc_ar_unat); |
context->br_loc[0] = &(sc->sc_br[0]); |
@@ -105,11 +105,17 @@ ia64_fallback_frame_state (struct _Unwind_Context *context, |
ia64_rse_skip_regs ((unsigned long *)(sc->sc_ar_bsp), -sof); |
} |
+ /* Account for use of br.ret to resume execution of user code. */ |
fs->curr.reg[UNW_REG_RP].where = UNW_WHERE_SPREL; |
fs->curr.reg[UNW_REG_RP].val |
= (unsigned long)&(sc->sc_ip) - context->psp; |
fs->curr.reg[UNW_REG_RP].when = -1; |
+ fs->curr.reg[UNW_REG_PFS].where = UNW_WHERE_SPREL; |
+ fs->curr.reg[UNW_REG_PFS].val |
+ = (unsigned long)&(sc->sc_cfm) - context->psp; |
+ fs ->curr.reg[UNW_REG_PFS].when = -1; |
+ |
return _URC_NO_REASON; |
} |
return _URC_END_OF_STACK; |
@@ -117,11 +123,16 @@ ia64_fallback_frame_state (struct _Unwind_Context *context, |
#define MD_HANDLE_UNWABI ia64_handle_unwabi |
+#define ABI_MARKER_OLD_LINUX_SIGTRAMP ((0 << 8) | 's') |
+#define ABI_MARKER_OLD_LINUX_INTERRUPT ((0 << 8) | 'i') |
+#define ABI_MARKER_LINUX_SIGTRAMP ((3 << 8) | 's') |
+#define ABI_MARKER_LINUX_INTERRUPT ((3 << 8) | 'i') |
+ |
static void |
ia64_handle_unwabi (struct _Unwind_Context *context, _Unwind_FrameState *fs) |
{ |
- if (fs->unwabi == ((3 << 8) | 's') |
- || fs->unwabi == ((0 << 8) | 's')) |
+ if (fs->unwabi == ABI_MARKER_LINUX_SIGTRAMP |
+ || fs->unwabi == ABI_MARKER_OLD_LINUX_SIGTRAMP) |
{ |
struct sigframe { |
char scratch[16]; |
@@ -144,7 +155,7 @@ ia64_handle_unwabi (struct _Unwind_Context *context, _Unwind_FrameState *fs) |
context->ireg[i - 2].loc = &sc->sc_gr[i]; |
} |
- context->pfs_loc = &(sc->sc_ar_pfs); |
+ context->signal_pfs_loc = &(sc->sc_ar_pfs); |
context->lc_loc = &(sc->sc_ar_lc); |
context->unat_loc = &(sc->sc_ar_unat); |
context->br_loc[0] = &(sc->sc_br[0]); |
@@ -181,9 +192,8 @@ ia64_handle_unwabi (struct _Unwind_Context *context, _Unwind_FrameState *fs) |
ia64_rse_skip_regs ((unsigned long *)(sc->sc_ar_bsp), -sof); |
} |
- /* pfs_loc already set above. Without this pfs_loc would point |
- incorrectly to sc_cfm instead of sc_ar_pfs. */ |
- fs->curr.reg[UNW_REG_PFS].where = UNW_WHERE_NONE; |
+ /* The use of br.ret to resume execution of user code is already |
+ accounted for in the unwind ABI. */ |
} |
} |
#endif /* glibc-2.3 or better */ |