aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog13
-rw-r--r--gas/dw2gencfi.c41
-rw-r--r--gas/dw2gencfi.h4
-rw-r--r--gas/read.c2
-rw-r--r--gas/read.h1
-rw-r--r--gas/testsuite/ChangeLog5
-rw-r--r--gas/testsuite/gas/cfi/cfi-label.d43
-rw-r--r--gas/testsuite/gas/cfi/cfi-label.s19
-rw-r--r--gas/testsuite/gas/cfi/cfi.exp4
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 (&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;
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 */
diff --git a/gas/read.c b/gas/read.c
index 7dfc20a..b2d5027 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -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;
diff --git a/gas/read.h b/gas/read.h
index 32d3767..d7ac6ce 100644
--- a/gas/read.h
+++ b/gas/read.h
@@ -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"
}