aboutsummaryrefslogtreecommitdiff
path: root/gas/dw2gencfi.c
diff options
context:
space:
mode:
Diffstat (limited to 'gas/dw2gencfi.c')
-rw-r--r--gas/dw2gencfi.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/gas/dw2gencfi.c b/gas/dw2gencfi.c
index 939c41a..6a80d0b 100644
--- a/gas/dw2gencfi.c
+++ b/gas/dw2gencfi.c
@@ -440,6 +440,19 @@ cfi_add_advance_loc (symbolS *label)
frchain_now->frch_cfi_data->last_address = label;
}
+/* Add a CFI insn to label the current position in the CFI segment. */
+
+void
+cfi_add_label (const char *name)
+{
+ unsigned int len = strlen (name) + 1;
+ struct cfi_insn_data *insn = alloc_cfi_insn_data ();
+
+ insn->insn = CFI_label;
+ obstack_grow (&notes, name, len);
+ insn->u.sym_name = (char *) obstack_finish (&notes);
+}
+
/* Add a DW_CFA_offset record to the CFI data. */
void
@@ -550,6 +563,7 @@ static void dot_cfi_endproc (int);
static void dot_cfi_personality (int);
static void dot_cfi_lsda (int);
static void dot_cfi_val_encoded_addr (int);
+static void dot_cfi_label (int);
const pseudo_typeS cfi_pseudo_table[] =
{
@@ -575,6 +589,7 @@ const pseudo_typeS cfi_pseudo_table[] =
{ "cfi_personality", dot_cfi_personality, 0 },
{ "cfi_lsda", dot_cfi_lsda, 0 },
{ "cfi_val_encoded_addr", dot_cfi_val_encoded_addr, 0 },
+ { "cfi_label", dot_cfi_label, 0 },
{ NULL, NULL, 0 }
};
@@ -1016,6 +1031,25 @@ dot_cfi_val_encoded_addr (int ignored ATTRIBUTE_UNUSED)
demand_empty_rest_of_line ();
}
+static void
+dot_cfi_label (int ignored ATTRIBUTE_UNUSED)
+{
+ char *name = read_symbol_name ();
+
+ if (name == NULL)
+ return;
+
+ /* If the last address was not at the current PC, advance to current. */
+ if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
+ || S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
+ != frag_now_fix ())
+ cfi_add_advance_loc (symbol_temp_new_now ());
+
+ cfi_add_label (name);
+
+ demand_empty_rest_of_line ();
+}
+
/* By default emit .eh_frame only, not .debug_frame. */
#define CFI_EMIT_eh_frame (1 << 0)
#define CFI_EMIT_debug_frame (1 << 1)
@@ -1386,6 +1420,10 @@ output_cfi_insn (struct cfi_insn_data *insn)
}
break;
+ case CFI_label:
+ colon (insn->u.sym_name);
+ break;
+
default:
abort ();
}
@@ -1761,7 +1799,8 @@ select_cie_for_fde (struct fde_entry *fde, bfd_boolean eh_frame,
if (i->insn == DW_CFA_advance_loc
|| i->insn == DW_CFA_remember_state
|| i->insn == CFI_escape
- || i->insn == CFI_val_encoded_addr)
+ || i->insn == CFI_val_encoded_addr
+ || i->insn == CFI_label)
break;
cie->last = i;