* 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.
This commit is contained in:
Richard Henderson 2003-06-11 23:16:58 +00:00
parent 2d8f7dc8d5
commit cdfbf930b9
10 changed files with 110 additions and 22 deletions

View file

@ -1,3 +1,16 @@
2003-06-11 Richard Henderson <rth@redhat.com>
* 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 <seufer@csv.ica.uni-stuttgart.de> 2003-06-11 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
* config/tc-mips.c (s_cpsetup): Use mips_frame_reg instead of SP. * config/tc-mips.c (s_cpsetup): Use mips_frame_reg instead of SP.

View file

@ -3691,13 +3691,7 @@ Some machine configurations provide additional directives.
* Byte:: @code{.byte @var{expressions}} * Byte:: @code{.byte @var{expressions}}
* Comm:: @code{.comm @var{symbol} , @var{length} } * Comm:: @code{.comm @var{symbol} , @var{length} }
* CFI directives:: @code{.cfi_startproc} * CFI directives:: @code{.cfi_startproc}, @code{.cfi_endproc}, etc.
@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}}
* Data:: @code{.data @var{subsection}} * Data:: @code{.data @var{subsection}}
@ifset COFF @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 This is often easier to use, because the number will match the
code it's annotating. code it's annotating.
@node Comm @section @code{.cfi_escape} @var{expression}[, @dots{}]
@section @code{.comm @var{symbol} , @var{length} } 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 @code{comm} directive
@cindex symbol, common @cindex symbol, common

View file

@ -68,6 +68,11 @@ struct cfi_insn_data
symbolS *lab1; symbolS *lab1;
symbolS *lab2; symbolS *lab2;
} ll; } ll;
struct cfi_escape_data {
struct cfi_escape_data *next;
expressionS exp;
} *esc;
} u; } 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. */ /* Parse CFI assembler directives. */
static void dot_cfi (int); static void dot_cfi (int);
static void dot_cfi_escape (int);
static void dot_cfi_startproc (int); static void dot_cfi_startproc (int);
static void dot_cfi_endproc (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_adjust_cfa_offset 0x100
#define CFI_return_column 0x101 #define CFI_return_column 0x101
#define CFI_rel_offset 0x102 #define CFI_rel_offset 0x102
#define CFI_escape 0x103
const pseudo_typeS cfi_pseudo_table[] = 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_same_value", dot_cfi, DW_CFA_same_value },
{ "cfi_remember_state", dot_cfi, DW_CFA_remember_state }, { "cfi_remember_state", dot_cfi, DW_CFA_remember_state },
{ "cfi_restore_state", dot_cfi, DW_CFA_restore_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 } { NULL, NULL, 0 }
}; };
@ -520,10 +521,6 @@ dot_cfi (int arg)
cfi_add_CFA_restore_state (); cfi_add_CFA_restore_state ();
break; break;
case DW_CFA_nop:
cfi_add_CFA_nop ();
break;
default: default:
abort (); abort ();
} }
@ -531,6 +528,39 @@ dot_cfi (int arg)
demand_empty_rest_of_line (); demand_empty_rest_of_line ();
} }
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 static void
dot_cfi_startproc (int ignored ATTRIBUTE_UNUSED) dot_cfi_startproc (int ignored ATTRIBUTE_UNUSED)
{ {
@ -757,10 +787,17 @@ output_cfi_insn (struct cfi_insn_data *insn)
case DW_CFA_remember_state: case DW_CFA_remember_state:
case DW_CFA_restore_state: case DW_CFA_restore_state:
case DW_CFA_nop:
out_one (insn->insn); out_one (insn->insn);
break; 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: default:
abort (); abort ();
} }
@ -892,6 +929,10 @@ select_cie_for_fde (struct fde_entry *fde, struct cfi_insn_data **pfirst)
goto fail; goto fail;
break; break;
case CFI_escape:
/* Don't bother matching these for now. */
goto fail;
default: default:
abort (); abort ();
} }

View file

@ -48,6 +48,5 @@ extern void cfi_add_CFA_undefined (unsigned);
extern void cfi_add_CFA_same_value (unsigned); extern void cfi_add_CFA_same_value (unsigned);
extern void cfi_add_CFA_remember_state (void); extern void cfi_add_CFA_remember_state (void);
extern void cfi_add_CFA_restore_state (void); extern void cfi_add_CFA_restore_state (void);
extern void cfi_add_CFA_nop (void);
#endif /* DW2GENCFI_H */ #endif /* DW2GENCFI_H */

View file

@ -3346,6 +3346,13 @@ parse_repeat_cons PARAMS ((expressionS *exp, unsigned int nbytes));
#endif #endif
#endif #endif
void
do_parse_cons_expression (expressionS *exp, int nbytes)
{
TC_PARSE_CONS_EXPRESSION (exp, nbytes);
}
/* Worker to do .byte etc statements. /* Worker to do .byte etc statements.
Clobbers input_line_pointer and checks end-of-line. */ Clobbers input_line_pointer and checks end-of-line. */

View file

@ -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 stabs_generate_asm_endfunc PARAMS ((const char *, const char *));
extern void do_repeat PARAMS((int,const char *,const char *)); extern void do_repeat PARAMS((int,const char *,const char *));
extern void end_repeat PARAMS((int)); extern void end_repeat PARAMS((int));
extern void do_parse_cons_expression PARAMS ((expressionS *, int));
extern void generate_lineno_debug PARAMS ((void)); extern void generate_lineno_debug PARAMS ((void));

View file

@ -1,3 +1,8 @@
2003-06-11 Richard Henderson <rth@redhat.com>
* gas/cfi/cfi-common-3.[ds]: New.
* gas/cfi/cfi.exp: Run it.
2003-06-11 Alan Modra <amodra@bigpond.net.au> 2003-06-11 Alan Modra <amodra@bigpond.net.au>
* gas/macros/app1.d: Ignore section symbols. * gas/macros/app1.d: Ignore section symbols.

View file

@ -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

View file

@ -0,0 +1,4 @@
.cfi_startproc simple
.long 0
.cfi_escape 10, 11
.cfi_endproc

View file

@ -34,3 +34,4 @@ if [istarget "x86_64-*"] then {
run_list_test "cfi-diag-1" "" run_list_test "cfi-diag-1" ""
run_dump_test "cfi-common-1" run_dump_test "cfi-common-1"
run_dump_test "cfi-common-2" run_dump_test "cfi-common-2"
run_dump_test "cfi-common-3"