extern void darwin_emit_unwind_label (FILE *, tree, int, int);
extern void darwin_emit_except_table_label (FILE *);
extern rtx darwin_make_eh_symbol_indirect (rtx, bool);
+extern bool darwin_should_restore_cfa_state (void);
extern void darwin_pragma_ignore (struct cpp_reader *);
extern void darwin_pragma_options (struct cpp_reader *);
/*stub_p=*/false));
}
+/* The unwinders in earlier Darwin versions are based on an old version
+ of libgcc_s and need current frame address stateto be reset after a
+ DW_CFA_restore_state recovers the register values. */
+
+bool
+darwin_should_restore_cfa_state (void)
+{
+ return generating_for_darwin_version <= 10;
+}
+
/* Return, and mark as used, the name of the stub for the mcount function.
Currently, this is only called by X86 code in the expansion of the
FUNCTION_PROFILER macro, when stubs are enabled. */
/* Make an EH (personality or LDSA) symbol indirect as needed. */
#define TARGET_ASM_MAKE_EH_SYMBOL_INDIRECT darwin_make_eh_symbol_indirect
+/* Some of Darwin's unwinders need current frame address state to be reset
+ after a DW_CFA_restore_state recovers the register values. */
+#undef TARGET_ASM_SHOULD_RESTORE_CFA_STATE
+#define TARGET_ASM_SHOULD_RESTORE_CFA_STATE darwin_should_restore_cfa_state
+
/* Our profiling scheme doesn't LP labels and counter words. */
#define NO_PROFILE_COUNTERS 1
True if the @code{TARGET_ASM_UNWIND_EMIT} hook should be called before the assembly for @var{insn} has been emitted, false if the hook should be called afterward.
@end deftypevr
+@deftypefn {Target Hook} bool TARGET_ASM_SHOULD_RESTORE_CFA_STATE (void)
+For DWARF-based unwind frames, two CFI instructions provide for save and restore of register state. GCC maintains the current frame address (CFA) separately from the register bank but the unwinder in libgcc preserves this state along with the registers (and this is expected by the code that writes the unwind frames). This hook allows the target to specify that the CFA data is not saved/restored along with the registers by the target unwinder so that suitable additional instructions should be emitted to restore it.
+@end deftypefn
+
@node Exception Region Output
@subsection Assembler Commands for Exception Regions
@hook TARGET_ASM_UNWIND_EMIT_BEFORE_INSN
+@hook TARGET_ASM_SHOULD_RESTORE_CFA_STATE
+
@node Exception Region Output
@subsection Assembler Commands for Exception Regions
cfi->dw_cfi_opc = DW_CFA_restore_state;
add_cfi (cfi);
+ /* If the target unwinder does not save the CFA as part of the
+ register state, we need to restore it separately. */
+ if (targetm.asm_out.should_restore_cfa_state ()
+ && (cfi = def_cfa_0 (&old_row->cfa, &ti->beg_row->cfa)))
+ add_cfi (cfi);
+
old_row = prev_ti->beg_row;
}
/* Otherwise, we'll simply change state from the previous end. */
be called afterward.",
bool, true)
+/* Return true if the target needs extra instructions to restore the current
+ frame address after a DW_CFA_restore_state opcode. */
+DEFHOOK
+(should_restore_cfa_state,
+ "For DWARF-based unwind frames, two CFI instructions provide for save and\
+ restore of register state. GCC maintains the current frame address (CFA)\
+ separately from the register bank but the unwinder in libgcc preserves this\
+ state along with the registers (and this is expected by the code that writes\
+ the unwind frames). This hook allows the target to specify that the CFA data\
+ is not saved/restored along with the registers by the target unwinder so that\
+ suitable additional instructions should be emitted to restore it.",
+ bool, (void),
+ hook_bool_void_false)
+
/* Generate an internal label.
For now this is just a wrapper for ASM_GENERATE_INTERNAL_LABEL. */
DEFHOOK_UNDOC