From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29464 invoked by alias); 18 Jul 2006 18:35:26 -0000 Received: (qmail 29447 invoked by uid 22791); 18 Jul 2006 18:35:25 -0000 X-Spam-Check-By: sourceware.org Received: from nevyn.them.org (HELO nevyn.them.org) (66.93.172.17) by sourceware.org (qpsmtpd/0.31.1) with ESMTP; Tue, 18 Jul 2006 18:35:22 +0000 Received: from drow by nevyn.them.org with local (Exim 4.54) id 1G2uPg-0006F2-99; Tue, 18 Jul 2006 14:35:20 -0400 Date: Tue, 18 Jul 2006 18:39:00 -0000 From: Daniel Jacobowitz To: Andreas Jaeger Cc: Mark Kettenis , gdb@sourceware.org, libc-alpha@sourceware.org, ak@suse.de Subject: Re: Notes on a frame_unwind_address_in_block problem Message-ID: <20060718183520.GA17864@nevyn.them.org> Mail-Followup-To: Andreas Jaeger , Mark Kettenis , gdb@sourceware.org, libc-alpha@sourceware.org, ak@suse.de References: <20060706222157.GA1377@nevyn.them.org> <200607132020.k6DKKCSB023812@elgar.sibelius.xs4all.nl> <8340.192.87.1.22.1153121386.squirrel@webmail.xs4all.nl> <20060717131527.GA9392@nevyn.them.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.11+cvs20060403 X-IsSubscribed: yes Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org X-SW-Source: 2006-07/txt/msg00132.txt.bz2 On Tue, Jul 18, 2006 at 09:24:39AM +0200, Andreas Jaeger wrote: > > Andreas, looking at the i386 version, I guess that using SA_RESTORER > > this way is not necessary. Simply a performance optimization because > > the old trampolines (written to the stack) were so slow, or maybe > > because they required an executable stack. i386 has > > "if (GLRO(dl_sysinfo_dso) == NULL)" around it. Can x86_64 do the same > > thing? > > i386 is the only platform doing it. I don't know the history of the > change and whether this is the right thing to do. Is somebody willing > to test this? Well, I tried. But it looks like I was just wrong about the situation. i386 has a vDSO and uses it for signal return trampolines, but x86_64 doesn't have a vDSO and in fact requires the use of SA_RESTORER. All x86_64 has is the vsyscall page, which is older. (There's something claiming to be [vdso] mapped in, but I think it's just the vsyscalls.) So I came up with this alternative patch. Glibc tests fine, and GDB (combined with a patch for the function-address-in-block issue mentioned upthread) improves quite a lot. 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). -- Daniel Jacobowitz CodeSourcery 2006-07-18 Daniel Jacobowitz * 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)