Add a wrapper for add_target in fbsd-nat.c to override target operations
common to all native FreeBSD targets.
gdb/ChangeLog:
* fbsd-nat.c (fbsd_pid_to_exec_file): Mark static.
(fbsd_find_memory_regions): Mark static.
(fbsd_nat_add_target): New function.
* fbsd-nat.h: Export fbsd_nat_add_target and remove prototypes for
fbsd_pid_to_exec_file and fbsd_find_memory_regions.
* amd64fbsd-nat.c (_initialize_amd64fbsd_nat): Use fbsd_nat_add_target.
* i386fbsd-nat.c (_initialize_i386fbsd_nat): Likewise.
* ppcfbsd-nat.c (_initialize_ppcfbsd_nat): Likewise.
* sparc64fbsd-nat.c (_initialize_sparc64fbsd_nat): Likewise.
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.
- 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".
This commit renames nine files that contain code used by both 32- and
64-bit Intel ports such that their names are prefixed with "x86"
rather than "i386". All types, functions and variables within these
files are likewise renamed such that their names are prefixed with
"x86" rather than "i386". This makes GDB follow the convention used
by gdbserver such that 32-bit Intel code lives in files called
"i386-*", 64-bit Intel code lives in files called "amd64-*", and code
for both 32- and 64-bit Intel lives in files called "x86-*".
This commit only renames OS-independent files. The Linux ports of
both GDB and gdbserver now follow the i386/amd64/x86 convention fully.
Some ports still use the old convention where "i386" in file/function/
type/variable names can mean "32-bit only" or "32- and 64-bit" but I
don't want to touch ports I can't fully test except where absolutely
necessary.
gdb/ChangeLog:
* i386-nat.h: Renamed as...
* x86-nat.h: New file. All type, function and variable name
prefixes changed from "i386_" to "x86_". All references updated.
* i386-nat.c: Renamed as...
* x86-nat.c: New file. All type, function and variable name
prefixes changed from "i386_" to "x86_". All references updated.
* common/i386-xstate.h: Renamed as...
* common/x86-xstate.h: New file. All type, function and variable
name prefixes changed from "i386_" to "x86_". All references
updated.
* nat/i386-cpuid.h: Renamed as...
* nat/x86-cpuid.h: New file. All type, function and variable name
prefixes changed from "i386_" to "x86_". All references updated.
* nat/i386-gcc-cpuid.h: Renamed as...
* nat/x86-gcc-cpuid.h: New file. All type, function and variable
name prefixes changed from "i386_" to "x86_". All references
updated.
* nat/i386-dregs.h: Renamed as...
* nat/x86-dregs.h: New file. All type, function and variable name
prefixes changed from "i386_" to "x86_". All references updated.
* nat/i386-dregs.c: Renamed as...
* nat/x86-dregs.c: New file. All type, function and variable name
prefixes changed from "i386_" to "x86_". All references updated.
gdb/gdbserver/ChangeLog:
* i386-low.h: Renamed as...
* x86-low.h: New file. All type, function and variable name
prefixes changed from "i386_" to "x86_". All references updated.
* i386-low.c: Renamed as...
* x86-low.c: New file. All type, function and variable name
prefixes changed from "i386_" to "x86_". All references updated.
While reviewing the native AArch64 patch, I noticed a problem:
On 02/06/2013 08:46 PM, Pedro Alves wrote:
>
>> > +static void
>> > +aarch64_linux_prepare_to_resume (struct lwp_info *lwp)
>> > +{
>> > + struct arch_lwp_info *info = lwp->arch_private;
>> > +
>> > + /* NULL means this is the main thread still going through the shell,
>> > + or, no watchpoint has been set yet. In that case, there's
>> > + nothing to do. */
>> > + if (info == NULL)
>> > + return;
>> > +
>> > + if (DR_HAS_CHANGED (info->dr_changed_bp)
>> > + || DR_HAS_CHANGED (info->dr_changed_wp))
>> > + {
>> > + int tid = GET_LWP (lwp->ptid);
>> > + struct aarch64_debug_reg_state *state = aarch64_get_debug_reg_state ();
> Hmm. This is always fetching the debug_reg_state of
> the current inferior, but may not be the inferior of lwp.
> I see the same bug on x86. Sorry about that. I'll fix it.
A natural fix would be to make xxx_get_debug_reg_state take an
inferior argument, but that doesn't work because of the case where we
detach breakpoints/watchpoints from the child fork, at a time there's
no inferior for the child fork at all. We do a nasty hack in
i386_inferior_data_get, but that relies on all callers pointing the
current inferior to the correct inferior, which isn't actually being
done by all callers, and I don't think we want to enforce that -- deep
in the bowls of linux-nat.c, there are many cases we resume lwps
behind the scenes, and it's be better to not have that code rely on
global state (as it doesn't today).
The fix is to decouple the watchpoints code from inferiors, making it
track target processes instead. This way, we can freely keep track of
the watchpoint mirrors for these processes behind the core's back.
Checkpoints also play dirty tricks with swapping the process behind
the inferior, so they get special treatment too in the patch (which
just amounts to calling a new hook). Instead of the old hack in
i386_inferior_data_get, where we returned a copy of the current
inferior's debug registers mirror, as soon as we detect a fork in the
target, we copy the debug register mirror from the parent to the child
process.
I don't have an old kernel handy to test, but I stepped through gdb doing
the watchpoint removal in the fork child in the watchpoint-fork test
seeing that the debug registers end up cleared in the child.
I didn't find the need for linux_nat_iterate_watchpoint_lwps. If
we use plain iterate_over_lwps instead, what happens is that
when removing watchpoints, that iterate_over_lwps doesn't actually
iterate over anything, since the fork child is not added to the
lwp list until later, at detach time, in linux_child_follow_fork.
And if we don't iterate over that lwp, we don't mark its debug
registers as needing update. But linux_child_follow_fork takes
care of doing that explicitly:
child_lp = add_lwp (inferior_ptid);
child_lp->stopped = 1;
child_lp->last_resume_kind = resume_stop;
make_cleanup (delete_lwp_cleanup, child_lp);
/* CHILD_LP has new PID, therefore linux_nat_new_thread is not called for it.
See i386_inferior_data_get for the Linux kernel specifics.
Ensure linux_nat_prepare_to_resume will reset the hardware debug
registers. It is done by the linux_nat_new_thread call, which is
being skipped in add_lwp above for the first lwp of a pid. */
gdb_assert (num_lwps (GET_PID (child_lp->ptid)) == 1);
if (linux_nat_new_thread != NULL)
linux_nat_new_thread (child_lp);
if (linux_nat_prepare_to_resume != NULL)
linux_nat_prepare_to_resume (child_lp);
ptrace (PTRACE_DETACH, child_pid, 0, 0);
so unless I'm missing something (quite possible) it ends up all
the same. But, the !detach-on-fork, and the "follow-fork child" paths
should also call linux_nat_new_thread, and they don't presently. It
seems to me in those cases we're not clearing debug regs correctly
when that's needed. Instead of copying that bit that works around
add_lwp bypassing the linux_nat_new_thread call, I thought it'd
be better to add an add_initial_lwp call to be used in the case we
really need to bypass linux_nat_new_thread, and make
add_lwp always call linux_nat_new_thread.
i386_cleanup_dregs is rewritten to forget about the current process
debug mirrors, which takes cares of other i386 ports. Only a couple
of extra tweaks here and there were needed, as some targets wheren't
actually calling i386_cleanup_dregs.
Tested on Fedora 17 x86_64 -m64/-m32.
GDBserver already fetches the i386_debug_reg_state from the right
process, and, it doesn't handle forks at all, so no fix is needed over
there.
gdb/
2013-02-13 Pedro Alves <palves@redhat.com>
* amd64-linux-nat.c (update_debug_registers_callback):
Update comment.
(amd64_linux_dr_set_control, amd64_linux_dr_set_addr): Use
iterate_over_lwps.
(amd64_linux_prepare_to_resume): Pass the lwp's pid to
i386_debug_reg_state.
(amd64_linux_new_fork): New function.
(_initialize_amd64_linux_nat): Install amd64_linux_new_fork as
linux_nat_new_fork hook, and i386_forget_process as
linux_nat_forget_process hook.
* i386-linux-nat.c (update_debug_registers_callback):
Update comment.
(amd64_linux_dr_set_control, amd64_linux_dr_set_addr): Use
iterate_over_lwps.
(i386_linux_prepare_to_resume): Pass the lwp's pid to
i386_debug_reg_state.
(i386_linux_new_fork): New function.
(_initialize_i386_linux_nat): Install i386_linux_new_fork as
linux_nat_new_fork hook, and i386_forget_process as
linux_nat_forget_process hook.
* i386-nat.c (i386_init_dregs): Delete.
(i386_inferior_data, struct i386_inferior_data):
Delete.
(struct i386_process_info): New.
(i386_process_list): New global.
(i386_find_process_pid, i386_add_process, i386_process_info_get):
New functions.
(i386_inferior_data_get): Delete.
(i386_process_info_get): New function.
(i386_debug_reg_state): New parameter 'pid'. Reimplement.
(i386_forget_process): New function.
(i386_cleanup_dregs): Rewrite.
(i386_update_inferior_debug_regs, i386_insert_watchpoint)
(i386_remove_watchpoint, i386_region_ok_for_watchpoint)
(i386_stopped_data_address, i386_insert_hw_breakpoint)
(i386_remove_hw_breakpoint): Adjust to pass the current process id
to i386_debug_reg_state.
(i386_use_watchpoints): Don't register inferior data.
* i386-nat.h (i386_debug_reg_state): Add new 'pid' parameter, and
adjust comment.
(i386_forget_process): Declare.
* linux-fork.c (delete_fork): Call linux_nat_forget_process.
* linux-nat.c (linux_nat_new_fork, linux_nat_forget_process_hook):
New static globals.
(linux_child_follow_fork): Don't call linux_nat_new_thread here.
(add_initial_lwp): New, factored out from ...
(add_lwp): ... this. Don't check the number of lwps before
calling linux_nat_new_thread.
(linux_nat_iterate_watchpoint_lwps): Delete.
(linux_nat_attach): Use add_initial_lwp instead of add_lwp.
(linux_handle_extended_wait): Call the linux_nat_new_fork hook on
forks and vforks.
(linux_nat_wait_1): Use add_initial_lwp instead of add_lwp for the
initial lwp.
(linux_nat_kill, linux_nat_mourn_inferior): Call
linux_nat_forget_process.
(linux_nat_set_new_fork, linux_nat_set_forget_process)
(linux_nat_forget_process): New functions.
* linux-nat.h (linux_nat_iterate_watchpoint_lwps_ftype): Delete
type.
(linux_nat_iterate_watchpoint_lwps): Delete declaration.
(linux_nat_new_fork_ftype, linux_nat_forget_process_ftype): New
types.
(linux_nat_set_new_fork, linux_nat_set_forget_process)
(linux_nat_forget_process): New declarations.
* amd64fbsd-nat.c (super_mourn_inferior): New global.
(amd64fbsd_mourn_inferior): New function.
(_initialize_amd64fbsd_nat): Override to_mourn_inferior.
* windows-nat.c (windows_detach): Call i386_cleanup_dregs.
Two modifications:
1. The addition of 2013 to the copyright year range for every file;
2. The use of a single year range, instead of potentially multiple
year ranges, as approved by the FSF.
(amd64bsd_target): New prototype.
* amd64bsd-nat.c: Include "target.h" and "inf-ptrace.h".
(amd64bsd_target): New function.
(amd64bsd_fetch_inferior_registers): Rename from
fetch_inferior_registers. Make static.
(amd64bsd_store_inferior_registers): Rename from
store_inferior_registers. Make static.
* amd64fbsd-nat.c: Include "target.h" and "fbsd-nat.h".
(_initialize_amd64fbsd_nat): Construct and add target vector.
* amd64nbsd-nat.o: Include "target.h".
(_initialize_amd64nbsd_nat): Construct and add target vector.
* amd64obsd-nat.c: Include "target.h".
(_initialize_amd64obsd_nat): Construct and add target vector.
* config/i386/nm-fbsd64.h (CHILD_PID_TO_EXEC_FILE): Remove define.
* config/i386/fbsd64.mh (NATDEPFILES): Remove infptrace.o,
inftarg.o and fbsd-proc.o. Add inf-child.o, inf-ptrace.o and
fbsd-nat.o.
* config/i386/nbsd64.mh, config/i386/obsd64.mh (NATDEPFILES):
Remove infptrace.o and inftarg.o. Add inf-child.o and
inf-ptrace.o.
* Makefile.in (amd64bsd-nat.o, amd64fbsd-nat.o, amd64nbsd-nat.o)
(amd64obsd-nat.o): Update dependencies.
(enum amd64_regnum): New.
(X86_64_RAX_REGNUM, X86_64_RDX_REGNUM, X86_64_RDI_REGNUM)
(X86_64_RBP_REGNUM, X86_64_RSP_REGNUM, X86_64_RIP_REGNUM)
(X86_64_EFLAGS_REGNUM, X86_64_ST0_REGNUM, X86_64_XMM0_REGNUM)
(X86_64_XMM1_REGNUM): Removed.
(AMD64_NUM_GREGS): Renamed from X86_64_NUM_GREGS.
(amd64_init_abi, amd64_supply_fxsave, amd64_fill_fxsave): Adjust
prototypes for renamed functions.
* x86-64-tdep.c: Fix typo.
(amd64_dwarf_regmap): Use constants from `enum amd64_regnum' for
register numbers.
(amd64_return_value, amd64_push_arguments, amd64_push_dummy_call):
Use constants from `enum amd64_regnum' for register numbers.
(AMD64_NUM_SAVED_REGS): Adjust for renamed macros.
(amd64_analyze_prologue, amd64_frame_cache,
amd64_sigtramp_frame_cache): Use constants from `enum
amd64_regnum' for register numbers.
(amd64_supply_fpregset): Adjust for renamed functions.
(amd64_init_abi): Rename from x86_64_init_abi. Use constants from
`enum amd64_regnum' for register numbers.
(I387_ST0_REGNUM): Use constant from `enum amd64_regnum'.
(amd64_supply_fxsave): Rename from x86_64_supply_fxsave.
(amd64_fill_fxsave): Rename fro x86_64_fill_fxsave.
* x86-64-linux-tdep.c (amd64_linux_supply_gregset)
(amd64_linux_fill_gregset): Adjust for renamed macros.
(fetch_core_registers): Adjust for renamed functions.
(amd64_linux_init_abi): Adjust for renamed functions.
* x86-64-linux-nat.c (supply_gregset, fill_gregset): Adjust for
renamed functions.
* amd64-nat.c: Adjust for renamed macros.
* amd64bsd-nat.c (fetch_inferior_registers)
(store_inferior_registers): Use constants from `enum amd64_regnum'
for register numbers. Adjust for renamed variables.
* amd64fbsd-nat.c (supply_gregset, fill_gregset): Adjust for
renamed variables.
(_initialize_amd64fbsd_nat): Use constants from `enum
amd64_regnum' for register numbers.
* amd64fbsd-tdep.c (amd64fbsd_sigcontext_addr): Use constants from
`enum amd64_regnum' for register numbers.
(amd64fbsd_init_abi): Adjust for renamed functions.
* amd64nbsd-tdep.c (amd64nbsd_sigcontext_addr): Use constants from
`enum amd64_regnum' for register numbers.
(amd64nbsd_init_abi): Adjust for renamed functions.
(_initialize_amd64nbsd_ndep): Adjust for renamed macros.
* amd64obsd-tdep.c (amd64obsd_sigcontext_addr): Use constants from
`enum amd64_regnum' for register numbers.
(amd64obsd_init_abi): Adjust for renamed functions.
(_initialize_amd64obsd_ndep): Adjust for renamed macros.
_initialize_am64fbsd_nat.
* gdbarch.sh (DEPRECATED_REG_STRUCT_HAS_ADDR): Add comment.
(stabs_argument_has_addr): New architecture method.
* arch-utils.h (default_stabs_argument_has_addr): New prototype.
* arch-utils.c: Include "buildsym.h".
(default_stabs_argument_has_addr): New function.
* stabsread.c (define_symbol): Use stabs_argument_has_addr
instead of DEPRECATED_REG_STRUCT_HAS_ADDR.
* amd64-nat.c: New file.
* amd64fbsd-nat.c: Include "amd64-nat.h".
(REG_ADDR, GETREGS_SUPPLIES): Remove macros.
(amd64fbsd32_r_reg_offset): New variable.
(supply_gregset): Simply call amd64_supply_native_gregset.
(fill_gregset): Rename `regno' to `regnum'. Simply call
amd64_collect_native_gregset.
(fill_fpregset): Rename `regno' to `regnum'.
(fetch_inferior_registers): Rename `regno' to `regnum'. Replace
usage of GETREGS_SUPPLIES with amd64_native_gregset_supplies_p.
Use `struct reg' and `struct fpreg' instead of `gregset_t' and
`fpregset_t'. Call amd64_supply_native_gregset instead of
supply_gregset. Call x86_64_supply_fxsave instead of
supply_fpregset.
(store_inferior_registers): Rename `regno' to `regnum'. Replace
usage of GETREGS_SUPPLIES with amd64_native_gregset_supplies_p.
Use `struct reg' and `struct fpreg' instead of `gregset_t' and
`fpregset_t'. Call amd64_collect_native_gregset instead of
fill_gregset. Call x86_64_collect_fxsave instead of
fill_fpregset.
(_initialize_am64fbsd_nat): Initialize
amd64_native_gregset32_reg_offset and
amd64_native_gregset64_reg_offset.
* config/i386/fbsd64.mh (NATDEPFILES): Add amd64-nat.o.
* configure.tgt: Add x86_64-*-freebsd*.
* Makefile.in (amd64fbsd-nat.o, amd64fbsd-tdep.o): New targets.
* amd64fbsd-nat.c: New file.
* amd64fbsd-tdep.c: New file.
* config/i386/nm-fbsd64.h: New file.
* config/i386/fbsd64.mh: New file.
* config/i386/fbsd64.mt: New file.