diff options
-rw-r--r-- | gas/ChangeLog | 13 | ||||
-rw-r--r-- | gas/dw2gencfi.c | 41 | ||||
-rw-r--r-- | gas/dw2gencfi.h | 4 | ||||
-rw-r--r-- | gas/read.c | 2 | ||||
-rw-r--r-- | gas/read.h | 1 | ||||
-rw-r--r-- | gas/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gas/testsuite/gas/cfi/cfi-label.d | 43 | ||||
-rw-r--r-- | gas/testsuite/gas/cfi/cfi-label.s | 19 | ||||
-rw-r--r-- | gas/testsuite/gas/cfi/cfi.exp | 4 |
9 files changed, 130 insertions, 2 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 2e3b2e9..78501ed 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,18 @@ 2015-01-12 Jan Beulich <jbeulich@suse.com> + * gas/dw2gencfi.c (cfi_add_label, dot_cfi_label): New. + (cfi_pseudo_table): Add "cfi_label". + (output_cfi_insn): Handle CFI_label. + (select_cie_for_fde): Als terminate CIE when encountering + CFI_label. + * dw2gencfi.h (cfi_add_label): Declare. + (struct cfi_insn_data): New member "sym_name". + (CFI_label): New. + * read.c (read_symbol_name): Drop "static". + * read.h (read_symbol_name): Declare. + +2015-01-12 Jan Beulich <jbeulich@suse.com> + * gas/config/tc-arm.c (do_neon_shl_imm): Check immediate range. (do_neon_qshl_imm): Likewise. 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; diff --git a/gas/dw2gencfi.h b/gas/dw2gencfi.h index e80b19e..6e2c50e 100644 --- a/gas/dw2gencfi.h +++ b/gas/dw2gencfi.h @@ -37,6 +37,7 @@ extern void cfi_new_fde (struct symbol *); extern void cfi_end_fde (struct symbol *); extern void cfi_set_return_column (unsigned); extern void cfi_add_advance_loc (struct symbol *); +extern void cfi_add_label (const char *); extern void cfi_add_CFA_offset (unsigned, offsetT); extern void cfi_add_CFA_def_cfa (unsigned, offsetT); @@ -94,6 +95,8 @@ struct cfi_insn_data unsigned reg, encoding; expressionS exp; } ea; + + const char *sym_name; } u; }; @@ -128,5 +131,6 @@ extern struct fde_entry *all_fde_data; #define CFI_escape 0x103 #define CFI_signal_frame 0x104 #define CFI_val_encoded_addr 0x105 +#define CFI_label 0x106 #endif /* DW2GENCFI_H */ @@ -1600,7 +1600,7 @@ s_altmacro (int on) If a symbol name could not be read, the routine issues an error messages, skips to the end of the line and returns NULL. */ -static char * +char * read_symbol_name (void) { char * name; @@ -127,6 +127,7 @@ extern void pseudo_set (symbolS * symbolP); extern void read_a_source_file (char *name); extern void read_begin (void); extern void read_print_statistics (FILE *); +extern char *read_symbol_name (void); extern int sizeof_leb128 (valueT, int sign); extern void stabs_generate_asm_file (void); extern void stabs_generate_asm_lineno (void); diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index ef359a1..54d9c6e 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2015-01-12 Jan Beulich <jbeulich@suse.com> + gas/cfi/cfi-label.d, gas/cfi/cfi-label.s: New. + gas/cfi/cfi.exp: Run new tests. + +2015-01-12 Jan Beulich <jbeulich@suse.com> + * gas/arm/neon-addressing-bad.s: Add test for invalid VSHL, VQSHL, and VQSHLU immediates. * gas/arm/neon-addressing-bad.l: Update accordingly. diff --git a/gas/testsuite/gas/cfi/cfi-label.d b/gas/testsuite/gas/cfi/cfi-label.d new file mode 100644 index 0000000..e96c795 --- /dev/null +++ b/gas/testsuite/gas/cfi/cfi-label.d @@ -0,0 +1,43 @@ +#objdump: -tWf +#name: .cfi_label directive + +.*\.o: file format elf.* + +SYMBOL TABLE: +0*00 l d \.text 0*00 \.text +0*00 l d \.data 0*00 \.data +0*00 l d \.bss 0*00 \.bss +0*00 l F \.text 0*04 cfilabel +0*2f l \.eh_frame 0*00 cfi2 +0*00 l d \.eh_frame 0*00 \.eh_frame +0*2b g \.eh_frame 0*00 cfi1 + + +Contents of the .eh_frame section: + +0*00 0*14 0*00 CIE + Version: 1 + Augmentation: "zR" + Code alignment factor: 1 + Data alignment factor: -[48] + Return address column: (8|16) + Augmentation data: 1b + + DW_CFA_def_cfa: r.* \([er]sp\) ofs [48] + DW_CFA_offset: r.* \([er]ip\) at cfa-[48] + DW_CFA_nop + DW_CFA_nop + +0*18 0*1[8c] 0*1c FDE cie=0*00 pc=0*00..0*04 + DW_CFA_remember_state + DW_CFA_advance_loc: 1 to 0*01 + DW_CFA_nop + DW_CFA_nop + DW_CFA_nop + DW_CFA_advance_loc: 1 to 0*02 + DW_CFA_nop + DW_CFA_nop + DW_CFA_advance_loc: 1 to 0*03 + DW_CFA_nop + DW_CFA_restore_state +#pass diff --git a/gas/testsuite/gas/cfi/cfi-label.s b/gas/testsuite/gas/cfi/cfi-label.s new file mode 100644 index 0000000..f0297ab --- /dev/null +++ b/gas/testsuite/gas/cfi/cfi-label.s @@ -0,0 +1,19 @@ + .text +cfilabel: + .cfi_startproc + .cfi_remember_state + nop + .globl cfi1 + .cfi_label cfi1 + .cfi_escape 0, 0, 0 + nop + .cfi_label cfi2 + .cfi_escape 0, 0 + nop + .cfi_label .Lcfi3 + .cfi_escape 0 + .cfi_restore_state + ret + .cfi_endproc + .type cfilabel, STT_FUNC + .size cfilabel, . - cfilabel diff --git a/gas/testsuite/gas/cfi/cfi.exp b/gas/testsuite/gas/cfi/cfi.exp index 33ae13e..be84941 100644 --- a/gas/testsuite/gas/cfi/cfi.exp +++ b/gas/testsuite/gas/cfi/cfi.exp @@ -51,6 +51,10 @@ if { [istarget "i*86-*-*"] || [istarget "x86_64-*-*"] } then { set ASFLAGS "$old_ASFLAGS" } + if { [is_elf_format] } then { + run_dump_test "cfi-label" + } + if { [is_pecoff_format] } then { run_dump_test "reloc-pe-i386" } |