This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Notes on a frame_unwind_address_in_block problem


On Tue, Jul 18, 2006 at 02:35:20PM -0400, Daniel Jacobowitz wrote:
> The only caveat is that it is in glibc, but knows about the kernel
> layout of struct rt_sigframe - specifically that a struct ucontext
> lives just above the SA_RESTORER return address.  Andi, what do you
> think of that?  If it's a bad idea, we may need a different approach
> (i.e. a vdso).

Andreas, Andi, did either of you have an opinion on this?  I'd really
like to get the "GDB bug" fixed one way or the other.  But I'm not
sure yet if we can do it with this glibc patch, or whether we need a
true ELF vDSO - or what other x86_64 specific issues that might have.

> 2006-07-18  Daniel Jacobowitz  <dan@codesourcery.com>
> 
> 	* sysdeps/unix/sysv/linux/x86_64/sigaction.c (restore_rt): Add correct
> 	unwind information.
> 
> Index: sysdeps/unix/sysv/linux/x86_64/sigaction.c
> ===================================================================
> RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/x86_64/sigaction.c,v
> retrieving revision 1.9
> diff -u -p -r1.9 sigaction.c
> --- sysdeps/unix/sysv/linux/x86_64/sigaction.c	29 Dec 2005 16:32:17 -0000	1.9
> +++ sysdeps/unix/sysv/linux/x86_64/sigaction.c	18 Jul 2006 17:52:21 -0000
> @@ -95,18 +95,94 @@ weak_alias (__libc_sigaction, sigaction)
>     signal handlers work right.  Important are both the names
>     (__restore_rt) and the exact instruction sequence.
>     If you ever feel the need to make any changes, please notify the
> -   appropriate GDB maintainer.  */
> +   appropriate GDB maintainer.
> +
> +   The unwind information starts a byte before __restore_rt, so that
> +   it is found when unwinding, to get an address the unwinder assumes
> +   will be in the middle of a call instruction.  See the Linux kernel
> +   (the i386 vsyscall, in particular) for an explanation of the complex
> +   unwind information used here in order to get the traditional CFA.
> +   We do not restore cs - it's only stored as two bytes here so that's
> +   a bit tricky.  We don't use the gas cfi directives, so that we can
> +   reliably add .cfi_signal_frame.  */
> +
> +#define do_cfa_expr \
> +  ".byte 0x0f\n"	/* DW_CFA_def_cfa_expression */	\
> +  ".byte 0x04\n"	/* length */		\
> +  ".byte 0x77\n"   	/* DW_OP_breg8 */	\
> +  ".byte 0xa0\n"				\
> +  ".byte 0x01\n"	/* 160 */		\
> +  ".byte 0x06\n"	/* DW_OP_deref */
> +
> +#define do_expr_1(regno, offset) \
> +  ".byte 0x10\n"	/* DW_CFA_expression */	\
> +  ".byte " CFI_STRINGIFY(regno) "\n"		\
> +  ".byte 0x02\n"	/* length */		\
> +  ".byte 0x77\n"   	/* DW_OP_breg8 */	\
> +  ".byte " CFI_STRINGIFY(offset) "\n"		\
> +
> +#define do_expr_2(regno, offset1, offset2) \
> +  ".byte 0x10\n"	/* DW_CFA_expression */	\
> +  ".byte " CFI_STRINGIFY(regno) "\n"		\
> +  ".byte 0x03\n"	/* length */		\
> +  ".byte 0x77\n"   	/* DW_OP_breg8 */	\
> +  ".byte " CFI_STRINGIFY(offset1) "\n"		\
> +  ".byte " CFI_STRINGIFY(offset2) "\n"		\
>  
>  #define RESTORE(name, syscall) RESTORE2 (name, syscall)
>  # define RESTORE2(name, syscall) \
>  asm						\
>    (						\
>     ".align 16\n"				\
> -   CFI_STARTPROC "\n"				\
> +   ".LSTART_" #name ":\n"			\
> +   "	nop\n"					\
>     "__" #name ":\n"				\
>     "	movq $" #syscall ", %rax\n"		\
>     "	syscall\n"				\
> -   CFI_ENDPROC "\n"				\
> +   ".LEND_" #name ":\n"				\
> +   ".section .eh_frame,\"a\",@progbits\n"				\
> +   ".LSTARTFRAME_" #name ":\n"						\
> +   "	.long .LENDCIE_" #name "-.LSTARTCIE_" #name "\n"		\
> +   ".LSTARTCIE_" #name ":\n"						\
> +   "	.long 0\n"	/* CIE ID */					\
> +   "	.byte 1\n"	/* Version number */				\
> +   "	.string \"zRS\"\n" /* NUL-terminated augmentation string */	\
> +   "	.uleb128 1\n"	/* Code alignment factor */			\
> +   "	.sleb128 -8\n"	/* Data alignment factor */			\
> +   "	.byte 0x10\n"	/* Return address register column */		\
> +   "	.uleb128 1\n"	/* Augmentation value length */			\
> +   "	.byte 0x1b\n"	/* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */		\
> +   "	.byte 0\n"	/* DW_CFA_nop */				\
> +   "	.align 8\n"							\
> +   ".LENDCIE_" #name ":\n"						\
> +   "	.long .LENDFDE_" #name "-.LSTARTFDE_" #name "\n" /* FDE len */	\
> +   ".LSTARTFDE_" #name ":\n"						\
> +   "	.long .LSTARTFDE_" #name "-.LSTARTFRAME_" #name "\n" /* CIE */	\
> +   "	.long .LSTART_" #name "-.\n"	/* PC-relative start address */	\
> +   "	.long .LEND_" #name "-.LSTART_" #name "\n"			\
> +   "	.uleb128 0\n"			/* Augmentation */		\
> +   do_cfa_expr					\
> +   do_expr_1 (8, 0x28)				\
> +   do_expr_1 (9, 0x30)				\
> +   do_expr_1 (10, 0x38)				\
> +   do_expr_2 (11, 0xc0, 0x00)			\
> +   do_expr_2 (12, 0xc8, 0x00)			\
> +   do_expr_2 (13, 0xd0, 0x00)			\
> +   do_expr_2 (14, 0xd8, 0x00)			\
> +   do_expr_2 (15, 0xe0, 0x00)			\
> +   do_expr_2 (5, 0xe8, 0x00)			\
> +   do_expr_2 (4, 0xf0, 0x00)			\
> +   do_expr_2 (6, 0xf8, 0x00)			\
> +   do_expr_2 (3, 0x80, 0x01)			\
> +   do_expr_2 (1, 0x88, 0x01)			\
> +   do_expr_2 (0, 0x90, 0x01)			\
> +   do_expr_2 (2, 0x98, 0x01)			\
> +   do_expr_2 (7, 0xa0, 0x01)			\
> +   do_expr_2 (16, 0xa8, 0x01)			\
> +   do_expr_2 (41, 0xb0, 0x01)			\
> +   ".align 4\n"					\
> +   ".LENDFDE_" #name ":\n"			\
> +   ".previous\n"				\
>     );
>  /* The return code for realtime-signals.  */
>  RESTORE (restore_rt, __NR_rt_sigreturn)
> 

-- 
Daniel Jacobowitz
CodeSourcery


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]