This is the mail archive of the
mailing list for the GCC project.
RFA: Fix DWARF2 CFI for m68k
- From: Daniel Jacobowitz <dan at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 22 Jul 2010 22:18:54 -0400
- Subject: RFA: Fix DWARF2 CFI for m68k
I traced a large number of GDB test failures on m68k-elf to bogus CFI
data. Here's a typical example:
.file 1 "gdb.base/advance.c"
.loc 1 5 0
.cfi_def_cfa 14, 8
.loc 1 6 0
.loc 1 7 0
.loc 1 8 0
.cfi_offset 14, -8
Take a look at that .cfi_offset. It represents the save of %fp at
CFA-8, by the link.w instruction. But it's way down at the end, and
the link.w instruction modified %fp. So GDB's idea of the saved value
of %fp is wrong except right before the rts (at which point it's wrong
again, because we're after the unlk - but that's a different issue).
The problem was the parallel used by the link.w pattern.
dwarf2out_frame_debug outputs queued saves if the current insn would
interfere, before processing it. But it doesn't output saves after
the insn if the insn itself both queued new saves and clobbered the
register they were relative to.
This shows up for m68k because the link instruction does a save and a
frame pointer update in parallel. I believe it doesn't show up for
other architectures, e.g. ARM, because the frame-related epxr on ARM
is a SEQUENCE rather than a PARALLEL.
Regression tested on an m68k-elf cross compiler (three ColdFire
multilibs with QEMU). We've also had it in our tree for a while to
test on other platforms.
OK to commit?
2010-07-22 Daniel Jacobowitz <email@example.com>
* dwarf2out.c (dwarf2out_frame_debug): Check for queued saves
again after processing insn.
--- gcc/dwarf2out.c (revision 162416)
+++ gcc/dwarf2out.c (working copy)
@@ -2791,6 +2791,12 @@ dwarf2out_frame_debug (rtx insn, bool af
insn = PATTERN (insn);
dwarf2out_frame_debug_expr (insn, label);
+ /* Check again. A parallel can save and update the same register.
+ We could probably check just once, here, but this is safer than
+ removing the check above. */
+ if (clobbers_queued_reg_save (insn))
+ flush_queued_reg_saves ();
/* Determine if we need to save and restore CFI information around this