This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix DW_AT_frame_base with -fdwarf2-cfi-asm
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Henderson <rth at redhat dot com>, Paul Pluzhnikov <ppluzhnikov at google dot com>
- Cc: gcc-patches at gcc dot gnu dot org, jan dot kratochvil at redhat dot com, Roland McGrath <roland at redhat dot com>
- Date: Mon, 1 Jun 2009 12:50:20 +0200
- Subject: [PATCH] Fix DW_AT_frame_base with -fdwarf2-cfi-asm
- References: <m3ab4sbmrh.fsf@google.com> <8ac60eac0906010024w1b2c49e8m700b43811f69f573@mail.gmail.com> <20090601094005.GC18874@tyan-ft48-01.lab.bos.redhat.com>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Mon, Jun 01, 2009 at 11:40:05AM +0200, Jakub Jelinek wrote:
> This seems not to be a bug in this weekend's patch, but a general
> problem with -fdwarf2-cfi-asm (so something that needs to be fixed there
> too). convert_cfa_to_fb_loc_list can't work properly with .cfi_* directives
> in their current shape. The only time convert_cfa_to_fb_loc_list actually
> appends something to the location lists for frame base is when
> case DW_CFA_set_loc:
> case DW_CFA_advance_loc1:
> case DW_CFA_advance_loc2:
> case DW_CFA_advance_loc4:
> but those aren't ever added when using .cfi_* directives (and what's worse,
> we don't emit labels at those instructions).
>
> I'll try to fix this, but could the dwarf3 consumers in the mean time
> implement DW_OP_call_frame_cfa, pretty please, preferrably yesterday?
Here is the patch I'm bootstrapping/regtesting:
2009-06-01 Jakub Jelinek <jakub@redhat.com>
* dwarf2out.c (dwarf2out_cfi_label): Add FORCE argument, if true,
force output of the label even for dwarf2out_do_cfi_asm.
(add_fde_cfi): If -g2 and above and cfi might change CFA,
force creation of CFI label and chain DW_CFA_set_loc jumping to it
for convert_cfa_to_fb_loc_list. Adjust other dwarf2out_cfi_label
caller.
(dwarf2out_stack_adjust, dwarf2out_frame_debug,
dwarf2out_begin_epilogue, dwarf2out_frame_debug_restore_state): Adjust
dwarf2out_cfi_label callers.
* tree.h (dwarf2out_cfi_label): Adjust prototype.
* config/arm/arm.c (thumb_pushpop, thumb1_output_function_prologue):
Adjust dwarf2out_cfi_label callers.
* config/vax/vax.c (vax_output_function_prologue): Likewise.
--- gcc/dwarf2out.c.jj 2009-05-30 10:13:04.000000000 +0200
+++ gcc/dwarf2out.c 2009-06-01 12:32:55.000000000 +0200
@@ -693,14 +693,15 @@ add_cfi (dw_cfi_ref *list_head, dw_cfi_r
*p = cfi;
}
-/* Generate a new label for the CFI info to refer to. */
+/* Generate a new label for the CFI info to refer to. FORCE is true
+ if a label needs to be output even when using .cfi_* directives. */
char *
-dwarf2out_cfi_label (void)
+dwarf2out_cfi_label (bool force)
{
static char label[20];
- if (dwarf2out_do_cfi_asm ())
+ if (!force && dwarf2out_do_cfi_asm ())
{
/* In this case, we will be emitting the asm directive instead of
the label, so just return a placeholder to keep the rest of the
@@ -728,11 +729,59 @@ add_fde_cfi (const char *label, dw_cfi_r
{
if (label)
{
- output_cfi_directive (cfi);
+ dw_fde_ref fde = current_fde ();
+
+ gcc_assert (fde != NULL);
/* We still have to add the cfi to the list so that
- lookup_cfa works later on. */
- list_head = ¤t_fde ()->dw_fde_cfi;
+ lookup_cfa works later on. When -g2 and above we
+ even need to force emitting of CFI labels and
+ add to list a DW_CFA_set_loc for convert_cfa_to_fb_loc_list
+ purposes. */
+ switch (cfi->dw_cfi_opc)
+ {
+ case DW_CFA_def_cfa_offset:
+ case DW_CFA_def_cfa_offset_sf:
+ case DW_CFA_def_cfa_register:
+ case DW_CFA_def_cfa:
+ case DW_CFA_def_cfa_sf:
+ case DW_CFA_def_cfa_expression:
+ case DW_CFA_restore_state:
+ if (write_symbols != DWARF2_DEBUG
+ && write_symbols != VMS_AND_DWARF2_DEBUG)
+ break;
+ if (debug_info_level <= DINFO_LEVEL_TERSE)
+ break;
+
+ if (*label == 0 || strcmp (label, "<do not output>") == 0)
+ label = dwarf2out_cfi_label (true);
+
+ if (fde->dw_fde_current_label == NULL
+ || strcmp (label, fde->dw_fde_current_label) != 0)
+ {
+ dw_cfi_ref xcfi;
+
+ label = xstrdup (label);
+
+ /* Set the location counter to the new label. */
+ xcfi = new_cfi ();
+ /* It doesn't metter whether DW_CFA_set_loc
+ or DW_CFA_advance_loc4 is added here, those aren't
+ emitted into assembly, only looked up by
+ convert_cfa_to_fb_loc_list. */
+ xcfi->dw_cfi_opc = DW_CFA_set_loc;
+ xcfi->dw_cfi_oprnd1.dw_cfi_addr = label;
+ add_cfi (&fde->dw_fde_cfi, xcfi);
+ fde->dw_fde_current_label = label;
+ }
+ break;
+ default:
+ break;
+ }
+
+ output_cfi_directive (cfi);
+
+ list_head = &fde->dw_fde_cfi;
}
/* ??? If this is a CFI for the CIE, we don't emit. This
assumes that the standard CIE contents that the assembler
@@ -747,7 +796,7 @@ add_fde_cfi (const char *label, dw_cfi_r
gcc_assert (fde != NULL);
if (*label == 0)
- label = dwarf2out_cfi_label ();
+ label = dwarf2out_cfi_label (false);
if (fde->dw_fde_current_label == NULL
|| strcmp (label, fde->dw_fde_current_label) != 0)
@@ -1477,7 +1526,7 @@ dwarf2out_stack_adjust (rtx insn, bool a
if (offset == 0)
return;
- label = dwarf2out_cfi_label ();
+ label = dwarf2out_cfi_label (false);
dwarf2out_args_size_adjust (offset, label);
}
@@ -2580,7 +2629,7 @@ dwarf2out_frame_debug (rtx insn, bool af
return;
}
- label = dwarf2out_cfi_label ();
+ label = dwarf2out_cfi_label (false);
for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
switch (REG_NOTE_KIND (note))
@@ -2709,7 +2758,7 @@ dwarf2out_begin_epilogue (rtx insn)
/* Emit the state save. */
cfi = new_cfi ();
cfi->dw_cfi_opc = DW_CFA_remember_state;
- add_fde_cfi (dwarf2out_cfi_label (), cfi);
+ add_fde_cfi (dwarf2out_cfi_label (false), cfi);
/* And emulate the state save. */
gcc_assert (!cfa_remember.in_use);
@@ -2723,7 +2772,7 @@ void
dwarf2out_frame_debug_restore_state (void)
{
dw_cfi_ref cfi = new_cfi ();
- const char *label = dwarf2out_cfi_label ();
+ const char *label = dwarf2out_cfi_label (false);
cfi->dw_cfi_opc = DW_CFA_restore_state;
add_fde_cfi (label, cfi);
--- gcc/tree.h.jj 2009-05-25 08:30:35.000000000 +0200
+++ gcc/tree.h 2009-06-01 12:06:21.000000000 +0200
@@ -5020,7 +5020,7 @@ extern tree tree_overlaps_hard_reg_set (
/* Generate a new label for the CFI info to refer to. */
-extern char *dwarf2out_cfi_label (void);
+extern char *dwarf2out_cfi_label (bool);
/* Entry point to update the canonical frame address (CFA). */
--- gcc/config/arm/arm.c.jj 2009-05-21 15:59:15.000000000 +0200
+++ gcc/config/arm/arm.c 2009-06-01 12:07:25.000000000 +0200
@@ -16984,7 +16984,7 @@ thumb_pushpop (FILE *f, unsigned long ma
if (push && pushed_words && dwarf2out_do_frame ())
{
- char *l = dwarf2out_cfi_label ();
+ char *l = dwarf2out_cfi_label (false);
int pushed_mask = real_regs;
*cfa_offset += pushed_words * 4;
@@ -17880,7 +17880,7 @@ thumb1_output_function_prologue (FILE *f
the stack pointer. */
if (dwarf2out_do_frame ())
{
- char *l = dwarf2out_cfi_label ();
+ char *l = dwarf2out_cfi_label (false);
cfa_offset = cfa_offset + crtl->args.pretend_args_size;
dwarf2out_def_cfa (l, SP_REGNUM, cfa_offset);
@@ -17929,7 +17929,7 @@ thumb1_output_function_prologue (FILE *f
if (dwarf2out_do_frame ())
{
- char *l = dwarf2out_cfi_label ();
+ char *l = dwarf2out_cfi_label (false);
cfa_offset = cfa_offset + 16;
dwarf2out_def_cfa (l, SP_REGNUM, cfa_offset);
--- gcc/config/vax/vax.c.jj 2009-05-19 10:51:31.000000000 +0200
+++ gcc/config/vax/vax.c 2009-06-01 12:07:52.000000000 +0200
@@ -133,7 +133,7 @@ vax_output_function_prologue (FILE * fil
if (dwarf2out_do_frame ())
{
- const char *label = dwarf2out_cfi_label ();
+ const char *label = dwarf2out_cfi_label (false);
int offset = 0;
for (regno = FIRST_PSEUDO_REGISTER-1; regno >= 0; --regno)
Jakub