diff options
Diffstat (limited to 'gas/dw2gencfi.c')
-rw-r--r-- | gas/dw2gencfi.c | 41 |
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 (¬es, name, len); + insn->u.sym_name = (char *) obstack_finish (¬es); +} + /* 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; |