Message ID | 20100723021849.GA20358@caradoc.them.org |
---|---|
State | New |
Headers | show |
On Fri, Jul 23, 2010 at 4:18 AM, Daniel Jacobowitz <dan@codesourcery.com> wrote: > I traced a large number of GDB test failures on m68k-elf to bogus CFI > data. Here's a typical example: > > foo: > .LFB0: > .file 1 "gdb.base/advance.c" > .loc 1 5 0 > .cfi_startproc > link.w %fp,#-4 > .LCFI0: > .cfi_def_cfa 14, 8 > .loc 1 6 0 > move.l 8(%fp),%a0 > lea (10,%a0),%a0 > move.l %a0,-4(%fp) > .loc 1 7 0 > move.l -4(%fp),%d0 > .loc 1 8 0 > unlk %fp > .cfi_offset 14, -8 > rts > .cfi_endproc > > 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? Ok. Thanks, Richard. > -- > Daniel Jacobowitz > CodeSourcery > > 2010-07-22 Daniel Jacobowitz <dan@codesourcery.com> > > * dwarf2out.c (dwarf2out_frame_debug): Check for queued saves > again after processing insn. > > Index: gcc/dwarf2out.c > =================================================================== > --- gcc/dwarf2out.c (revision 162416) > +++ gcc/dwarf2out.c (working copy) > @@ -2791,6 +2791,12 @@ dwarf2out_frame_debug (rtx insn, bool af > insn = PATTERN (insn); > found: > 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 >
Index: gcc/dwarf2out.c =================================================================== --- gcc/dwarf2out.c (revision 162416) +++ gcc/dwarf2out.c (working copy) @@ -2791,6 +2791,12 @@ dwarf2out_frame_debug (rtx insn, bool af insn = PATTERN (insn); found: 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