diff options
author | John Baldwin <jhb@freebsd.org> | 2015-02-25 09:51:42 -0500 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2015-02-26 11:10:25 +0000 |
commit | cf424aef0af89903abdd6c4e055684929e4990af (patch) | |
tree | 2dd568a48d7a0ee4bd6d523e9acb7b09e62fe332 /gdb/amd64fbsd-tdep.c | |
parent | c5cb74eeb3ea13a9fbeb0ec26b5bad10c4b92e4a (diff) | |
download | gdb-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.c | 32 |
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; |