diff options
author | Richard Henderson <rth@redhat.com> | 2003-06-11 23:16:58 +0000 |
---|---|---|
committer | Richard Henderson <rth@redhat.com> | 2003-06-11 23:16:58 +0000 |
commit | cdfbf930b96d5ae51342f34dd180323a8011f8ef (patch) | |
tree | 7b44edfdd335470b947085026b832e2f960460ac /gas/dw2gencfi.c | |
parent | 2d8f7dc8d5dc22ec3f6527d2a7636ba8f3f57d34 (diff) | |
download | gdb-cdfbf930b96d5ae51342f34dd180323a8011f8ef.zip gdb-cdfbf930b96d5ae51342f34dd180323a8011f8ef.tar.gz gdb-cdfbf930b96d5ae51342f34dd180323a8011f8ef.tar.bz2 |
* 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.
Diffstat (limited to 'gas/dw2gencfi.c')
-rw-r--r-- | gas/dw2gencfi.c | 65 |
1 files changed, 53 insertions, 12 deletions
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 (); } |