This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[PATCH] Improve OpenBSD/amd64 signal trampoline unwinder
- From: Mark Kettenis <kettenis at chello dot nl>
- To: gdb-patches at sources dot redhat dot com
- Date: Sat, 15 May 2004 23:07:52 +0200 (CEST)
- Subject: [PATCH] Improve OpenBSD/amd64 signal trampoline unwinder
This patch makes sure we always return the correct address for `struct
sigcontext'.
Committed,
Mark
Index: ChangeLog
from Mark Kettenis <kettenis@gnu.org>
* amd64obsd-tdep.c (amd64obsd_sigtramp_p): Replace hexadecimal
offset with decimal offset.
(amd64obsd_sigcontext_addr): Return correct address for entire
signal trampoline.
Index: amd64obsd-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/amd64obsd-tdep.c,v
retrieving revision 1.9
diff -u -p -r1.9 amd64obsd-tdep.c
--- amd64obsd-tdep.c 9 Apr 2004 23:26:19 -0000 1.9
+++ amd64obsd-tdep.c 15 May 2004 21:05:12 -0000
@@ -109,7 +109,7 @@ amd64obsd_sigtramp_p (struct frame_info
/* If we can't read the instructions at START_PC, return zero. */
buf = alloca (sizeof sigreturn);
- if (target_read_memory (start_pc + 0x7, buf, sizeof sigreturn))
+ if (target_read_memory (start_pc + 7, buf, sizeof sigreturn))
return 0;
/* Check for sigreturn(2). */
@@ -125,9 +125,25 @@ amd64obsd_sigtramp_p (struct frame_info
static CORE_ADDR
amd64obsd_sigcontext_addr (struct frame_info *next_frame)
{
+ CORE_ADDR pc = frame_pc_unwind (next_frame);
+ ULONGEST offset = (pc & (amd64obsd_page_size - 1));
+
/* The %rsp register points at `struct sigcontext' upon entry of a
- signal trampoline. */
- return frame_unwind_register_unsigned (next_frame, AMD64_RSP_REGNUM);
+ signal trampoline. The relevant part of the trampoline is
+
+ call *%rax
+ movq %rsp, %rdi
+ pushq %rdi
+ movq $SYS_sigreturn,%rax
+ int $0x80
+
+ (see /usr/src/sys/arch/amd64/amd64/locore.S). The `pushq'
+ instruction clobbers %rsp, but its value is saved in `%rdi'. */
+
+ if (offset > 6)
+ return frame_unwind_register_unsigned (next_frame, AMD64_RDI_REGNUM);
+ else
+ return frame_unwind_register_unsigned (next_frame, AMD64_RSP_REGNUM);
}
/* OpenBSD 3.5 or later. */