From: Daniel Jacobowitz <drow@false.org>
To: Andreas Jaeger <aj@suse.de>
Cc: Mark Kettenis <mark.kettenis@xs4all.nl>,
gdb@sourceware.org, libc-alpha@sourceware.org, ak@suse.de
Subject: Re: Notes on a frame_unwind_address_in_block problem
Date: Tue, 18 Jul 2006 18:39:00 -0000 [thread overview]
Message-ID: <20060718183520.GA17864@nevyn.them.org> (raw)
In-Reply-To: <hoirlvgytk.fsf@reger.suse.de>
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 <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)
next prev parent reply other threads:[~2006-07-18 18:35 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-07-06 22:22 Daniel Jacobowitz
2006-07-13 20:20 ` Mark Kettenis
2006-07-17 7:30 ` Andreas Jaeger
2006-07-17 13:15 ` Mark Kettenis
2006-07-17 13:20 ` Daniel Jacobowitz
2006-07-18 9:48 ` Andreas Jaeger
2006-07-18 18:39 ` Daniel Jacobowitz [this message]
2006-08-03 2:04 ` Daniel Jacobowitz
2006-08-03 2:38 ` Andi Kleen
2006-08-03 2:48 ` Daniel Jacobowitz
2006-08-03 3:12 ` Andi Kleen
2006-08-03 3:21 ` Daniel Jacobowitz
2006-08-03 3:29 ` Andi Kleen
2006-08-03 13:27 ` Daniel Jacobowitz
2006-08-18 15:08 ` Andreas Jaeger
2006-08-18 15:15 ` Daniel Jacobowitz
2006-08-21 8:50 ` Andreas Jaeger
2006-08-21 14:19 ` Ulrich Drepper
2006-08-21 14:52 ` Daniel Jacobowitz
2006-07-18 18:50 ` Daniel Jacobowitz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060718183520.GA17864@nevyn.them.org \
--to=drow@false.org \
--cc=aj@suse.de \
--cc=ak@suse.de \
--cc=gdb@sourceware.org \
--cc=libc-alpha@sourceware.org \
--cc=mark.kettenis@xs4all.nl \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox