Not only changes to the stack pointer, but also changes to call-saved
registers, such as %ebp. You're intending to be able to unwind through
asynchronous signals here, which means that you can't leave even a single
insn window with a register modified but not recorded.
So you also need a
0x85 0x04 DW_CFA_offset %ebp -16
there at the end of the prologue.
> + /* Finally the epilogue. */
> + 0x04, /* DW_CFA_advance_loc4 */
> + 0x0e, 0x00, 0x00, 0x00, /* Offset til pop %edx */
> + 0x0e, /* DW_CFA_def_cfa_offset */
> + 0x12, /* RA at offset 12 now */
And of course you need a corresponding bit here, since once we
pop off the slot in which we stored %ebp, we can't restore it
from there, because we will have clobbered that slot in the
signal handler.
(Btw, typo here in comment; it's "%ebp" not "%edx".)
So here we also need a
0xc5 DW_CFA_restore %ebp
here before the next DW_CFA_advance_loc.
Oh, and you don't need to use DW_CFA_advance_loc4. You should
be using
DW_CFA_advance_loc+N N <= 0x3f
DW_CFA_advance_loc1 N N <= 0xff
We have to use DW_CFA_advance_loc4 in GCC because we don't know
the true sizes of instructions. This gets fixed for us in GAS
through some truely disgusting magic based on section names.
r~
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/