diff options
author | John Baldwin <jhb@FreeBSD.org> | 2015-02-21 16:43:30 -0500 |
---|---|---|
committer | John Baldwin <jhb@FreeBSD.org> | 2015-04-13 16:07:01 -0400 |
commit | 97de3545ca6b690031cc00983346ed72f11e78a2 (patch) | |
tree | 15eca66ea0dd34d0a1d1555d9ef93a48e7015214 /gdb/amd64fbsd-nat.c | |
parent | 0d2a7a932244fab27d6c4ce211ea8f7708a1a9cc (diff) | |
download | binutils-gdb-97de3545ca6b690031cc00983346ed72f11e78a2.tar.gz |
Add support for the x86 XSAVE extended state on FreeBSD/x86.
Recognize NT_X86_XSTATE notes in FreeBSD process cores. Recent
FreeBSD versions include a note containing the XSAVE state for each
thread in the process when XSAVE is in use. The note stores a copy of
the current XSAVE mask in a reserved section of the machine-defined
XSAVE state at the same offset as Linux's NT_X86_XSTATE note.
For native processes, use the PT_GETXSTATE_INFO ptrace request to
determine if XSAVE is enabled, and if so the active XSAVE state mask
(that is, the value of %xcr0 for the target process) as well as the
size of XSAVE state area. Use the PT_GETXSTATE and PT_SETXSTATE requests
to fetch and store the XSAVE state, respectively, in the BSD x86
native targets.
In addition, the FreeBSD amd64 and i386 native targets now include
"read_description" target methods to determine the correct x86 target
description for the current XSAVE mask. On FreeBSD amd64 this also
properly returns an i386 target description for 32-bit binaries which
allows the 64-bit GDB to run 32-bit binaries.
Note that the ptrace changes are in the BSD native targets, not the
FreeBSD-specific native targets since that is where the other ptrace
register accesses occur. Of the other BSDs, NetBSD and DragonFly use
XSAVE in the kernel but do not currently export the extended state via
ptrace(2). OpenBSD does not currently support XSAVE.
bfd/ChangeLog:
* elf.c (elfcore_grok_note): Recognize NT_X86_XSTATE on
FreeBSD.
(elfcore_write_xstatereg): Use correct note name on FreeBSD.
gdb/ChangeLog:
* amd64-tdep.c (amd64_target_description): New function.
* amd64-tdep.h: Export amd64_target_description and tdesc_amd64.
* amd64bsd-nat.c [PT_GETXSTATE_INFO]: New variable amd64bsd_xsave_len.
(amd64bsd_fetch_inferior_registers) [PT_GETXSTATE_INFO]: Handle
x86 extended save area.
(amd64bsd_store_inferior_registers) [PT_GETXSTATE_INFO]: Likewise.
* amd64bsd-nat.h: Export amd64bsd_xsave_len.
* amd64fbsd-nat.c (amd64fbsd_read_description): New function.
(_initialize_amd64fbsd_nat): Set "to_read_description" to
"amd64fbsd_read_description".
* amd64fbsd-tdep.c (amd64fbsd_core_read_description): New function.
(amd64fbsd_supply_xstateregset): New function.
(amd64fbsd_collect_xstateregset): New function.
Add "amd64fbsd_xstateregset".
(amd64fbsd_iterate_over_regset_sections): New function.
(amd64fbsd_init_abi): Set "xsave_xcr0_offset" to
"I386_FBSD_XSAVE_XCR0_OFFSET".
Add "iterate_over_regset_sections" gdbarch method.
Add "core_read_description" gdbarch method.
* i386-tdep.c (i386_target_description): New function.
* i386-tdep.h: Export i386_target_description and tdesc_i386.
* i386bsd-nat.c [PT_GETXSTATE_INFO]: New variable i386bsd_xsave_len.
(i386bsd_fetch_inferior_registers) [PT_GETXSTATE_INFO]: Handle
x86 extended save area.
(i386bsd_store_inferior_registers) [PT_GETXSTATE_INFO]: Likewise.
* i386bsd-nat.h: Export i386bsd_xsave_len.
* i386fbsd-nat.c (i386fbsd_read_description): New function.
(_initialize_i386fbsd_nat): Set "to_read_description" to
"i386fbsd_read_description".
* i386fbsd-tdep.c (i386fbsd_core_read_xcr0): New function.
(i386fbsd_core_read_description): New function.
(i386fbsd_supply_xstateregset): New function.
(i386fbsd_collect_xstateregset): New function.
Add "i386fbsd_xstateregset".
(i386fbsd_iterate_over_regset_sections): New function.
(i386fbsd4_init_abi): Set "xsave_xcr0_offset" to
"I386_FBSD_XSAVE_XCR0_OFFSET".
Add "iterate_over_regset_sections" gdbarch method.
Add "core_read_description" gdbarch method.
* i386fbsd-tdep.h: New file.
Diffstat (limited to 'gdb/amd64fbsd-nat.c')
-rw-r--r-- | gdb/amd64fbsd-nat.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/gdb/amd64fbsd-nat.c b/gdb/amd64fbsd-nat.c index b1b261c1961..a721f48edee 100644 --- a/gdb/amd64fbsd-nat.c +++ b/gdb/amd64fbsd-nat.c @@ -151,6 +151,50 @@ amd64fbsd_mourn_inferior (struct target_ops *ops) super_mourn_inferior (ops); } +/* Implement the to_read_description method. */ + +static const struct target_desc * +amd64fbsd_read_description (struct target_ops *ops) +{ +#ifdef PT_GETXSTATE_INFO + static int xsave_probed; + static uint64_t xcr0; +#endif + struct reg regs; + int is64; + + if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid), + (PTRACE_TYPE_ARG3) ®s, 0) == -1) + perror_with_name (_("Couldn't get registers")); + is64 = (regs.r_cs == GSEL (GUCODE_SEL, SEL_UPL)); +#ifdef PT_GETXSTATE_INFO + if (!xsave_probed) + { + struct ptrace_xstate_info info; + + if (ptrace (PT_GETXSTATE_INFO, ptid_get_pid (inferior_ptid), + (PTRACE_TYPE_ARG3) &info, sizeof (info)) == 0) + { + amd64bsd_xsave_len = info.xsave_len; + xcr0 = info.xsave_mask; + } + xsave_probed = 1; + } + + if (amd64bsd_xsave_len != 0) + { + if (is64) + return amd64_target_description (xcr0); + else + return i386_target_description (xcr0); + } +#endif + if (is64) + return tdesc_amd64; + else + return tdesc_i386; +} + /* Provide a prototype to silence -Wmissing-prototypes. */ void _initialize_amd64fbsd_nat (void); @@ -181,6 +225,7 @@ _initialize_amd64fbsd_nat (void) super_mourn_inferior = t->to_mourn_inferior; t->to_mourn_inferior = amd64fbsd_mourn_inferior; + t->to_read_description = amd64fbsd_read_description; t->to_pid_to_exec_file = fbsd_pid_to_exec_file; t->to_find_memory_regions = fbsd_find_memory_regions; |