# endif
#endif
+#ifndef EH_FRAME_ALIGNMENT
+# ifdef BFD_ASSEMBLER
+# define EH_FRAME_ALIGNMENT (bfd_get_arch_size (stdoutput) == 64 ? 3 : 2)
+# else
+# define EH_FRAME_ALIGNMENT 2
+# endif
+#endif
+
#ifndef tc_cfi_frame_initial_instructions
# define tc_cfi_frame_initial_instructions() ((void)0)
#endif
{ "cfi_same_value", dot_cfi, DW_CFA_same_value },
{ "cfi_remember_state", dot_cfi, DW_CFA_remember_state },
{ "cfi_restore_state", dot_cfi, DW_CFA_restore_state },
+ { "cfi_window_save", dot_cfi, DW_CFA_GNU_window_save },
{ "cfi_escape", dot_cfi_escape, 0 },
{ NULL, NULL, 0 }
};
cfi_add_CFA_restore_state ();
break;
+ case DW_CFA_GNU_window_save:
+ cfi_add_CFA_insn (DW_CFA_GNU_window_save);
+ break;
+
default:
abort ();
}
out_one (insn->insn);
break;
+ case DW_CFA_GNU_window_save:
+ out_one (DW_CFA_GNU_window_save);
+ break;
+
case CFI_escape:
{
struct cfi_escape_data *e;
out_one (0);
out_uleb128 (DWARF2_LINE_MIN_INSN_LENGTH); /* Code alignment */
out_sleb128 (DWARF2_CIE_DATA_ALIGNMENT); /* Data alignment */
- out_one (cie->return_column); /* Return column */
+ if (DW_CIE_VERSION == 1) /* Return column. */
+ out_one (cie->return_column);
+ else
+ out_uleb128 (cie->return_column);
out_uleb128 (1); /* Augmentation size */
+#if defined DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
out_one (DW_EH_PE_pcrel | DW_EH_PE_sdata4);
+#else
+ out_one (DW_EH_PE_sdata4);
+#endif
if (cie->first)
for (i = cie->first; i != cie->last; i = i->next)
static void
output_fde (struct fde_entry *fde, struct cie_entry *cie,
- struct cfi_insn_data *first)
+ struct cfi_insn_data *first, int align)
{
symbolS *after_size_address, *end_address;
expressionS exp;
exp.X_add_symbol = after_size_address;
exp.X_op_symbol = cie->start_address;
emit_expr (&exp, 4); /* CIE offset */
-
+
+#ifdef DIFF_EXPR_OK
exp.X_add_symbol = fde->start_address;
exp.X_op_symbol = symbol_temp_new_now ();
emit_expr (&exp, 4); /* Code offset */
+#else
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = fde->start_address;
+ exp.X_op_symbol = NULL;
+#ifdef tc_cfi_emit_pcrel_expr
+ tc_cfi_emit_pcrel_expr (&exp, 4); /* Code offset */
+#else
+ emit_expr (&exp, 4); /* Code offset */
+#endif
+ exp.X_op = O_subtract;
+#endif
exp.X_add_symbol = fde->end_address;
exp.X_op_symbol = fde->start_address; /* Code length */
for (; first; first = first->next)
output_cfi_insn (first);
- frag_align (2, 0, 0);
+ frag_align (align, 0, 0);
symbol_set_value_now (end_address);
}
SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_READONLY);
#endif
subseg_set (cfi_seg, 0);
- record_alignment (cfi_seg, 2);
+ record_alignment (cfi_seg, EH_FRAME_ALIGNMENT);
/* Make sure check_eh_frame doesn't do anything with our output. */
save_flag_traditional_format = flag_traditional_format;
struct cie_entry *cie;
cie = select_cie_for_fde (fde, &first);
- output_fde (fde, cie, first);
+ output_fde (fde, cie, first, fde->next == NULL ? EH_FRAME_ALIGNMENT : 2);
}
flag_traditional_format = save_flag_traditional_format;