Re: unwinding for vsyscall code

Richard Henderson (rth@twiddle.net)
Sun, 13 Apr 2003 14:10:28 -0700


On Sat, Apr 12, 2003 at 08:57:16PM -0700, Ulrich Drepper wrote:
> + /* What follows are the instructions for the table generation.
> + We have to record all changes of the stack pointer. */
> + 0x04, /* DW_CFA_advance_loc4 */
> + 0x01, 0x00, 0x00, 0x00, /* Size of push %ecx */
> + 0x0e, /* DW_CFA_def_cfa_offset */
> + 0x08, /* RA at offset 8 now */
> + 0x04, /* DW_CFA_advance_loc4 */
> + 0x01, 0x00, 0x00, 0x00, /* Size of push %edx */
> + 0x0e, /* DW_CFA_def_cfa_offset */
> + 0x0c, /* RA at offset 12 now */
> + 0x04, /* DW_CFA_advance_loc4 */
> + 0x01, 0x00, 0x00, 0x00, /* Size of push %ebp */
> + 0x0e, /* DW_CFA_def_cfa_offset */
> + 0x10, /* RA at offset 16 now */

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/