From cdfbf930b96d5ae51342f34dd180323a8011f8ef Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 11 Jun 2003 23:16:58 +0000 Subject: * dw2gencfi.c (struct cfi_escape_data): New. (cfi_add_CFA_nop): Remove. (CFI_escape, dot_cfi_escape): New. (dot_cfi): Remove nop. (cfi_pseudo_table): Remove nop; add escape. (output_cfi_insn): Likewise. (select_cie_for_fde): Stop on escape. * dw2gencfi.h (cfi_add_CFA_nop): Remove. * read.c, read.h (do_parse_cons_expression): New. * doc/as.texinfo (.cfi_escape): New. * gas/cfi/cfi-common-3.[ds]: New. * gas/cfi/cfi.exp: Run it. --- gas/ChangeLog | 13 ++++++++ gas/doc/as.texinfo | 14 +++----- gas/dw2gencfi.c | 65 +++++++++++++++++++++++++++++------- gas/dw2gencfi.h | 1 - gas/read.c | 7 ++++ gas/read.h | 1 + gas/testsuite/ChangeLog | 5 +++ gas/testsuite/gas/cfi/cfi-common-3.d | 21 ++++++++++++ gas/testsuite/gas/cfi/cfi-common-3.s | 4 +++ gas/testsuite/gas/cfi/cfi.exp | 1 + 10 files changed, 110 insertions(+), 22 deletions(-) create mode 100644 gas/testsuite/gas/cfi/cfi-common-3.d create mode 100644 gas/testsuite/gas/cfi/cfi-common-3.s diff --git a/gas/ChangeLog b/gas/ChangeLog index 38430a3..9df96ef 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,16 @@ +2003-06-11 Richard Henderson + + * dw2gencfi.c (struct cfi_escape_data): New. + (cfi_add_CFA_nop): Remove. + (CFI_escape, dot_cfi_escape): New. + (dot_cfi): Remove nop. + (cfi_pseudo_table): Remove nop; add escape. + (output_cfi_insn): Likewise. + (select_cie_for_fde): Stop on escape. + * dw2gencfi.h (cfi_add_CFA_nop): Remove. + * read.c, read.h (do_parse_cons_expression): New. + * doc/as.texinfo (.cfi_escape): New. + 2003-06-11 Thiemo Seufer * config/tc-mips.c (s_cpsetup): Use mips_frame_reg instead of SP. diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo index d37198a..3e608d4 100644 --- a/gas/doc/as.texinfo +++ b/gas/doc/as.texinfo @@ -3691,13 +3691,7 @@ Some machine configurations provide additional directives. * Byte:: @code{.byte @var{expressions}} * Comm:: @code{.comm @var{symbol} , @var{length} } -* CFI directives:: @code{.cfi_startproc} - @code{.cfi_endproc} - @code{.cfi_def_cfa @var{register}, @var{offset}} - @code{.cfi_def_cfa_register @var{register}} - @code{.cfi_def_cfa_offset @var{offset}} - @code{.cfi_adjust_cfa_offset @var{offset}} - @code{.cfi_offset @var{register}, @var{offset}} +* CFI directives:: @code{.cfi_startproc}, @code{.cfi_endproc}, etc. * Data:: @code{.data @var{subsection}} @ifset COFF @@ -4020,8 +4014,10 @@ using the known displacement of the CFA register from the CFA. This is often easier to use, because the number will match the code it's annotating. -@node Comm -@section @code{.comm @var{symbol} , @var{length} } +@section @code{.cfi_escape} @var{expression}[, @dots{}] +Allows the user to add arbitrary bytes to the unwind info. One +might use this to add OS-specific CFI opcodes, or generic CFI +opcodes that GAS does not yet support. @cindex @code{comm} directive @cindex symbol, common diff --git a/gas/dw2gencfi.c b/gas/dw2gencfi.c index ccfb110..0e118e1 100644 --- a/gas/dw2gencfi.c +++ b/gas/dw2gencfi.c @@ -68,6 +68,11 @@ struct cfi_insn_data symbolS *lab1; symbolS *lab2; } ll; + + struct cfi_escape_data { + struct cfi_escape_data *next; + expressionS exp; + } *esc; } u; }; @@ -330,16 +335,11 @@ cfi_add_CFA_restore_state (void) } } -void -cfi_add_CFA_nop (void) -{ - cfi_add_CFA_insn (DW_CFA_nop); -} - /* Parse CFI assembler directives. */ static void dot_cfi (int); +static void dot_cfi_escape (int); static void dot_cfi_startproc (int); static void dot_cfi_endproc (int); @@ -347,6 +347,7 @@ static void dot_cfi_endproc (int); #define CFI_adjust_cfa_offset 0x100 #define CFI_return_column 0x101 #define CFI_rel_offset 0x102 +#define CFI_escape 0x103 const pseudo_typeS cfi_pseudo_table[] = { @@ -365,7 +366,7 @@ const pseudo_typeS cfi_pseudo_table[] = { "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_nop", dot_cfi, DW_CFA_nop }, + { "cfi_escape", dot_cfi_escape, 0 }, { NULL, NULL, 0 } }; @@ -520,10 +521,6 @@ dot_cfi (int arg) cfi_add_CFA_restore_state (); break; - case DW_CFA_nop: - cfi_add_CFA_nop (); - break; - default: abort (); } @@ -532,6 +529,39 @@ dot_cfi (int arg) } static void +dot_cfi_escape (int ignored ATTRIBUTE_UNUSED) +{ + struct cfi_escape_data *head, **tail, *e; + struct cfi_insn_data *insn; + + if (!cur_fde_data) + { + as_bad (_("CFI instruction used without previous .cfi_startproc")); + return; + } + + /* If the last address was not at the current PC, advance to current. */ + if (symbol_get_frag (last_address) != frag_now + || S_GET_VALUE (last_address) != frag_now_fix ()) + cfi_add_advance_loc (symbol_temp_new_now ()); + + tail = &head; + do + { + e = xmalloc (sizeof (*e)); + do_parse_cons_expression (&e->exp, 1); + *tail = e; + tail = &e->next; + } + while (*input_line_pointer++ == ','); + *tail = NULL; + + insn = alloc_cfi_insn_data (); + insn->insn = CFI_escape; + insn->u.esc = head; +} + +static void dot_cfi_startproc (int ignored ATTRIBUTE_UNUSED) { int simple = 0; @@ -757,10 +787,17 @@ output_cfi_insn (struct cfi_insn_data *insn) case DW_CFA_remember_state: case DW_CFA_restore_state: - case DW_CFA_nop: out_one (insn->insn); break; + case CFI_escape: + { + struct cfi_escape_data *e; + for (e = insn->u.esc; e ; e = e->next) + emit_expr (&e->exp, 1); + break; + } + default: abort (); } @@ -892,6 +929,10 @@ select_cie_for_fde (struct fde_entry *fde, struct cfi_insn_data **pfirst) goto fail; break; + case CFI_escape: + /* Don't bother matching these for now. */ + goto fail; + default: abort (); } diff --git a/gas/dw2gencfi.h b/gas/dw2gencfi.h index 0361f97..75b6ec2 100644 --- a/gas/dw2gencfi.h +++ b/gas/dw2gencfi.h @@ -48,6 +48,5 @@ extern void cfi_add_CFA_undefined (unsigned); extern void cfi_add_CFA_same_value (unsigned); extern void cfi_add_CFA_remember_state (void); extern void cfi_add_CFA_restore_state (void); -extern void cfi_add_CFA_nop (void); #endif /* DW2GENCFI_H */ diff --git a/gas/read.c b/gas/read.c index b7d9190..061dfd4 100644 --- a/gas/read.c +++ b/gas/read.c @@ -3346,6 +3346,13 @@ parse_repeat_cons PARAMS ((expressionS *exp, unsigned int nbytes)); #endif #endif +void +do_parse_cons_expression (expressionS *exp, int nbytes) +{ + TC_PARSE_CONS_EXPRESSION (exp, nbytes); +} + + /* Worker to do .byte etc statements. Clobbers input_line_pointer and checks end-of-line. */ diff --git a/gas/read.h b/gas/read.h index ba431af..5a33c70 100644 --- a/gas/read.h +++ b/gas/read.h @@ -133,6 +133,7 @@ extern void stabs_generate_asm_func PARAMS ((const char *, const char *)); extern void stabs_generate_asm_endfunc PARAMS ((const char *, const char *)); extern void do_repeat PARAMS((int,const char *,const char *)); extern void end_repeat PARAMS((int)); +extern void do_parse_cons_expression PARAMS ((expressionS *, int)); extern void generate_lineno_debug PARAMS ((void)); diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index d114c0f..1ef04ab 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2003-06-11 Richard Henderson + + * gas/cfi/cfi-common-3.[ds]: New. + * gas/cfi/cfi.exp: Run it. + 2003-06-11 Alan Modra * gas/macros/app1.d: Ignore section symbols. diff --git a/gas/testsuite/gas/cfi/cfi-common-3.d b/gas/testsuite/gas/cfi/cfi-common-3.d new file mode 100644 index 0000000..f82e02e --- /dev/null +++ b/gas/testsuite/gas/cfi/cfi-common-3.d @@ -0,0 +1,21 @@ +#readelf: -wf +#name: CFI common 2 +The section .eh_frame contains: + +00000000 00000010 00000000 CIE + Version: 1 + Augmentation: "zR" + Code alignment factor: .* + Data alignment factor: .* + Return address column: .* + Augmentation data: 1b + + DW_CFA_nop + DW_CFA_nop + DW_CFA_nop + +00000014 00000010 00000018 FDE cie=00000000 pc=.* + DW_CFA_advance_loc: 4 to .* + DW_CFA_remember_state + DW_CFA_restore_state + diff --git a/gas/testsuite/gas/cfi/cfi-common-3.s b/gas/testsuite/gas/cfi/cfi-common-3.s new file mode 100644 index 0000000..d1282d1 --- /dev/null +++ b/gas/testsuite/gas/cfi/cfi-common-3.s @@ -0,0 +1,4 @@ + .cfi_startproc simple + .long 0 + .cfi_escape 10, 11 + .cfi_endproc diff --git a/gas/testsuite/gas/cfi/cfi.exp b/gas/testsuite/gas/cfi/cfi.exp index 968d3b1..6592bbe 100644 --- a/gas/testsuite/gas/cfi/cfi.exp +++ b/gas/testsuite/gas/cfi/cfi.exp @@ -34,3 +34,4 @@ if [istarget "x86_64-*"] then { run_list_test "cfi-diag-1" "" run_dump_test "cfi-common-1" run_dump_test "cfi-common-2" +run_dump_test "cfi-common-3" -- cgit v1.1