aboutsummaryrefslogtreecommitdiff
path: root/gdb/amd64fbsd-tdep.c
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@freebsd.org>2015-02-25 09:51:42 -0500
committerPedro Alves <palves@redhat.com>2015-02-26 11:10:25 +0000
commitcf424aef0af89903abdd6c4e055684929e4990af (patch)
tree2dd568a48d7a0ee4bd6d523e9acb7b09e62fe332 /gdb/amd64fbsd-tdep.c
parentc5cb74eeb3ea13a9fbeb0ec26b5bad10c4b92e4a (diff)
downloadgdb-cf424aef0af89903abdd6c4e055684929e4990af.zip
gdb-cf424aef0af89903abdd6c4e055684929e4990af.tar.gz
gdb-cf424aef0af89903abdd6c4e055684929e4990af.tar.bz2
Rework signal frame probing for FreeBSD/x86
- Use signal frame sniffers that look for the signal trampoline instruction sequence to detect most signal frames. - FreeBSD kernels between 9.2 and 10.1 inclusive do not include the signal trampoline code in process core dumps. To detect signal frames for core dumps under these kernels, use the kern.proc.sigtramp.<pid> sysctl to fetch the location of the signal trampoline in the gdb process and assume that PC values within this location are signal frames. This depends on that location being identical for all binaries. gdb/ChangeLog: 2015-02-25 John Baldwin <jhb@FreeBSD.org> * amd64fbsd-nat.c: Include sys/user.h. (_initialize_amd64fbsd_nat): Use the KERN_PROC_SIGTRAMP sysctl instead of KERN_PS_STRINGS to locate the signal trampoline. * i386fbsd-nat.c: Include sys/user.h. (_initialize_i386fbsd_nat): Use the KERN_PROC_SIGTRAMP sysctl instead of KERN_PS_STRINGS to locate the signal trampoline. * amd64fbsd-tdep.c (amd64fbsd_sigtramp_code): New. (amd64fbsd_sigtramp_p): New. (amd64fbsd_sigtramp_start_addr, amd64fbsd_sigtramp_end_addr): No longer set default values. (amd64fbsd_init_abi): Set "sigtramp_p" to "amd64fbsd_sigtramp_p". * i386fbsd-tdep.c (i386fbsd_sigtramp_start) (i386fbsd_sigtramp_middle, i386fbsd_sigtramp_end) (i386fbsd_freebsd4_sigtramp_start) (i386fbsd_freebsd4_sigtramp_middle) (i386fbsd_freebsd4_sigtramp_end, i386fbsd_osigtramp_start) (i386fbsd_osigtramp_middle, i386fbsd_osigtramp_end): New. (i386fbsd_sigtramp_p): New. (i386fbsd_sigtramp_start_addr, i386fbsd_sigtramp_end_addr): No longer set default values. (i386fbsd_init_abi): Set "sigtramp_p" to "i386fbsd_sigtramp_p".
Diffstat (limited to 'gdb/amd64fbsd-tdep.c')
-rw-r--r--gdb/amd64fbsd-tdep.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/gdb/amd64fbsd-tdep.c b/gdb/amd64fbsd-tdep.c
index abb0cab..e11b0f3 100644
--- a/gdb/amd64fbsd-tdep.c
+++ b/gdb/amd64fbsd-tdep.c
@@ -31,6 +31,33 @@
/* Support for signal handlers. */
+/* Return whether THIS_FRAME corresponds to a FreeBSD sigtramp
+ routine. */
+
+static const gdb_byte amd64fbsd_sigtramp_code[] =
+{
+ 0x48, 0x8d, 0x7c, 0x24, 0x10, /* lea SIGF_UC(%rsp),%rdi */
+ 0x6a, 0x00, /* pushq $0 */
+ 0x48, 0xc7, 0xc0, 0xa1, 0x01, 0x00, 0x00,
+ /* movq $SYS_sigreturn,%rax */
+ 0x0f, 0x05 /* syscall */
+};
+
+static int
+amd64fbsd_sigtramp_p (struct frame_info *this_frame)
+{
+ CORE_ADDR pc = get_frame_pc (this_frame);
+ gdb_byte buf[sizeof amd64fbsd_sigtramp_code];
+
+ if (!safe_frame_unwind_memory (this_frame, pc, buf, sizeof buf))
+ return 0;
+ if (memcmp (buf, amd64fbsd_sigtramp_code, sizeof amd64fbsd_sigtramp_code) !=
+ 0)
+ return 0;
+
+ return 1;
+}
+
/* Assuming THIS_FRAME is for a BSD sigtramp routine, return the
address of the associated sigcontext structure. */
@@ -88,8 +115,8 @@ static int amd64fbsd_r_reg_offset[] =
};
/* Location of the signal trampoline. */
-CORE_ADDR amd64fbsd_sigtramp_start_addr = 0x7fffffffffc0ULL;
-CORE_ADDR amd64fbsd_sigtramp_end_addr = 0x7fffffffffe0ULL;
+CORE_ADDR amd64fbsd_sigtramp_start_addr;
+CORE_ADDR amd64fbsd_sigtramp_end_addr;
/* From <machine/signal.h>. */
int amd64fbsd_sc_reg_offset[] =
@@ -199,6 +226,7 @@ amd64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
amd64_init_abi (info, gdbarch);
+ tdep->sigtramp_p = amd64fbsd_sigtramp_p;
tdep->sigtramp_start = amd64fbsd_sigtramp_start_addr;
tdep->sigtramp_end = amd64fbsd_sigtramp_end_addr;
tdep->sigcontext_addr = amd64fbsd_sigcontext_addr;