| 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 */
|
|
|