[Bug debug/99334] Generated DWARF unwind table issue while on instructions where rbp is pointing to callers stack frame

jakub at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Fri Mar 26 16:01:36 GMT 2021


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99334

--- Comment #9 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
As I said on the mailing list, the above patch has problems, it relies on the
insn that clobbers_queued_reg_save to be a single hardware instruction so that
a debug info consumer or unwinding can't stop "in the middle of the
instruction".
We have various NONJUMP_INSN_P insns that violate that, for one inline asm, but
also various patterns that emit more than one insn.
E.g. on x86 they are usually (but unsure if we can guarantee that) marked by
get_attr_type (insn) == TYPE_MULTI.
I have tried to instead deal with this on the i386.c side with:
--- i386.c.jj3  2021-03-25 21:05:35.554309579 +0100
+++ i386.c      2021-03-26 15:56:21.349642695 +0100
@@ -8355,9 +8355,33 @@ ix86_expand_prologue (void)

       if (m->fs.sp_offset == frame.hard_frame_pointer_offset)
        {
+         if (stack_realign_drap)
+           {
+             /* Pretend the push %[re]bp instruction is just
+                add $-wordsize, [%re]sp for CFI purposes.  */
+             rtx spadj = plus_constant (Pmode, stack_pointer_rtx,
+                                        -UNITS_PER_WORD);
+             rtx r = gen_rtx_SET (stack_pointer_rtx, spadj);
+             add_reg_note (insn, REG_FRAME_RELATED_EXPR, r);
+           }
+
          insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
          RTX_FRAME_RELATED_P (insn) = 1;

+         if (stack_realign_drap)
+           {
+             /* And that the mov %[re]sp, %[re]bp instruction acts as
+                both mov %[re]bp, (%[re]sp) and mov %[re]sp, %[re]bp
+                together for CFI purposes.  */
+             rtx r = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
+             XVECEXP (r, 0, 0)
+               = gen_rtx_SET (gen_rtx_MEM (word_mode, stack_pointer_rtx),
+                              hard_frame_pointer_rtx);
+             XVECEXP (r, 0, 1)
+               = gen_rtx_SET (hard_frame_pointer_rtx, stack_pointer_rtx);
+             add_reg_note (insn, REG_FRAME_RELATED_EXPR, r);
+           }
+
          if (m->fs.cfa_reg == stack_pointer_rtx)
            m->fs.cfa_reg = hard_frame_pointer_rtx;
          m->fs.fp_offset = m->fs.sp_offset;
but unfortunately that doesn't work properly, because dwarf2cfi.c has special
rule for that push %[re]bp with drap active, described as Rule 18.
So I think we should instead change the dwarf2cfi.c rule 18 handling so that it
waits with the reg save until the hfp = sp instruction after it.

Generally, there is also the option of e.g. adding some insn attribute on
targets that want it which would say which instructions are single undivisible
hw instructions and use that get_attr_{single,undivisible} or how it would be
called in dwarf2cfi.c to decide whether to emit queued reg saves before it or
after it.


More information about the Gcc-bugs mailing list