binutils-gdb/gdb/ppc-linux-nat.c

3213 lines
100 KiB
C
Raw Normal View History

/* PPC GNU/Linux native support.
Copyright (C) 1988-2020 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "frame.h"
#include "inferior.h"
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
#include "gdbthread.h"
#include "gdbcore.h"
#include "regcache.h"
[PowerPC] Fix access to VSCR in linux targets The 4-byte VSCR register is found inside a 16-byte field in the regset returned by ptrace and in core files. The position of VSCR depends on the endianess of the target, which was previously assumed to be big-endian for the purpose of getting VSCR. This patch removes this assumption to fix access to VSCR in little-endian mode. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-tdep.h (struct ppc_reg_offsets): Remove vector register offset fields. * ppc-fbsd-tdep.c (ppc32_fbsd_reg_offsets): Remove initializers for vector register offset fields. (ppc64_fbsd_reg_offsets): Likewise. * ppc-nbsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-nat.c (_initialize_ppcobsd_nat): Remove assignment to vector register offset fields. * rs6000-aix-tdep.c (rs6000_aix32_reg_offsets): Remove initializers for vector register offset fields. (rs6000_aix64_reg_offsets): Likewise. * rs6000-tdep.c (ppc_vrreg_offset): Remove. (ppc_supply_vrregset): Remove. (ppc_collect_vrregset): Remove. * ppc-linux-tdep.c (ppc_linux_collect_vrregset): New function. (ppc_linux_vrregset) : New function. (ppc32_le_linux_vrregmap, ppc32_be_linux_vrregmap) (ppc32_le_linux_vrregset, ppc32_be_linux_vrregset): New globals. (ppc32_linux_vrregset): Remove. (ppc_linux_iterate_over_regset_sections): Call ppc_linux_vrregset and use result instead of ppc32_linux_vrregset. (ppc32_linux_reg_offsets): Remove initializers for vector register offset fields. (ppc64_linux_reg_offsets): Likewise. * ppc-linux-tdep.h (ppc_linux_vrregset): New declaration. * ppc-linux-nat.c: Include regset.h. (gdb_vrregset_t): Adjust comment to account for little-endian mode. (supply_vrregset, fill_vrregset): Remove. (fetch_altivec_register, store_altivec_register): Remove. (fetch_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to supply registers. (store_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to collect registers. (fetch_register): Call fetch_altivec_registers instead of fetch_altivec_register. (store_register): Call store_altivec_registers instead of store_altivec_register. (fetch_ppc_registers): Call fetch_altivec_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_altivec_registers with -1 for the new regno parameter. gdb/gdbserver/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * linux-ppc-low.c (ppc_fill_vrregset): Add vscr_offset variable. Set vscr_offset to 0 in little-endian mode and 12 in big-endian mode. Call collect_register_by_name with vscr using vscr_offset. Zero-pad vscr and vrsave fields in collector buffer. (ppc_store_vrregset): Add and set vscr_offset variable as in ppc_fill_vrregset. Call supply_register_by_name with vscr using vscr_offset.
2018-05-22 22:09:05 +08:00
#include "regset.h"
* Makefile.in (ALLDEPFILES): Update. (alpha-linux-nat.o, sparc-linux-nat.o): New rules. (amd64-linux-nat.o, arm-linux-nat.o, hppa-linux-nat.o) (i386-linux-nat.o, ia64-linux-nat.o, linux-nat.o, m32r-linux-nat.o) (m68klinux-nat.o, mips-linux-nat.o, ppc-linux-nat.o, s390-nat.o) (sparc64-linux-nat.o): Update dependencies. * alpha-linux-nat.c, sparc-linux-nat.c: New files. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (amd64_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (amd64_linux_child_post_start_inferior): Renamed from child_post_startup_inferior and made static. Call super_post_startup_inferior. (super_post_startup_inferior): New. (_initialize_amd64_linux_nat): Set it. Call linux_target and add_target. * arm-linux-nat.c (arm_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (arm_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (_initialize_arm_linux_nat): Add a prototype. Use linux_target and add_target. * hppa-linux-nat.c (hppa_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (hppa_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (_initialize_hppa_linux_nat): New function. * i386-linux-nat.c (i386_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (i386_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (i386_linux_resume): Renamed from child_resume and made static. (i386_linux_child_post_start_inferior): Renamed from child_post_startup_inferior and made static. Call super_post_startup_inferior. (super_post_startup_inferior): New. (_initialize_i386_linux_nat): New function. * i386-nat.c: Remove LINUX_CHILD_POST_STARTUP_INFERIOR #ifndef. * ia64-linux-nat.c (ia64_linux_xfer_unwind_table): Remove. (super_xfer_partial): New. (ia64_linux_xfer_partial): New function. Use it. (_initialize_ia64_linux_nat): New function. * ia64-tdep.c (getunwind_table): Revert 2005-06-08 change; use target_read_partial and document the problem. * inf-ptrace.c (inf_ptrace_fetch_register): Use CANNOT_FETCH_REGISTER. Fix some comments. (inf_ptrace_store_register): Use CANNOT_STORE_REGISTER. Fix some comments. * linux-nat.c: Include "inf-ptrace.h" and "auxv.h". (linux_ops, super_xfer_partial): New variables. (linux_child_post_startup_inferior): Make static. (child_post_startup_inferior): Delete. (linux_nat_attach, linux_nat_detach, resume_callback) (linux_nat_resume, linux_nat_wait, linux_nat_create_inferior) (linux_nat_mourn_inferior): Use linux_ops instead of deprecated_child_ops. (child_wait): Do not depend on CHILD_WAIT. (linux_nat_xfer_memory): Remove, replace by ... (linux_nat_xfer_partial): ... this. Use linux_ops->to_xfer_partial instead of linux_proc_xfer_memory and child_xfer_memory. (linux_nat_fetch_registers, linux_nat_store_registers) (linux_nat_child_post_startup_inferior): New functions. (init_linux_nat_ops): Use the new functions. (linux_proc_xfer_memory): Remove, replace by ... (linux_proc_xfer_partial): ... this. Make static. (linux_xfer_partial, linux_register_u_offset, linux_target): New functions. (_initialize_linux_nat): Do not modify deprecated_child_ops. * linux-nat.h (linux_proc_xfer_memory): Remove prototype. (struct mem_attrib, struct target_ops): Remove forward declarations. (linux_child_post_startup_inferior): Remove prototype. (linux_target): Add prototype. * linux-thread-db.c (thread_db_xfer_memory): Remove, replace by ... (thread_db_xfer_partial): ... this. (init_thread_db_ops): Set to_xfer_partial instead of deprecated_xfer_memory. * m32r-linux-nat.c (m32r_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (m32r_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (_initialize_m32r_linux_nat): New function. * m68klinux-nat.c (m68k_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (m68k_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (old_fetch_inferior_registers, old_store_inferior_registers): Made static. (_initialize_m68k_linux_nat): Use linux_target and add_target. * mips-linux-nat.c (_initialize_mips_linux_nat): New function. * ppc-linux-nat.c (ppc_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (ppc_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (_initialize_ppc_linux_nat): New function. * s390-nat.c (s390_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (s390_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (_initialize_s390_nat): New function. * sparc64-linux-nat.c (_initialize_sparc64_linux_nat): Use linux_target and add_target. * config/nm-linux.h: Don't include "auxv.h". (struct target_waitstatus, child_wait, CHILD_WAIT) (CHILD_PID_TO_EXEC_FILE, CHILD_INSERT_FORK_CATCHPOINT) (CHILD_INSERT_VFORK_CATCHPOINT, CHILD_INSERT_EXEC_CATCHPOINT) (CHILD_POST_STARTUP_INFERIOR, CHILD_POST_ATTACH, CHILD_FOLLOW_FORK) (DEPRECATED_KILL_INFERIOR, NATIVE_XFER_AUXV): Delete. * config/alpha/alpha-linux.mh (NATDEPFILES): Replace infptrace.o and inftarg.o with inf-ptrace.o and alpha-linux-nat.o. * config/sparc/linux.mh (NATDEPFILES): Replace infptrace.o and inftarg.o with sparc-linux-nat.o. * config/sparc/linux64.mh (NATDEPFILES): Remove infptrace.o and inftarg.o. * config/arm/linux.mh (NATDEPFILES): Replace infptrace.o and inftarg.o with inf-ptrace.o. * config/i386/linux.mh (NATDEPFILES): Likewise. * config/i386/linux64.mh (NATDEPFILES): Likewise. * config/ia64/linux.mh (NATDEPFILES): Likewise. * config/m32r/linux.mh (NATDEPFILES): Likewise. * config/m68k/linux.mh (NATDEPFILES): Likewise. * config/mips/linux.mh (NATDEPFILES): Likewise. * config/pa/linux.mh (NATDEPFILES): Likewise. * config/powerpc/linux.mh (NATDEPFILES): Likewise. * config/powerpc/ppc64-linux.mh (NATDEPFILES): Likewise. * config/s390/s390.mh (NATDEPFILES): Likewise. * config/i386/nm-linux.h (DEPRECATED_CHILD_RESUME): Don't define. (LINUX_CHILD_POST_STARTUP_INFERIOR): Don't define. * config/i386/nm-linux64.h (LINUX_CHILD_POST_STARTUP_INFERIOR): Don't define. * config/ia64/nm-linux.h: Don't include "target.h". (NATIVE_XFER_UNWIND_TABLE, ia64_linux_xfer_unwind_table): Remove. * config/djgpp/fnchange.lst: Add alpha-linux-tdep.c, alpha-linux-nat.c, sparc-linux-tdep.c, and sparc-linux-nat.c.
2005-09-11 02:11:14 +08:00
#include "target.h"
#include "linux-nat.h"
#include <sys/types.h>
#include <signal.h>
#include <sys/user.h>
#include <sys/ioctl.h>
[PowerPC] Add support for PPR and DSCR This patch adds gdb support for the Program Priorty Register and the Data Stream Control Register, for the powerpc linux native and core file targets, and for the powerpc linux server stub. gdb/ChangeLog: 2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * arch/ppc-linux-tdesc.h (tdesc_powerpc_isa205_ppr_dscr_vsx32l) (tdesc_powerpc_isa205_ppr_dscr_vsx64l): Declare. * arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_PPRREGSET) (PPC_LINUX_SIZEOF_DSCRREGSET): Define. (struct ppc_linux_features) <ppr_dscr>: New field. (ppc_linux_no_features): Add initializer for ppr_dscr field. * arch/ppc-linux-common.c (ppc_linux_match_description): Return new tdescs. * nat/ppc-linux.h (PPC_FEATURE2_DSCR, NT_PPC_PPR, NT_PPC_DSCR): Define if not already defined. * features/Makefile (WHICH): Add rs6000/powerpc-isa205-ppr-dscr-vsx32l and rs6000/powerpc-isa205-ppr-dscr-vsx64l. (XMLTOC): Add rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml and rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml. * features/rs6000/power-dscr.xml: New file. * features/rs6000/power-ppr.xml: New file. * features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml: New file. * features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml: New file. * features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.c: Generate. * features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.c: Generate. * regformats/rs6000/powerpc-isa205-ppr-dscr-vsx32l.dat: Generate. * regformats/rs6000/powerpc-isa205-ppr-dscr-vsx64l.dat: Generate. * ppc-linux-nat.c: Include <sys/uio.h>. (fetch_regset, store_regset, check_regset): New functions. (fetch_register, fetch_ppc_registers): Call fetch_regset with DSCR and PPR regsets. (store_register, store_ppc_registers): Call store_regset with DSCR and PPR regsets. (ppc_linux_get_hwcap2): New function. (ppc_linux_nat_target::read_description): Call ppc_linux_get_hwcap2 and check_regset, set ppr_dscr field in the features struct if needed. * ppc-linux-tdep.c: Include features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.c and features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.c. (ppc32_regmap_ppr, ppc32_regmap_dscr, ppc32_linux_pprregset) (ppc32_linux_dscrregset): New globals. (ppc_linux_iterate_over_regset_sections): Call back with the ppr and dscr regsets. (ppc_linux_core_read_description): Check if the ppr and dscr sections are present and set ppr_dscr in the features struct. (_initialize_ppc_linux_tdep): Call initialize_tdesc_powerpc_isa205_ppr_dscr_vsx32l and initialize_tdesc_powerpc_isa205_ppr_dscr_vsx64l. * ppc-linux-tdep.h (ppc32_linux_pprregset) (ppc32_linux_dscrregset): Declare. * ppc-tdep.h (struct gdbarch_tdep) <ppc_ppr_regnum>: New field. <ppc_dscr_regnum>: New field. (enum) <PPC_PPR_REGNUM, PPC_DSCR_REGNUM>: New enum values. * rs6000-tdep.c (rs6000_gdbarch_init): Look for and validate ppr and dscr features. (ppc_process_record_op31): Record changes to PPR and DSCR. gdb/gdbserver/ChangeLog: 2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * configure.srv (ipa_ppc_linux_regobj): Add powerpc-isa205-ppr-dscr-vsx32l-ipa.o and powerpc-isa205-ppr-dscr-vsx64l-ipa.o. (powerpc*-*-linux*): Add powerpc-isa205-ppr-dscr-vsx32l.o and powerpc-isa205-ppr-dscr-vsx64l.o to srv_regobj, add rs6000/power-dscr.xml, rs6000/power-ppr.xml, rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml and rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml to srv_xmlfiles. * linux-ppc-tdesc-init.h (enum ppc_linux_tdesc) <PPC_TDESC_ISA205_PPR_DSCR_VSX>: New enum value. (init_registers_powerpc_isa205_ppr_dscr_vsx32l) (init_registers_powerpc_isa205_ppr_dscr_vsx64l): Declare. * linux-ppc-low.c: Include "elf/common.h" and <sys/uio.h>. (ppc_hwcap): Add comment. (ppc_hwcap2): New global. (ppc_check_regset, ppc_fill_pprregset, ppc_store_pprregset) (ppc_fill_dscrregset, ppc_store_dscrregset): New functions. (ppc_regsets): Add entries for the DSCR and PPR regsets. (ppc_arch_setup): Get AT_HWCAP2. Set ppr_dscr in features struct when needed. Set sizes for the the DSCR and PPR regsets. (ppc_get_ipa_tdesc_idx): Return PPC_TDESC_ISA205_PPR_DSCR_VSX. (initialize_low_arch): Call init_registers_powerpc_isa205_ppr_dscr_vsx32l and init_registers_powerpc_isa205_ppr_dscr_vsx64l. * linux-ppc-ipa.c (get_ipa_tdesc): Handle PPC_TDESC_ISA205_PPR_DSCR_VSX. (initialize_low_tracepoint): Call init_registers_powerpc_isa205_ppr_dscr_vsx32l and init_registers_powerpc_isa205_ppr_dscr_vsx64l. gdb/testsuite/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.arch/powerpc-ppr-dscr.c: New file. * gdb.arch/powerpc-ppr-dscr.exp: New file. gdb/doc/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.texinfo (PowerPC Features): Describe new features "org.gnu.gdb.power.ppr" and "org.gnu.gdb.power.dscr".
2018-10-26 20:37:54 +08:00
#include <sys/uio.h>
Rename common to gdbsupport This is the next patch in the ongoing series to move gdbsever to the top level. This patch just renames the "common" directory. The idea is to do this move in two parts: first rename the directory (this patch), then move the directory to the top. This approach makes the patches a bit more tractable. I chose the name "gdbsupport" for the directory. However, as this patch was largely written by sed, we could pick a new name without too much difficulty. Tested by the buildbot. gdb/ChangeLog 2019-07-09 Tom Tromey <tom@tromey.com> * contrib/ari/gdb_ari.sh: Change common to gdbsupport. * configure: Rebuild. * configure.ac: Change common to gdbsupport. * gdbsupport: Rename from common. * acinclude.m4: Change common to gdbsupport. * Makefile.in (CONFIG_SRC_SUBDIR, COMMON_SFILES) (HFILES_NO_SRCDIR, stamp-version, ALLDEPFILES): Change common to gdbsupport. * aarch64-tdep.c, ada-lang.c, ada-lang.h, agent.c, alloc.c, amd64-darwin-tdep.c, amd64-dicos-tdep.c, amd64-fbsd-nat.c, amd64-fbsd-tdep.c, amd64-linux-nat.c, amd64-linux-tdep.c, amd64-nbsd-tdep.c, amd64-obsd-tdep.c, amd64-sol2-tdep.c, amd64-tdep.c, amd64-windows-tdep.c, arch-utils.c, arch/aarch64-insn.c, arch/aarch64.c, arch/aarch64.h, arch/amd64.c, arch/amd64.h, arch/arm-get-next-pcs.c, arch/arm-linux.c, arch/arm.c, arch/i386.c, arch/i386.h, arch/ppc-linux-common.c, arch/riscv.c, arch/riscv.h, arch/tic6x.c, arm-tdep.c, auto-load.c, auxv.c, ax-gdb.c, ax-general.c, ax.h, breakpoint.c, breakpoint.h, btrace.c, btrace.h, build-id.c, build-id.h, c-lang.h, charset.c, charset.h, cli/cli-cmds.c, cli/cli-cmds.h, cli/cli-decode.c, cli/cli-dump.c, cli/cli-option.h, cli/cli-script.c, coff-pe-read.c, command.h, compile/compile-c-support.c, compile/compile-c.h, compile/compile-cplus-symbols.c, compile/compile-cplus-types.c, compile/compile-cplus.h, compile/compile-loc2c.c, compile/compile.c, completer.c, completer.h, contrib/ari/gdb_ari.sh, corefile.c, corelow.c, cp-support.c, cp-support.h, cp-valprint.c, csky-tdep.c, ctf.c, darwin-nat.c, debug.c, defs.h, disasm-selftests.c, disasm.c, disasm.h, dtrace-probe.c, dwarf-index-cache.c, dwarf-index-cache.h, dwarf-index-write.c, dwarf2-frame.c, dwarf2expr.c, dwarf2loc.c, dwarf2read.c, event-loop.c, event-top.c, exceptions.c, exec.c, extension.h, fbsd-nat.c, features/aarch64-core.c, features/aarch64-fpu.c, features/aarch64-pauth.c, features/aarch64-sve.c, features/i386/32bit-avx.c, features/i386/32bit-avx512.c, features/i386/32bit-core.c, features/i386/32bit-linux.c, features/i386/32bit-mpx.c, features/i386/32bit-pkeys.c, features/i386/32bit-segments.c, features/i386/32bit-sse.c, features/i386/64bit-avx.c, features/i386/64bit-avx512.c, features/i386/64bit-core.c, features/i386/64bit-linux.c, features/i386/64bit-mpx.c, features/i386/64bit-pkeys.c, features/i386/64bit-segments.c, features/i386/64bit-sse.c, features/i386/x32-core.c, features/riscv/32bit-cpu.c, features/riscv/32bit-csr.c, features/riscv/32bit-fpu.c, features/riscv/64bit-cpu.c, features/riscv/64bit-csr.c, features/riscv/64bit-fpu.c, features/tic6x-c6xp.c, features/tic6x-core.c, features/tic6x-gp.c, filename-seen-cache.h, findcmd.c, findvar.c, fork-child.c, gcore.c, gdb_bfd.c, gdb_bfd.h, gdb_proc_service.h, gdb_regex.c, gdb_select.h, gdb_usleep.c, gdbarch-selftests.c, gdbthread.h, gdbtypes.h, gnu-nat.c, go32-nat.c, guile/guile.c, guile/scm-ports.c, guile/scm-safe-call.c, guile/scm-type.c, i386-fbsd-nat.c, i386-fbsd-tdep.c, i386-go32-tdep.c, i386-linux-nat.c, i386-linux-tdep.c, i386-tdep.c, i387-tdep.c, ia64-libunwind-tdep.c, ia64-linux-nat.c, inf-child.c, inf-ptrace.c, infcall.c, infcall.h, infcmd.c, inferior-iter.h, inferior.c, inferior.h, inflow.c, inflow.h, infrun.c, infrun.h, inline-frame.c, language.h, linespec.c, linux-fork.c, linux-nat.c, linux-tdep.c, linux-thread-db.c, location.c, machoread.c, macrotab.h, main.c, maint.c, maint.h, memattr.c, memrange.h, mi/mi-cmd-break.h, mi/mi-cmd-env.c, mi/mi-cmd-stack.c, mi/mi-cmd-var.c, mi/mi-interp.c, mi/mi-main.c, mi/mi-parse.h, minsyms.c, mips-linux-tdep.c, namespace.h, nat/aarch64-linux-hw-point.c, nat/aarch64-linux-hw-point.h, nat/aarch64-linux.c, nat/aarch64-sve-linux-ptrace.c, nat/amd64-linux-siginfo.c, nat/fork-inferior.c, nat/linux-btrace.c, nat/linux-btrace.h, nat/linux-namespaces.c, nat/linux-nat.h, nat/linux-osdata.c, nat/linux-personality.c, nat/linux-procfs.c, nat/linux-ptrace.c, nat/linux-ptrace.h, nat/linux-waitpid.c, nat/mips-linux-watch.c, nat/mips-linux-watch.h, nat/ppc-linux.c, nat/x86-dregs.c, nat/x86-dregs.h, nat/x86-linux-dregs.c, nat/x86-linux.c, nto-procfs.c, nto-tdep.c, objfile-flags.h, objfiles.c, objfiles.h, obsd-nat.c, observable.h, osdata.c, p-valprint.c, parse.c, parser-defs.h, ppc-linux-nat.c, printcmd.c, probe.c, proc-api.c, procfs.c, producer.c, progspace.h, psymtab.h, python/py-framefilter.c, python/py-inferior.c, python/py-ref.h, python/py-type.c, python/python.c, record-btrace.c, record-full.c, record.c, record.h, regcache-dump.c, regcache.c, regcache.h, remote-fileio.c, remote-fileio.h, remote-sim.c, remote.c, riscv-tdep.c, rs6000-aix-tdep.c, rust-exp.y, s12z-tdep.c, selftest-arch.c, ser-base.c, ser-event.c, ser-pipe.c, ser-tcp.c, ser-unix.c, skip.c, solib-aix.c, solib-target.c, solib.c, source-cache.c, source.c, source.h, sparc-nat.c, spu-linux-nat.c, stack.c, stap-probe.c, symfile-add-flags.h, symfile.c, symfile.h, symtab.c, symtab.h, target-descriptions.c, target-descriptions.h, target-memory.c, target.c, target.h, target/waitstatus.c, target/waitstatus.h, thread-iter.h, thread.c, tilegx-tdep.c, top.c, top.h, tracefile-tfile.c, tracefile.c, tracepoint.c, tracepoint.h, tui/tui-io.c, ui-file.c, ui-out.h, unittests/array-view-selftests.c, unittests/child-path-selftests.c, unittests/cli-utils-selftests.c, unittests/common-utils-selftests.c, unittests/copy_bitwise-selftests.c, unittests/environ-selftests.c, unittests/format_pieces-selftests.c, unittests/function-view-selftests.c, unittests/lookup_name_info-selftests.c, unittests/memory-map-selftests.c, unittests/memrange-selftests.c, unittests/mkdir-recursive-selftests.c, unittests/observable-selftests.c, unittests/offset-type-selftests.c, unittests/optional-selftests.c, unittests/parse-connection-spec-selftests.c, unittests/ptid-selftests.c, unittests/rsp-low-selftests.c, unittests/scoped_fd-selftests.c, unittests/scoped_mmap-selftests.c, unittests/scoped_restore-selftests.c, unittests/string_view-selftests.c, unittests/style-selftests.c, unittests/tracepoint-selftests.c, unittests/unpack-selftests.c, unittests/utils-selftests.c, unittests/xml-utils-selftests.c, utils.c, utils.h, valarith.c, valops.c, valprint.c, value.c, value.h, varobj.c, varobj.h, windows-nat.c, x86-linux-nat.c, xml-support.c, xml-support.h, xml-tdesc.h, xstormy16-tdep.c, xtensa-linux-nat.c, dwarf2read.h: Change common to gdbsupport. gdb/gdbserver/ChangeLog 2019-07-09 Tom Tromey <tom@tromey.com> * configure: Rebuild. * configure.ac: Change common to gdbsupport. * acinclude.m4: Change common to gdbsupport. * Makefile.in (SFILES, OBS, GDBREPLAY_OBS, IPA_OBJS) (version-generated.c, gdbsupport/%-ipa.o, gdbsupport/%.o): Change common to gdbsupport. * ax.c, event-loop.c, fork-child.c, gdb_proc_service.h, gdbreplay.c, gdbthread.h, hostio-errno.c, hostio.c, i387-fp.c, inferiors.c, inferiors.h, linux-aarch64-tdesc-selftest.c, linux-amd64-ipa.c, linux-i386-ipa.c, linux-low.c, linux-tic6x-low.c, linux-x86-low.c, linux-x86-tdesc-selftest.c, linux-x86-tdesc.c, lynx-i386-low.c, lynx-low.c, mem-break.h, nto-x86-low.c, regcache.c, regcache.h, remote-utils.c, server.c, server.h, spu-low.c, symbol.c, target.h, tdesc.c, tdesc.h, thread-db.c, tracepoint.c, win32-i386-low.c, win32-low.c: Change common to gdbsupport.
2019-05-06 10:29:24 +08:00
#include "gdbsupport/gdb_wait.h"
#include <fcntl.h>
#include <sys/procfs.h>
#include "nat/gdb_ptrace.h"
#include "nat/linux-ptrace.h"
Use ptid from regcache in almost all remaining nat files This patch contains almost all of the remaining changes needed to make to_fetch_registers/to_store_registers/to_prepare_to_store independent of inferior_ptid. It contains only some "trivial" changes, the more complicated ones are in separate patches. gdb/ChangeLog: * i386-linux-nat.c (fetch_register, store_register, i386_linux_fetch_inferior_registers, i386_linux_store_inferior_registers): Use ptid from regcache. * ia64-linux-nat.c (ia64_linux_fetch_register, ia64_linux_store_register): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register, inf_ptrace_store_register): Likewise. * m32r-linux-nat.c (m32r_linux_fetch_inferior_registers, m32r_linux_store_inferior_registers): Likewise. * m68k-bsd-nat.c (m68kbsd_fetch_inferior_registers, m68kbsd_store_inferior_registers): Likewise. * m68k-linux-nat.c (fetch_register, store_register, m68k_linux_fetch_inferior_registers, m68k_linux_store_inferior_registers): Likewise. * m88k-bsd-nat.c (m88kbsd_fetch_inferior_registers, m88kbsd_store_inferior_registers): Likewise. * mips-fbsd-nat.c (mips_fbsd_fetch_inferior_registers, mips_fbsd_store_inferior_registers): Likewise. * mips-linux-nat.c (mips64_linux_regsets_fetch_registers, mips64_linux_regsets_store_registers): Likewise. * mips-nbsd-nat.c (mipsnbsd_fetch_inferior_registers, mipsnbsd_store_inferior_registers): Likewise. * mips-obsd-nat.c (mips64obsd_fetch_inferior_registers, mips64obsd_store_inferior_registers): Likewise. * nto-procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * ppc-fbsd-nat.c (ppcfbsd_fetch_inferior_registers, ppcfbsd_store_inferior_registers): Likewise. * ppc-linux-nat.c (ppc_linux_fetch_inferior_registers, ppc_linux_store_inferior_registers): Likewise. * ppc-nbsd-nat.c (ppcnbsd_fetch_inferior_registers, ppcnbsd_store_inferior_registers): Likewise. * ppc-obsd-nat.c (ppcobsd_fetch_registers, ppcobsd_store_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * ravenscar-thread.c (ravenscar_fetch_registers, ravenscar_store_registers, ravenscar_prepare_to_store): Likewise. * record-btrace.c (record_btrace_fetch_registers, record_btrace_store_registers, record_btrace_prepare_to_store): Likewise. * remote-sim.c (gdbsim_fetch_register, gdbsim_store_register): Lookup inferior using ptid from regcache, instead of current_inferior. * remote.c (remote_fetch_registers, remote_store_registers): Use ptid from regcache. * rs6000-nat.c (fetch_register, store_register): Likewise. * s390-linux-nat.c (s390_linux_fetch_inferior_registers, s390_linux_store_inferior_registers): Likewise. * sh-nbsd-nat.c (shnbsd_fetch_inferior_registers, shnbsd_store_inferior_registers): Likewise. * sol-thread.c (sol_thread_fetch_registers, sol_thread_store_registers): Likewise. * sparc-nat.c (sparc_fetch_inferior_registers, sparc_store_inferior_registers): Likewise. * tilegx-linux-nat.c (fetch_inferior_registers, store_inferior_registers): Likewise. * vax-bsd-nat.c (vaxbsd_fetch_inferior_registers, vaxbsd_store_inferior_registers): Likewise. * xtensa-linux-nat.c (fetch_gregs, store_gregs, fetch_xtregs, store_xtregs): Likewise.
2017-03-21 05:37:36 +08:00
#include "inf-ptrace.h"
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
#include <algorithm>
#include <unordered_map>
#include <list>
/* Prototypes for supply_gregset etc. */
#include "gregset.h"
#include "ppc-tdep.h"
ChangeLog: * Makefile.in (ppc_linux_tdep_h): New macro. (powerpc_32l_c, powerpc_altivec32_c, powerpc_altivec32l_c): Likewise. (powerpc_64l_c, powerpc_altivec64_c, powerpc_altivec64l_c): Likewise. (powerpc_e500l_c): Likewise. (ppc-linux-nat.o): Update dependencies. (ppc-linux-tdep.o): Update dependencies. (rs6000-tdep.o): Update dependencies. * ppc-tdep.h (ppc_linux_memory_remove_breakpoint): Remove. (ppc_linux_svr4_fetch_link_map_offsets): Remove. (ppc_linux_gregset, ppc_linux_fpregset): Move to ppc-linux-tdep.h (ppc_supply_reg, ppc_collect_reg): Add prototypes. (tdesc_powerpc_e500): Remove. * rs6000.c: Include "features/rs6000/powerpc-altivec32.c" and "features/rs6000/powerpc-altivec64.c". (ppc_supply_reg, ppc_collect_reg): Make global. (variants): Use tdesc_powerpc_32 for "powerpc" and tdesc_powerpc_altivec64 for "powerpc64". (_initialize_rs6000_tdep): Initialize AltiVec descriptions. * ppc-linux-tdep.h: New file. * ppc-linux-tdep.c: Include "ppc-linux-tdep.c". Include "features/rs6000/powerpc-32l.c". Include "features/rs6000/powerpc-altivec32l.c". Include "features/rs6000/powerpc-64l.c". Include "features/rs6000/powerpc-altivec64l.c". Include "features/rs6000/powerpc-e500l.c". (ppc_linux_supply_gregset): New function. (ppc_linux_collect_gregset): Handle orig_r3 and trap registers. (ppc32_linux_gregset): Use ppc_linux_supply_gregset. (ppc64_linux_gregset): Likewise. (ppc_linux_sigtramp_cache): Handle orig_r3 and trap registers. (ppc_linux_trap_reg_p): New function. (ppc_linux_write_pc): New function. (ppc_linux_core_read_description): New function. (ppc_linux_init_abi): Install ppc_linux_write_pc and ppc_linux_core_read_description. Install orig_r3 and trap registers if present in the target description. (_initialize_ppc_linux_tdep): Initialize Linux target descriptions. * ppc-linux-nat.c: Include "ppc-linux-tdep.h". (PT_ORIG_R3, PT_TRAP): Define if necessary. (ppc_register_u_addr): Handle orig_r3 and trap registers. (fetch_ppc_registers): Likewise. (store_ppc_registers): Likewise. (store_register): Likewise. (ppc_linux_read_description): Check whether AltiVec is supported. Check whether inferior is 32-bit or 64-bit. Return the appropriate Linux target description. * features/Makefile (WHICH): Use rs6000/powerpc-32l and rs6000/powerpc-altivec32l instead of rs6000/powerpc-32. Use rs6000/powerpc-64l and rs6000/powerpc-altivec64l instead of rs6000/powerpc-64. Use rs6000/powerpc-e500l instead of rs6000/powerpc-e500. Update -expedite variables accordingly. * features/rs6000/power-spe.xml: Use regnum 73 for "acc". * features/rs6000/powerpc-32.xml: Do not include power-altivec.xml. * features/rs6000/powerpc-64.xml: Do not include power-altivec.xml. * features/rs6000/powerpc-e500.c: Regenerate. * features/rs6000/powerpc-32.c: Regenerate. * features/rs6000/powerpc-64.c: Regenerate. * features/rs6000/power-linux.xml: New file. * features/rs6000/power64-linux.xml: New file. * features/rs6000/powerpc-32l.xml: New file. * features/rs6000/powerpc-altivec32l.xml: New file. * features/rs6000/powerpc-64l.xml: New file. * features/rs6000/powerpc-altivec64l.xml: New file. * features/rs6000/powerpc-e500l.xml: New file. * features/rs6000/powerpc-32l.c: New (generated) file. * features/rs6000/powerpc-altivec32l.c: New (generated) file. * features/rs6000/powerpc-64l.c: New (generated) file. * features/rs6000/powerpc-altivec64l.c: New (generated) file. * features/rs6000/powerpc-e500l.xml: New (generated) file. * regformats/reg-ppc.dat: Remove. * regformats/reg-ppc64.dat: Remove. * regformats/rs6000/powerpc-32.dat: Remove. * regformats/rs6000/powerpc-64.dat: Remove. * regformats/rs6000/powerpc-e500.dat: Remove. * regformats/rs6000/powerpc-32l.dat: New (generated) file. * regformats/rs6000/powerpc-altivec32l.dat: New (generated) file. * regformats/rs6000/powerpc-64l.dat: New (generated) file. * regformats/rs6000/powerpc-altivec64l.dat: New (generated) file. * regformats/rs6000/powerpc-e500l.dat: New (generated) file. gdbserver/ChangeLog: * configure.srv (powerpc*-*-linux*): Set srv_regobj to powerpc-32l.o, powerpc-altivec32l.o, powerpc-e500l.o, powerpc-64l.o, and powerpc-altivec64l.o. Remove rs6000/powerpc-32.xml, rs6000/powerpc-64.xml, and rs6000/powerpc-e500.xml; add rs6000/powerpc-32l.xml, rs6000/powerpc-altivec32l.xml, rs6000/powerpc-e500l.xml, rs6000/powerpc-64l.xml, rs6000/powerpc-altivec64l.xml, rs6000/power-linux.xml, and rs6000/power64-linux.xml to srv_xmlfiles. * Makefile.in (reg-ppc.o, reg-ppc.c): Remove, replace by ... (powerpc-32l.o, powerpc-32l.c): ... these new rules. (powerpc-32.o, powerpc-32.c): Remove, replace by ... (powerpc-altivec32l.o, powerpc-altivec32l.c): ... these new rules. (powerpc-e500.o, powerpc-e500.c): Remove, replace by ... (powerpc-e500l.o, powerpc-e500l.c): ... these new rules. (reg-ppc64.o, reg-ppc64.c): Remove, replace by ... (powerpc-64l.o, powerpc-64l.c): ... these new rules. (powerpc-64.o, powerpc-64.c): Remove, replace by ... (powerpc-altivec64l.o, powerpc-altivec64l.c): ... these new rules. (clean): Update. * linux-ppc-low.c (init_registers_ppc): Remove, replace by ... (init_registers_powerpc_32l): ... this new prototype. (init_registers_powerpc_32): Remove, replace by ... (init_registers_powerpc_altivec32l): ... this new prototype. (init_registers_powerpc_e500): Remove, replace by ... (init_registers_powerpc_e500l): ... this new prototype. (init_registers_ppc64): Remove, replace by ... (init_registers_powerpc_64l): ... this new prototype. (init_registers_powerpc_64): Remove, replace by ... (init_registers_powerpc_altivec64l): ... this new prototype. (ppc_num_regs): Set to 73. (PT_ORIG_R3, PT_TRAP): Define if necessary. (ppc_regmap, ppc_regmap_e500): Add values for orig_r3 and trap. (ppc_cannot_store_register): Handle orig_r3 and trap. (ppc_arch_setup): Update init_registers_... calls. (ppc_fill_gregset): Handle orig_r3 and trap. * inferiors.c (clear_inferiors): Reset current_inferior.
2008-05-04 01:16:44 +08:00
#include "ppc-linux-tdep.h"
/* Required when using the AUXV. */
#include "elf/common.h"
#include "auxv.h"
[PowerPC] Consolidate linux target description selection Share target description declarations and selection among ppc linux native targets, core files, gdbserver and IPA. To avoid complicated define guards, gdbserver and IPA now have declarations for all descriptions, including 64-bit generated descriptions when compiled in 32-bit mode. These have always been linked into the gdbserver and IPA binaries. Because they might be uninitialized, the selection function checks that the selected description is initialized. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * arch/ppc-linux-common.c: New file. * arch/ppc-linux-common.h: New file. * arch/ppc-linux-tdesc.h: New file. * configure.tgt (powerpc*-*-linux*): Add arch/ppc-linux-common.o. * Makefile.in (ALL_TARGET_OBS): Add arch/ppc-linux-common.o. (HFILES_NO_SRCDIR): Add arch/ppc-linux-common.h and arch/ppc-linux-tdesc.h. * ppc-linux-nat.c: Include arch/ppc-linux-common.h and arch/ppc-linux-tdesc.h. (ppc_linux_nat_target::read_description): Remove target description matching code. Fill a ppc_linux_features struct and call ppc_linux_match_description with it. Move comment about ISA 2.05 to ppc-linux-common.c. * ppc-linux-tdep.c: Include arch/ppc-linux-common.h and arch/ppc-linux-tdesc.h. (ppc_linux_core_read_description): Remove target description matching code. Fill a ppc_linux_features struct and call ppc_linux_match_description with it. * ppc-linux-tdep.h (tdesc_powerpc_32l, tdesc_powerpc_64l) (tdesc_powerpc_altivec32l, tdesc_powerpc_altivec64l) (tdesc_powerpc_cell32l, tdesc_powerpc_cell64l) (tdesc_powerpc_vsx32l, tdesc_powerpc_vsx64l) (tdesc_powerpc_isa205_32l, tdesc_powerpc_isa205_64l) (tdesc_powerpc_isa205_altivec32l, tdesc_powerpc_isa205_altivec64l) (tdesc_powerpc_isa205_vsx32l, tdesc_powerpc_isa205_vsx64l) (tdesc_powerpc_e500l): Remove. gdb/gdbserver/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * configure.srv (srv_tgtobj): Add arch/ppc-linux-common.o. * Makefile.in (SFILES): Add arch/ppc-linux-common.c. * linux-ppc-tdesc.h: Rename to linux-ppc-tdesc-init.h. * linux-ppc-tdesc-init.h (tdesc_powerpc_32l, tdesc_powerpc_64l) (tdesc_powerpc_altivec32l, tdesc_powerpc_altivec64l) (tdesc_powerpc_cell32l, tdesc_powerpc_cell64l) (tdesc_powerpc_vsx32l, tdesc_powerpc_vsx64l) (tdesc_powerpc_isa205_32l, tdesc_powerpc_isa205_64l) (tdesc_powerpc_isa205_altivec32l, tdesc_powerpc_isa205_altivec64l) (tdesc_powerpc_isa205_vsx32l, tdesc_powerpc_isa205_vsx64l) (tdesc_powerpc_e500l): Remove. * linux-ppc-ipa.c: Include arch/ppc-linux-tdesc.h and linux-ppc-tdesc-init.h. Don't include linux-ppc-tdesc.h. * linux-ppc-low.c: Include arch/ppc-linux-common.h, arch/ppc-linux-tdesc.h, and linux-ppc-tdesc-init.h. Don't include linux-ppc-tdesc.h. (ppc_arch_setup): Remove target description matching code. Fill a ppc_linux_features struct and call ppc_linux_match_description with it.
2018-05-22 22:09:05 +08:00
#include "arch/ppc-linux-common.h"
#include "arch/ppc-linux-tdesc.h"
#include "nat/ppc-linux.h"
#include "linux-tdep.h"
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
/* Similarly for the hardware watchpoint support. These requests are used
when the PowerPC HWDEBUG ptrace interface is not available. */
#ifndef PTRACE_GET_DEBUGREG
#define PTRACE_GET_DEBUGREG 25
#endif
#ifndef PTRACE_SET_DEBUGREG
#define PTRACE_SET_DEBUGREG 26
#endif
#ifndef PTRACE_GETSIGINFO
#define PTRACE_GETSIGINFO 0x4202
#endif
/* These requests are used when the PowerPC HWDEBUG ptrace interface is
available. It exposes the debug facilities of PowerPC processors, as well
as additional features of BookE processors, such as ranged breakpoints and
watchpoints and hardware-accelerated condition evaluation. */
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
#ifndef PPC_PTRACE_GETHWDBGINFO
/* Not having PPC_PTRACE_GETHWDBGINFO defined means that the PowerPC HWDEBUG
ptrace interface is not present in ptrace.h, so we'll have to pretty much
include it all here so that the code at least compiles on older systems. */
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
#define PPC_PTRACE_GETHWDBGINFO 0x89
#define PPC_PTRACE_SETHWDEBUG 0x88
#define PPC_PTRACE_DELHWDEBUG 0x87
struct ppc_debug_info
{
uint32_t version; /* Only version 1 exists to date. */
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
uint32_t num_instruction_bps;
uint32_t num_data_bps;
uint32_t num_condition_regs;
uint32_t data_bp_alignment;
uint32_t sizeof_condition; /* size of the DVC register. */
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
uint64_t features;
};
/* Features will have bits indicating whether there is support for: */
#define PPC_DEBUG_FEATURE_INSN_BP_RANGE 0x1
#define PPC_DEBUG_FEATURE_INSN_BP_MASK 0x2
#define PPC_DEBUG_FEATURE_DATA_BP_RANGE 0x4
#define PPC_DEBUG_FEATURE_DATA_BP_MASK 0x8
struct ppc_hw_breakpoint
{
uint32_t version; /* currently, version must be 1 */
uint32_t trigger_type; /* only some combinations allowed */
uint32_t addr_mode; /* address match mode */
uint32_t condition_mode; /* break/watchpoint condition flags */
uint64_t addr; /* break/watchpoint address */
uint64_t addr2; /* range end or mask */
uint64_t condition_value; /* contents of the DVC register */
};
/* Trigger type. */
#define PPC_BREAKPOINT_TRIGGER_EXECUTE 0x1
#define PPC_BREAKPOINT_TRIGGER_READ 0x2
#define PPC_BREAKPOINT_TRIGGER_WRITE 0x4
#define PPC_BREAKPOINT_TRIGGER_RW 0x6
/* Address mode. */
#define PPC_BREAKPOINT_MODE_EXACT 0x0
#define PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE 0x1
#define PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE 0x2
#define PPC_BREAKPOINT_MODE_MASK 0x3
/* Condition mode. */
#define PPC_BREAKPOINT_CONDITION_NONE 0x0
#define PPC_BREAKPOINT_CONDITION_AND 0x1
#define PPC_BREAKPOINT_CONDITION_EXACT 0x1
#define PPC_BREAKPOINT_CONDITION_OR 0x2
#define PPC_BREAKPOINT_CONDITION_AND_OR 0x3
#define PPC_BREAKPOINT_CONDITION_BE_ALL 0x00ff0000
#define PPC_BREAKPOINT_CONDITION_BE_SHIFT 16
#define PPC_BREAKPOINT_CONDITION_BE(n) \
(1<<((n)+PPC_BREAKPOINT_CONDITION_BE_SHIFT))
#endif /* PPC_PTRACE_GETHWDBGINFO */
/* Feature defined on Linux kernel v3.9: DAWR interface, that enables wider
watchpoint (up to 512 bytes). */
#ifndef PPC_DEBUG_FEATURE_DATA_BP_DAWR
#define PPC_DEBUG_FEATURE_DATA_BP_DAWR 0x10
#endif /* PPC_DEBUG_FEATURE_DATA_BP_DAWR */
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
/* The version of the PowerPC HWDEBUG kernel interface that we will use, if
available. */
#define PPC_DEBUG_CURRENT_VERSION 1
/* Similarly for the general-purpose (gp0 -- gp31)
and floating-point registers (fp0 -- fp31). */
#ifndef PTRACE_GETREGS
#define PTRACE_GETREGS 12
#endif
#ifndef PTRACE_SETREGS
#define PTRACE_SETREGS 13
#endif
#ifndef PTRACE_GETFPREGS
#define PTRACE_GETFPREGS 14
#endif
#ifndef PTRACE_SETFPREGS
#define PTRACE_SETFPREGS 15
#endif
/* This oddity is because the Linux kernel defines elf_vrregset_t as
an array of 33 16 bytes long elements. I.e. it leaves out vrsave.
However the PTRACE_GETVRREGS and PTRACE_SETVRREGS requests return
the vrsave as an extra 4 bytes at the end. I opted for creating a
flat array of chars, so that it is easier to manipulate for gdb.
There are 32 vector registers 16 bytes longs, plus a VSCR register
which is only 4 bytes long, but is fetched as a 16 bytes
quantity. Up to here we have the elf_vrregset_t structure.
Appended to this there is space for the VRSAVE register: 4 bytes.
Even though this vrsave register is not included in the regset
typedef, it is handled by the ptrace requests.
The layout is like this (where x is the actual value of the vscr reg): */
/* *INDENT-OFF* */
/*
[PowerPC] Fix access to VSCR in linux targets The 4-byte VSCR register is found inside a 16-byte field in the regset returned by ptrace and in core files. The position of VSCR depends on the endianess of the target, which was previously assumed to be big-endian for the purpose of getting VSCR. This patch removes this assumption to fix access to VSCR in little-endian mode. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-tdep.h (struct ppc_reg_offsets): Remove vector register offset fields. * ppc-fbsd-tdep.c (ppc32_fbsd_reg_offsets): Remove initializers for vector register offset fields. (ppc64_fbsd_reg_offsets): Likewise. * ppc-nbsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-nat.c (_initialize_ppcobsd_nat): Remove assignment to vector register offset fields. * rs6000-aix-tdep.c (rs6000_aix32_reg_offsets): Remove initializers for vector register offset fields. (rs6000_aix64_reg_offsets): Likewise. * rs6000-tdep.c (ppc_vrreg_offset): Remove. (ppc_supply_vrregset): Remove. (ppc_collect_vrregset): Remove. * ppc-linux-tdep.c (ppc_linux_collect_vrregset): New function. (ppc_linux_vrregset) : New function. (ppc32_le_linux_vrregmap, ppc32_be_linux_vrregmap) (ppc32_le_linux_vrregset, ppc32_be_linux_vrregset): New globals. (ppc32_linux_vrregset): Remove. (ppc_linux_iterate_over_regset_sections): Call ppc_linux_vrregset and use result instead of ppc32_linux_vrregset. (ppc32_linux_reg_offsets): Remove initializers for vector register offset fields. (ppc64_linux_reg_offsets): Likewise. * ppc-linux-tdep.h (ppc_linux_vrregset): New declaration. * ppc-linux-nat.c: Include regset.h. (gdb_vrregset_t): Adjust comment to account for little-endian mode. (supply_vrregset, fill_vrregset): Remove. (fetch_altivec_register, store_altivec_register): Remove. (fetch_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to supply registers. (store_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to collect registers. (fetch_register): Call fetch_altivec_registers instead of fetch_altivec_register. (store_register): Call store_altivec_registers instead of store_altivec_register. (fetch_ppc_registers): Call fetch_altivec_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_altivec_registers with -1 for the new regno parameter. gdb/gdbserver/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * linux-ppc-low.c (ppc_fill_vrregset): Add vscr_offset variable. Set vscr_offset to 0 in little-endian mode and 12 in big-endian mode. Call collect_register_by_name with vscr using vscr_offset. Zero-pad vscr and vrsave fields in collector buffer. (ppc_store_vrregset): Add and set vscr_offset variable as in ppc_fill_vrregset. Call supply_register_by_name with vscr using vscr_offset.
2018-05-22 22:09:05 +08:00
Big-Endian:
|.|.|.|.|.....|.|.|.|.||.|.|.|x||.|
<-------> <-------><-------><->
VR0 VR31 VSCR VRSAVE
[PowerPC] Fix access to VSCR in linux targets The 4-byte VSCR register is found inside a 16-byte field in the regset returned by ptrace and in core files. The position of VSCR depends on the endianess of the target, which was previously assumed to be big-endian for the purpose of getting VSCR. This patch removes this assumption to fix access to VSCR in little-endian mode. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-tdep.h (struct ppc_reg_offsets): Remove vector register offset fields. * ppc-fbsd-tdep.c (ppc32_fbsd_reg_offsets): Remove initializers for vector register offset fields. (ppc64_fbsd_reg_offsets): Likewise. * ppc-nbsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-nat.c (_initialize_ppcobsd_nat): Remove assignment to vector register offset fields. * rs6000-aix-tdep.c (rs6000_aix32_reg_offsets): Remove initializers for vector register offset fields. (rs6000_aix64_reg_offsets): Likewise. * rs6000-tdep.c (ppc_vrreg_offset): Remove. (ppc_supply_vrregset): Remove. (ppc_collect_vrregset): Remove. * ppc-linux-tdep.c (ppc_linux_collect_vrregset): New function. (ppc_linux_vrregset) : New function. (ppc32_le_linux_vrregmap, ppc32_be_linux_vrregmap) (ppc32_le_linux_vrregset, ppc32_be_linux_vrregset): New globals. (ppc32_linux_vrregset): Remove. (ppc_linux_iterate_over_regset_sections): Call ppc_linux_vrregset and use result instead of ppc32_linux_vrregset. (ppc32_linux_reg_offsets): Remove initializers for vector register offset fields. (ppc64_linux_reg_offsets): Likewise. * ppc-linux-tdep.h (ppc_linux_vrregset): New declaration. * ppc-linux-nat.c: Include regset.h. (gdb_vrregset_t): Adjust comment to account for little-endian mode. (supply_vrregset, fill_vrregset): Remove. (fetch_altivec_register, store_altivec_register): Remove. (fetch_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to supply registers. (store_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to collect registers. (fetch_register): Call fetch_altivec_registers instead of fetch_altivec_register. (store_register): Call store_altivec_registers instead of store_altivec_register. (fetch_ppc_registers): Call fetch_altivec_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_altivec_registers with -1 for the new regno parameter. gdb/gdbserver/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * linux-ppc-low.c (ppc_fill_vrregset): Add vscr_offset variable. Set vscr_offset to 0 in little-endian mode and 12 in big-endian mode. Call collect_register_by_name with vscr using vscr_offset. Zero-pad vscr and vrsave fields in collector buffer. (ppc_store_vrregset): Add and set vscr_offset variable as in ppc_fill_vrregset. Call supply_register_by_name with vscr using vscr_offset.
2018-05-22 22:09:05 +08:00
Little-Endian:
|.|.|.|.|.....|.|.|.|.||X|.|.|.||.|
<-------> <-------><-------><->
VR0 VR31 VSCR VRSAVE
*/
/* *INDENT-ON* */
typedef char gdb_vrregset_t[PPC_LINUX_SIZEOF_VRREGSET];
* rs6000-tdep: Include "features/rs6000/powerpc-vsx32.c". Include "features/rs6000/powerpc-vsx64.c". (ppc_supply_vsxregset): New function. (ppc_collect_vsxregset): New function. (IS_VSX_PSEUDOREG): New macro. (IS_EFP_PSEUDOREG): New macro. (vsx_register_p): New function. (ppc_vsx_support_p): New function. (rs6000_builtin_type_vec128): New function. (rs6000_register_name): Hide upper halves of vs0~vs31. Return correct names for VSX registers and EFPR registers. (rs6000_pseudo_register_type): Return correct types for VSX and EFPR registers. (rs6000_pseudo_register_reggroup_p): Return correct group for VSX and EFPR registers. (ppc_pseudo_register_read): Rename to dfp_pseudo_register_read. (ppc_pseudo_register_write): Rename to dfp_pseudo_register_write. (vsx_pseudo_register_read): New function. (vsx_pseudo_register_write): New function. (efpr_pseudo_register_read): New function. (efpr_pseudo_register_write): New function. (rs6000_pseudo_register_read): Call new VSX and EFPR read functions. (rs6000_pseudo_register_write): Call new VSX and EFPR write functions. (rs6000_gdbarch_init): Declare have_vsx. Initialize new upper half VSX registers. Initialize VSX-related and EFPR-related pseudo-registers variables. Adjust the number of pseudo registers accordingly. * ppc-linux-nat.c: Define PTRACE_GETVSXREGS, PTRACE_SETVSXREGS and SIZEOF_VSRREGS. (gdb_vsxregset_t): New type. (have_ptrace_getsetvsxregs): New variable. (fetch_vsx_register): New function. (fetch_register): Handle VSX registers. (fetch_vsx_registers): New function. (fetch_ppc_registers): Handle VSX registers. (store_ppc_registers): Handle VSX registers. (store_vsx_register): New function. (store_register): Handle VSX registers. (store_vsx_registers): New function. (ppc_linux_read_description): Handle VSX-enabled inferiors. (gdb_vsxregset_t): New type. (supply_vsxregset): New function. (fill_vsxregset): New function. * ppc-tdep.h (vsx_register_p): New prototype. (vsx_support_p): New prototype. (ppc_vsr0_regnum): New variable. (ppc_vsr0_upper_regnum): Likewise. (ppc_efpr0_regnum): Likewise. (ppc_builtin_type_vec128): New type. (ppc_num_vsrs): New constant. (ppc_num_vshrs): New constant. (ppc_num_efprs): Likewise. Define POWERPC_VEC_VSX PPC_VSR0_UPPER_REGNUM and PPC_VSR31_UPPER_REGNUM. (ppc_supply_vsxregset): New prototype. (ppc_collect_vsxregset): New prototype. * ppc-linux-tdep.c: Include "features/rs6000/powerpc-vsx32l.c" Include "features/rs6000/powerpc-vsx64l.c". (_initialize_ppc_linux_tdep): Initialize VSX-enabled targets. (ppc_linux_regset_sections): Add new ".reg-ppc-vsx" field. (ppc32_linux_vsxregset): New 32-bit VSX-enabled regset. (ppc_linux_regset_from_core_section): Handle VSX core section. (ppc_linux_core_read_description): Support VSX-enabled core files. * ppc-linux-tdep.h: Declare *tdesc_powerpc_vsx32l Declare tdesc_powerpc_vsx64l * corelow.c (get_core_register_section): Support VSX-enabled core files. * features/rs6000/power-vsx.xml: New VSX descriptions. * features/rs6000/powerpc-vsx32.xml: New file. * features/rs6000/powerpc-vsx32l.xml: New file. * features/rs6000/powerpc-vsx64.xml: New file. * features/rs6000/powerpc-vsx64l.xml: New file. * features/rs6000/powerpc-vsx32.c: New file (generated). * features/rs6000/powerpc-vsx32l.c: New file (generated). * features/rs6000/powerpc-vsx64.c: New file (generated). * features/rs6000/powerpc-vsx64l.c: New file (generated). * features/Makefile: Updated with new descriptions. * regformats/rs6000/powerpc-vsx32l.dat: New file (generated). * regformats/rs6000/powerpc-vsx64l.dat: New file (generated). * testsuite/gdb.arch/vsx-regs.c: New source file. * testsuite/gdb.arch/vsx-regs.exp: New testcase. * testsuite/lib/gdb.exp (skip_vsx_tests): New function.
2008-08-15 23:18:34 +08:00
/* This is the layout of the POWER7 VSX registers and the way they overlap
with the existing FPR and VMX registers.
VSR doubleword 0 VSR doubleword 1
----------------------------------------------------------------
VSR[0] | FPR[0] | |
----------------------------------------------------------------
VSR[1] | FPR[1] | |
----------------------------------------------------------------
| ... | |
| ... | |
----------------------------------------------------------------
VSR[30] | FPR[30] | |
----------------------------------------------------------------
VSR[31] | FPR[31] | |
----------------------------------------------------------------
VSR[32] | VR[0] |
----------------------------------------------------------------
VSR[33] | VR[1] |
----------------------------------------------------------------
| ... |
| ... |
----------------------------------------------------------------
VSR[62] | VR[30] |
----------------------------------------------------------------
VSR[63] | VR[31] |
----------------------------------------------------------------
VSX has 64 128bit registers. The first 32 registers overlap with
the FP registers (doubleword 0) and hence extend them with additional
64 bits (doubleword 1). The other 32 regs overlap with the VMX
registers. */
typedef char gdb_vsxregset_t[PPC_LINUX_SIZEOF_VSXREGSET];
/* On PPC processors that support the Signal Processing Extension
(SPE) APU, the general-purpose registers are 64 bits long.
However, the ordinary Linux kernel PTRACE_PEEKUSER / PTRACE_POKEUSER
ptrace calls only access the lower half of each register, to allow
them to behave the same way they do on non-SPE systems. There's a
separate pair of calls, PTRACE_GETEVRREGS / PTRACE_SETEVRREGS, that
read and write the top halves of all the general-purpose registers
at once, along with some SPE-specific registers.
GDB itself continues to claim the general-purpose registers are 32
Change the layout of the PowerPC E500 raw register cache to allow the lower 32-bit halves of the GPRS to be their own raw registers, not pseudoregisters. * ppc-tdep.h (struct gdbarch_tdep): Remove ppc_gprs_pseudo_p flag; add ppc_ev0_upper_regnum flag. * rs6000-tdep.c: #include "reggroups.h". (spe_register_p): Recognize the ev upper half registers as SPE registers. (init_sim_regno_table): Build gdb->sim mappings for the upper-half registers. (e500_move_ev_register): New function. (e500_pseudo_register_read, e500_pseudo_register_write): The 'ev' vector registers are the pseudo-registers now, formed by splicing together the gprs and the upper-half registers. (e500_register_reggroup_p): New function. (P): Macro deleted. (P8, A4): New macro. (PPC_EV_REGS, PPC_GPRS_PSEUDO_REGS): Macros deleted. (PPC_SPE_GP_REGS, PPC_SPE_UPPER_GP_REGS, PPC_EV_PSEUDO_REGS): New macros. (registers_e500): Rearrange register set so that the raw register set contains 32-bit GPRs and upper-half registers, and the SPE vector registers become pseudo-registers. (rs6000_gdbarch_init): Don't initialize tdep->ppc_gprs_pseudo_p; it has been deleted. Initialize ppc_ev0_upper_regnum. Many other register numbers are now the same for the E500 as they are for other PowerPC variants. Register e500_register_reggroup_p as the register group function for the E500. * Makefile.in (rs6000-tdep.o): Update dependencies. Adapt PPC E500 native support to the new raw regcache layout. * ppc-linux-nat.c (struct gdb_evrregset_t): Doc fixes. (read_spliced_spe_reg, write_spliced_spe_reg): Deleted. (fetch_spe_register, store_spe_register): Handle fetching/storing all the SPE registers at once, if regno == -1. These now take over the job of fetch_spe_registers and store_spe_registers. (fetch_spe_registers, store_spe_registers): Deleted. (fetch_ppc_registers, store_ppc_registers): Fetch/store gprs unconditionally; they're always raw. Fetch/store SPE upper half registers, if present, instead of ev registers. (fetch_register, store_register): Remove sanity checks: gprs are never pseudo-registers now, so we never need to even mention any registers that are ever pseudoregisters.
2004-08-05 01:17:55 +08:00
bits long. It has unnamed raw registers that hold the upper halves
of the gprs, and the full 64-bit SIMD views of the registers,
Change the layout of the PowerPC E500 raw register cache to allow the lower 32-bit halves of the GPRS to be their own raw registers, not pseudoregisters. * ppc-tdep.h (struct gdbarch_tdep): Remove ppc_gprs_pseudo_p flag; add ppc_ev0_upper_regnum flag. * rs6000-tdep.c: #include "reggroups.h". (spe_register_p): Recognize the ev upper half registers as SPE registers. (init_sim_regno_table): Build gdb->sim mappings for the upper-half registers. (e500_move_ev_register): New function. (e500_pseudo_register_read, e500_pseudo_register_write): The 'ev' vector registers are the pseudo-registers now, formed by splicing together the gprs and the upper-half registers. (e500_register_reggroup_p): New function. (P): Macro deleted. (P8, A4): New macro. (PPC_EV_REGS, PPC_GPRS_PSEUDO_REGS): Macros deleted. (PPC_SPE_GP_REGS, PPC_SPE_UPPER_GP_REGS, PPC_EV_PSEUDO_REGS): New macros. (registers_e500): Rearrange register set so that the raw register set contains 32-bit GPRs and upper-half registers, and the SPE vector registers become pseudo-registers. (rs6000_gdbarch_init): Don't initialize tdep->ppc_gprs_pseudo_p; it has been deleted. Initialize ppc_ev0_upper_regnum. Many other register numbers are now the same for the E500 as they are for other PowerPC variants. Register e500_register_reggroup_p as the register group function for the E500. * Makefile.in (rs6000-tdep.o): Update dependencies. Adapt PPC E500 native support to the new raw regcache layout. * ppc-linux-nat.c (struct gdb_evrregset_t): Doc fixes. (read_spliced_spe_reg, write_spliced_spe_reg): Deleted. (fetch_spe_register, store_spe_register): Handle fetching/storing all the SPE registers at once, if regno == -1. These now take over the job of fetch_spe_registers and store_spe_registers. (fetch_spe_registers, store_spe_registers): Deleted. (fetch_ppc_registers, store_ppc_registers): Fetch/store gprs unconditionally; they're always raw. Fetch/store SPE upper half registers, if present, instead of ev registers. (fetch_register, store_register): Remove sanity checks: gprs are never pseudo-registers now, so we never need to even mention any registers that are ever pseudoregisters.
2004-08-05 01:17:55 +08:00
'ev0' -- 'ev31', are pseudo-registers that splice the top and
bottom halves together.
This is the structure filled in by PTRACE_GETEVRREGS and written to
the inferior's registers by PTRACE_SETEVRREGS. */
struct gdb_evrregset_t
{
unsigned long evr[32];
unsigned long long acc;
unsigned long spefscr;
};
* rs6000-tdep: Include "features/rs6000/powerpc-vsx32.c". Include "features/rs6000/powerpc-vsx64.c". (ppc_supply_vsxregset): New function. (ppc_collect_vsxregset): New function. (IS_VSX_PSEUDOREG): New macro. (IS_EFP_PSEUDOREG): New macro. (vsx_register_p): New function. (ppc_vsx_support_p): New function. (rs6000_builtin_type_vec128): New function. (rs6000_register_name): Hide upper halves of vs0~vs31. Return correct names for VSX registers and EFPR registers. (rs6000_pseudo_register_type): Return correct types for VSX and EFPR registers. (rs6000_pseudo_register_reggroup_p): Return correct group for VSX and EFPR registers. (ppc_pseudo_register_read): Rename to dfp_pseudo_register_read. (ppc_pseudo_register_write): Rename to dfp_pseudo_register_write. (vsx_pseudo_register_read): New function. (vsx_pseudo_register_write): New function. (efpr_pseudo_register_read): New function. (efpr_pseudo_register_write): New function. (rs6000_pseudo_register_read): Call new VSX and EFPR read functions. (rs6000_pseudo_register_write): Call new VSX and EFPR write functions. (rs6000_gdbarch_init): Declare have_vsx. Initialize new upper half VSX registers. Initialize VSX-related and EFPR-related pseudo-registers variables. Adjust the number of pseudo registers accordingly. * ppc-linux-nat.c: Define PTRACE_GETVSXREGS, PTRACE_SETVSXREGS and SIZEOF_VSRREGS. (gdb_vsxregset_t): New type. (have_ptrace_getsetvsxregs): New variable. (fetch_vsx_register): New function. (fetch_register): Handle VSX registers. (fetch_vsx_registers): New function. (fetch_ppc_registers): Handle VSX registers. (store_ppc_registers): Handle VSX registers. (store_vsx_register): New function. (store_register): Handle VSX registers. (store_vsx_registers): New function. (ppc_linux_read_description): Handle VSX-enabled inferiors. (gdb_vsxregset_t): New type. (supply_vsxregset): New function. (fill_vsxregset): New function. * ppc-tdep.h (vsx_register_p): New prototype. (vsx_support_p): New prototype. (ppc_vsr0_regnum): New variable. (ppc_vsr0_upper_regnum): Likewise. (ppc_efpr0_regnum): Likewise. (ppc_builtin_type_vec128): New type. (ppc_num_vsrs): New constant. (ppc_num_vshrs): New constant. (ppc_num_efprs): Likewise. Define POWERPC_VEC_VSX PPC_VSR0_UPPER_REGNUM and PPC_VSR31_UPPER_REGNUM. (ppc_supply_vsxregset): New prototype. (ppc_collect_vsxregset): New prototype. * ppc-linux-tdep.c: Include "features/rs6000/powerpc-vsx32l.c" Include "features/rs6000/powerpc-vsx64l.c". (_initialize_ppc_linux_tdep): Initialize VSX-enabled targets. (ppc_linux_regset_sections): Add new ".reg-ppc-vsx" field. (ppc32_linux_vsxregset): New 32-bit VSX-enabled regset. (ppc_linux_regset_from_core_section): Handle VSX core section. (ppc_linux_core_read_description): Support VSX-enabled core files. * ppc-linux-tdep.h: Declare *tdesc_powerpc_vsx32l Declare tdesc_powerpc_vsx64l * corelow.c (get_core_register_section): Support VSX-enabled core files. * features/rs6000/power-vsx.xml: New VSX descriptions. * features/rs6000/powerpc-vsx32.xml: New file. * features/rs6000/powerpc-vsx32l.xml: New file. * features/rs6000/powerpc-vsx64.xml: New file. * features/rs6000/powerpc-vsx64l.xml: New file. * features/rs6000/powerpc-vsx32.c: New file (generated). * features/rs6000/powerpc-vsx32l.c: New file (generated). * features/rs6000/powerpc-vsx64.c: New file (generated). * features/rs6000/powerpc-vsx64l.c: New file (generated). * features/Makefile: Updated with new descriptions. * regformats/rs6000/powerpc-vsx32l.dat: New file (generated). * regformats/rs6000/powerpc-vsx64l.dat: New file (generated). * testsuite/gdb.arch/vsx-regs.c: New source file. * testsuite/gdb.arch/vsx-regs.exp: New testcase. * testsuite/lib/gdb.exp (skip_vsx_tests): New function.
2008-08-15 23:18:34 +08:00
/* Non-zero if our kernel may support the PTRACE_GETVSXREGS and
PTRACE_SETVSXREGS requests, for reading and writing the VSX
POWER7 registers 0 through 31. Zero if we've tried one of them and
gotten an error. Note that VSX registers 32 through 63 overlap
with VR registers 0 through 31. */
int have_ptrace_getsetvsxregs = 1;
/* Non-zero if our kernel may support the PTRACE_GETVRREGS and
PTRACE_SETVRREGS requests, for reading and writing the Altivec
registers. Zero if we've tried one of them and gotten an
error. */
int have_ptrace_getvrregs = 1;
/* Non-zero if our kernel may support the PTRACE_GETEVRREGS and
PTRACE_SETEVRREGS requests, for reading and writing the SPE
registers. Zero if we've tried one of them and gotten an
error. */
int have_ptrace_getsetevrregs = 1;
/* Non-zero if our kernel may support the PTRACE_GETREGS and
PTRACE_SETREGS requests, for reading and writing the
general-purpose registers. Zero if we've tried one of
them and gotten an error. */
int have_ptrace_getsetregs = 1;
/* Non-zero if our kernel may support the PTRACE_GETFPREGS and
PTRACE_SETFPREGS requests, for reading and writing the
floating-pointers registers. Zero if we've tried one of
them and gotten an error. */
int have_ptrace_getsetfpregs = 1;
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
/* Private arch info associated with each thread lwp_info object, used
for debug register handling. */
struct arch_lwp_info
{
/* When true, indicates that the debug registers installed in the
thread no longer correspond to the watchpoints and breakpoints
requested by GDB. */
bool debug_regs_stale;
/* We need a back-reference to the PTID of the thread so that we can
cleanup the debug register state of the thread in
low_delete_thread. */
ptid_t lwp_ptid;
};
/* Class used to detect which set of ptrace requests that
ppc_linux_nat_target will use to install and remove hardware
breakpoints and watchpoints.
The interface is only detected once, testing the ptrace calls. The
result can indicate that no interface is available.
The Linux kernel provides two different sets of ptrace requests to
handle hardware watchpoints and breakpoints for Power:
- PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and
PPC_PTRACE_DELHWDEBUG.
Or
- PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG
The first set is the more flexible one and allows setting watchpoints
with a variable watched region length and, for BookE processors,
multiple types of debug registers (e.g. hardware breakpoints and
hardware-assisted conditions for watchpoints). The second one only
allows setting one debug register, a watchpoint, so we only use it if
the first one is not available. */
class ppc_linux_dreg_interface
{
public:
ppc_linux_dreg_interface ()
: m_interface (), m_hwdebug_info ()
{
};
DISABLE_COPY_AND_ASSIGN (ppc_linux_dreg_interface);
/* One and only one of these three functions returns true, indicating
whether the corresponding interface is the one we detected. The
interface must already have been detected as a precontidion. */
bool hwdebug_p ()
{
gdb_assert (detected_p ());
return *m_interface == HWDEBUG;
}
bool debugreg_p ()
{
gdb_assert (detected_p ());
return *m_interface == DEBUGREG;
}
bool unavailable_p ()
{
gdb_assert (detected_p ());
return *m_interface == UNAVAILABLE;
}
/* Returns the debug register capabilities of the target. Should only
be called if the interface is HWDEBUG. */
const struct ppc_debug_info &hwdebug_info ()
{
gdb_assert (hwdebug_p ());
return m_hwdebug_info;
}
/* Returns true if the interface has already been detected. This is
useful for cases when we know there is no work to be done if the
interface hasn't been detected yet. */
bool detected_p ()
{
return m_interface.has_value ();
}
/* Detect the available interface, if any, if it hasn't been detected
before, using PTID for the necessary ptrace calls. */
void detect (const ptid_t &ptid)
{
if (m_interface.has_value ())
return;
gdb_assert (ptid.lwp_p ());
bool no_features = false;
if (ptrace (PPC_PTRACE_GETHWDBGINFO, ptid.lwp (), 0, &m_hwdebug_info)
!= -1)
{
/* If there are no advertised features, we don't use the
HWDEBUG interface and try the DEBUGREG interface instead.
It shouldn't be necessary to do this, however, when the
kernel is configured without CONFIG_HW_BREAKPOINTS (selected
by CONFIG_PERF_EVENTS), there is a bug that causes
watchpoints installed with the HWDEBUG interface not to
trigger. When this is the case, features will be zero,
which we use as an indicator to fall back to the DEBUGREG
interface. */
if (m_hwdebug_info.features != 0)
{
m_interface.emplace (HWDEBUG);
return;
}
else
no_features = true;
}
/* EIO indicates that the request is invalid, so we try DEBUGREG
next. Technically, it can also indicate other failures, but we
can't differentiate those.
Other errors could happen for various reasons. We could get an
ESRCH if the traced thread was killed by a signal. Trying to
detect the interface with another thread in the future would be
complicated, as callers would have to handle an "unknown
interface" case. It's also unclear if raising an exception
here would be safe.
Other errors, such as ENODEV, could be more permanent and cause
a failure for any thread.
For simplicity, with all errors other than EIO, we set the
interface to UNAVAILABLE and don't try DEBUGREG. If DEBUGREG
fails too, we'll also set the interface to UNAVAILABLE. It's
unlikely that trying the DEBUGREG interface with this same thread
would work, for errors other than EIO. This means that these
errors will cause hardware watchpoints and breakpoints to become
unavailable throughout a GDB session. */
if (no_features || errno == EIO)
{
unsigned long wp;
if (ptrace (PTRACE_GET_DEBUGREG, ptid.lwp (), 0, &wp) != -1)
{
m_interface.emplace (DEBUGREG);
return;
}
}
if (errno != EIO)
warning (_("Error when detecting the debug register interface. "
"Debug registers will be unavailable."));
m_interface.emplace (UNAVAILABLE);
return;
}
private:
/* HWDEBUG represents the set of calls PPC_PTRACE_GETHWDBGINFO,
PPC_PTRACE_SETHWDEBUG and PPC_PTRACE_DELHWDEBUG.
DEBUGREG represents the set of calls PTRACE_SET_DEBUGREG and
PTRACE_GET_DEBUGREG.
UNAVAILABLE can indicate that the kernel doesn't support any of the
two sets of requests or that there was an error when we tried to
detect wich interface is available. */
enum debug_reg_interface
{
UNAVAILABLE,
HWDEBUG,
DEBUGREG
};
/* The interface option. Initialized if has_value () returns true. */
gdb::optional<enum debug_reg_interface> m_interface;
/* The info returned by the kernel with PPC_PTRACE_GETHWDBGINFO. Only
valid if we determined that the interface is HWDEBUG. */
struct ppc_debug_info m_hwdebug_info;
};
/* Per-process information. This includes the hardware watchpoints and
breakpoints that GDB requested to this target. */
struct ppc_linux_process_info
{
/* The list of hardware watchpoints and breakpoints that GDB requested
for this process.
Only used when the interface is HWDEBUG. */
std::list<struct ppc_hw_breakpoint> requested_hw_bps;
/* The watchpoint value that GDB requested for this process.
Only used when the interface is DEBUGREG. */
gdb::optional<long> requested_wp_val;
};
Convert struct target_ops to C++ I.e., use C++ virtual methods and inheritance instead of tables of function pointers. Unfortunately, there's no way to do a smooth transition. ALL native targets in the tree must be converted at the same time. I've tested all I could with cross compilers and with help from GCC compile farm, but naturally I haven't been able to test many of the ports. Still, I made a best effort to port everything over, and while I expect some build problems due to typos and such, which should be trivial to fix, I don't expect any design problems. * Implementation notes: - The flattened current_target is gone. References to current_target or current_target.beneath are replaced with references to target_stack (the top of the stack) directly. - To keep "set debug target" working, this adds a new debug_stratum layer that sits on top of the stack, prints the debug, and delegates to the target beneath. In addition, this makes the shortname and longname properties of target_ops be virtual methods instead of data fields, and makes the debug target defer those to the target beneath. This is so that debug code sprinkled around that does "if (debugtarget) ..." can transparently print the name of the target beneath. A patch later in the series actually splits out the shortname/longname methods to a separate structure, but I preferred to keep that chance separate as it is associated with changing a bit the design of how targets are registered and open. - Since you can't check whether a C++ virtual method is overridden, the old method of checking whether a target_ops implements a method by comparing the function pointer must be replaced with something else. Some cases are fixed by adding a parallel "can_do_foo" target_ops methods. E.g.,: + for (t = target_stack; t != NULL; t = t->beneath) { - if (t->to_create_inferior != NULL) + if (t->can_create_inferior ()) break; } Others are fixed by changing void return type to bool or int return type, and have the default implementation return false or -1, to indicate lack of support. - make-target-delegates was adjusted to generate C++ classes and methods. It needed tweaks to grok "virtual" in front of the target method name, and for the fact that methods are no longer function pointers. (In particular, the current code parsing the return type was simple because it could simply parse up until the '(' in '(*to_foo)'. It now generates a couple C++ classes that inherit target_ops: dummy_target and debug_target. Since we need to generate the class declarations as well, i.e., we need to emit methods twice, we now generate the code in two passes. - The core_target global is renamed to avoid conflict with the "core_target" class. - ctf/tfile targets init_tracefile_ops is replaced by a base class that is inherited by both ctf and tfile. - bsd-uthread The bsd_uthread_ops_hack hack is gone. It's not needed because nothing was extending a target created by bsd_uthread_target. - remote/extended-remote targets This is a first pass, just enough to C++ify target_ops. A later pass will convert more free functions to methods, and make remote_state be truly per remote instance, allowing multiple simultaneous instances of remote targets. - inf-child/"native" is converted to an actual base class (inf_child_target), that is inherited by all native targets. - GNU/Linux The old weird double-target linux_ops mechanism in linux-nat.c, is gone, replaced by adding a few virtual methods to linux-nat.h's target_ops, called low_XXX, that the concrete linux-nat implementations override. Sort of like gdbserver's linux_target_ops, but simpler, for requiring only one target_ops-like hierarchy, which spares implementing the same method twice when we need to forward the method to a low implementation. The low target simply reimplements the target_ops method directly in that case. There are a few remaining linux-nat.c hooks that would be better converted to low_ methods like above too. E.g.: linux_nat_set_new_thread (t, x86_linux_new_thread); linux_nat_set_new_fork (t, x86_linux_new_fork); linux_nat_set_forget_process That'll be done in a follow up patch. - We can no longer use functions like x86_use_watchpoints to install custom methods on an arbitrary base target. The patch replaces instances of such a pattern with template mixins. For example memory_breakpoint_target defined in target.h, or x86_nat_target in x86-nat.h. - linux_trad_target, MIPS and Alpha GNU/Linux The code in the new linux-nat-trad.h/c files which was split off of inf-ptrace.h/c recently, is converted to a C++ base class, and used by the MIPS and Alpha GNU/Linux ports. - BSD targets The $architecture x NetBSD/OpenBSD/FreeBSD support matrix complicates things a bit. There's common BSD target code, and there's common architecture-specific code shared between the different BSDs. Currently, all that is stiched together to form a final target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target functions etc. This introduces new fbsd_nat_target, obsd_nat_target and nbsd_nat_target classes that serve as base/prototype target for the corresponding BSD variant. And introduces generic i386/AMD64 BSD targets, to be used as template mixin to build a final target. Similarly, a generic SPARC target is added, used by both BSD and Linux ports. - bsd_kvm_add_target, BSD libkvm target I considered making bsd_kvm_supply_pcb a virtual method, and then have each port inherit bsd_kvm_target and override that method, but that was resulting in lots of unjustified churn, so I left the function pointer mechanism alone. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> John Baldwin <jhb@freebsd.org> * target.h (enum strata) <debug_stratum>: New. (struct target_ops) <all delegation methods>: Replace by C++ virtual methods, and drop "to_" prefix. All references updated throughout. <to_shortname, to_longname, to_doc, to_data, to_have_steppable_watchpoint, to_have_continuable_watchpoint, to_has_thread_control, to_attach_no_wait>: Delete, replaced by virtual methods. All references updated throughout. <can_attach, supports_terminal_ours, can_create_inferior, get_thread_control_capabilities, attach_no_wait>: New virtual methods. <insert_breakpoint, remove_breakpoint>: Now TARGET_DEFAULT_NORETURN methods. <info_proc>: Now returns bool. <to_magic>: Delete. (OPS_MAGIC): Delete. (current_target): Delete. All references replaced by references to ... (target_stack): ... this. New. (target_shortname, target_longname): Adjust. (target_can_run): Now a function declaration. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (memory_breakpoint_target): New template class. (test_target_ops): Refactor as a C++ class with virtual methods. * make-target-delegates (NAME_PART): Tighten. (POINTER_PART, CP_SYMBOL): New. (SIMPLE_RETURN_PART): Reimplement. (VEC_RETURN_PART): Expect less. (RETURN_PART, VIRTUAL_PART): New. (METHOD): Adjust to C++ virtual methods. (scan_target_h): Remove reference to C99. (dname): Output "target_ops::" prefix. (write_function_header): Adjust to output a C++ class method. (write_declaration): New. (write_delegator): Adjust to output a C++ class method. (tdname): Output "dummy_target::" prefix. (write_tdefault, write_debugmethod): Adjust to output a C++ class method. (tdefault_names, debug_names): Delete. (return_types, tdefaults, styles, argtypes_array): New. (top level): All methods are delegators. (print_class): New. (top level): Print dummy_target and debug_target classes. * target-delegates.c: Regenerate. * target-debug.h (target_debug_print_enum_info_proc_what) (target_debug_print_thread_control_capabilities) (target_debug_print_thread_info_p): New. * target.c (dummy_target): Delete. (the_dummy_target, the_debug_target): New. (target_stack): Now extern. (set_targetdebug): Push/unpush debug target. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (add_target_with_completer): No longer call complete_target_initialization. (target_supports_terminal_ours): Use regular delegation. (update_current_target): Delete. (push_target): No longer check magic number. Don't call update_current_target. (unpush_target): Don't call update_current_target. (target_is_pushed): No longer check magic number. (target_require_runnable): Skip for all stratums over process_stratum. (target_ops::info_proc): New. (target_info_proc): Use find_target_at and find_default_run_target. (target_supports_disable_randomization): Use regular delegation. (target_get_osdata): Use find_target_at. (target_ops::open, target_ops::close, target_ops::can_attach) (target_ops::attach, target_ops::can_create_inferior) (target_ops::create_inferior, target_ops::can_run) (target_can_run): New. (default_fileio_target): Use regular delegation. (target_ops::fileio_open, target_ops::fileio_pwrite) (target_ops::fileio_pread, target_ops::fileio_fstat) (target_ops::fileio_close, target_ops::fileio_unlink) (target_ops::fileio_readlink): New. (target_fileio_open_1, target_fileio_unlink) (target_fileio_readlink): Always call the target method. Handle FILEIO_ENOSYS. (return_zero, return_zero_has_execution): Delete. (init_dummy_target): Delete. (dummy_target::dummy_target, dummy_target::shortname) (dummy_target::longname, dummy_target::doc) (debug_target::debug_target, debug_target::shortname) (debug_target::longname, debug_target::doc): New. (target_supports_delete_record): Use regular delegation. (setup_target_debug): Delete. (maintenance_print_target_stack): Skip debug_stratum. (initialize_targets): Instantiate the_dummy_target and the_debug_target. * auxv.c (target_auxv_parse): Remove 'ops' parameter. Adjust to use target_stack. (target_auxv_search, fprint_target_auxv): Adjust. (info_auxv_command): Adjust to use target_stack. * auxv.h (target_auxv_parse): Remove 'ops' parameter. * exceptions.c (print_flush): Handle a NULL target_stack. * regcache.c (target_ops_no_register): Refactor as class with virtual methods. * exec.c (exec_target): New class. (exec_ops): Now an exec_target. (exec_open, exec_close_1, exec_get_section_table) (exec_xfer_partial, exec_files_info, exec_has_memory) (exec_make_note_section): Refactor as exec_target methods. (exec_file_clear, ignore, exec_remove_breakpoint, init_exec_ops): Delete. (exec_target::find_memory_regions): New. (_initialize_exec): Don't call init_exec_ops. * gdbcore.h (exec_file_clear): Delete. * corefile.c (core_target): Delete. (core_file_command): Adjust. * corelow.c (core_target): New class. (the_core_target): New. (core_close): Remove target_ops parameter. (core_close_cleanup): Adjust. (core_target::close): New. (core_open, core_detach, get_core_registers, core_files_info) (core_xfer_partial, core_thread_alive, core_read_description) (core_pid_to_str, core_thread_name, core_has_memory) (core_has_stack, core_has_registers, core_info_proc): Rework as core_target methods. (ignore, core_remove_breakpoint, init_core_ops): Delete. (_initialize_corelow): Initialize the_core_target. * gdbcore.h (core_target): Delete. (the_core_target): New. * ctf.c: (ctf_target): New class. (ctf_ops): Now a ctf_target. (ctf_open, ctf_close, ctf_files_info, ctf_fetch_registers) (ctf_xfer_partial, ctf_get_trace_state_variable_value) (ctf_trace_find, ctf_traceframe_info): Refactor as ctf_target methods. (init_ctf_ops): Delete. (_initialize_ctf): Don't call it. * tracefile-tfile.c (tfile_target): New class. (tfile_ops): Now a tfile_target. (tfile_open, tfile_close, tfile_files_info) (tfile_get_tracepoint_status, tfile_trace_find) (tfile_fetch_registers, tfile_xfer_partial) (tfile_get_trace_state_variable_value, tfile_traceframe_info): Refactor as tfile_target methods. (tfile_xfer_partial_features): Remove target_ops parameter. (init_tfile_ops): Delete. (_initialize_tracefile_tfile): Don't call it. * tracefile.c (tracefile_has_all_memory, tracefile_has_memory) (tracefile_has_stack, tracefile_has_registers) (tracefile_thread_alive, tracefile_get_trace_status): Refactor as tracefile_target methods. (init_tracefile_ops): Delete. (tracefile_target::tracefile_target): New. * tracefile.h: Include "target.h". (tracefile_target): New class. (init_tracefile_ops): Delete. * spu-multiarch.c (spu_multiarch_target): New class. (spu_ops): Now a spu_multiarch_target. (spu_thread_architecture, spu_region_ok_for_hw_watchpoint) (spu_fetch_registers, spu_store_registers, spu_xfer_partial) (spu_search_memory, spu_mourn_inferior): Refactor as spu_multiarch_target methods. (init_spu_ops): Delete. (_initialize_spu_multiarch): Remove references to init_spu_ops, complete_target_initialization. * ravenscar-thread.c (ravenscar_thread_target): New class. (ravenscar_ops): Now a ravenscar_thread_target. (ravenscar_resume, ravenscar_wait, ravenscar_update_thread_list) (ravenscar_thread_alive, ravenscar_pid_to_str) (ravenscar_fetch_registers, ravenscar_store_registers) (ravenscar_prepare_to_store, ravenscar_stopped_by_sw_breakpoint) (ravenscar_stopped_by_hw_breakpoint) (ravenscar_stopped_by_watchpoint, ravenscar_stopped_data_address) (ravenscar_mourn_inferior, ravenscar_core_of_thread) (ravenscar_get_ada_task_ptid): Refactor as ravenscar_thread_target methods. (init_ravenscar_thread_ops): Delete. (_initialize_ravenscar): Remove references to init_ravenscar_thread_ops and complete_target_initialization. * bsd-uthread.c (bsd_uthread_ops_hack): Delete. (bsd_uthread_target): New class. (bsd_uthread_ops): Now a bsd_uthread_target. (bsd_uthread_activate): Adjust to refer to bsd_uthread_ops. (bsd_uthread_close, bsd_uthread_mourn_inferior) (bsd_uthread_fetch_registers, bsd_uthread_store_registers) (bsd_uthread_wait, bsd_uthread_resume, bsd_uthread_thread_alive) (bsd_uthread_update_thread_list, bsd_uthread_extra_thread_info) (bsd_uthread_pid_to_str): Refactor as bsd_uthread_target methods. (bsd_uthread_target): Delete function. (_initialize_bsd_uthread): Remove reference to complete_target_initialization. * bfd-target.c (target_bfd_data): Delete. Fields folded into ... (target_bfd): ... this new class. (target_bfd_xfer_partial, target_bfd_get_section_table) (target_bfd_close): Refactor as target_bfd methods. (target_bfd::~target_bfd): New. (target_bfd_reopen): Adjust. (target_bfd::close): New. * record-btrace.c (record_btrace_target): New class. (record_btrace_ops): Now a record_btrace_target. (record_btrace_open, record_btrace_stop_recording) (record_btrace_disconnect, record_btrace_close) (record_btrace_async, record_btrace_info) (record_btrace_insn_history, record_btrace_insn_history_range) (record_btrace_insn_history_from, record_btrace_call_history) (record_btrace_call_history_range) (record_btrace_call_history_from, record_btrace_record_method) (record_btrace_is_replaying, record_btrace_will_replay) (record_btrace_xfer_partial, record_btrace_insert_breakpoint) (record_btrace_remove_breakpoint, record_btrace_fetch_registers) (record_btrace_store_registers, record_btrace_prepare_to_store) (record_btrace_to_get_unwinder) (record_btrace_to_get_tailcall_unwinder, record_btrace_resume) (record_btrace_commit_resume, record_btrace_wait) (record_btrace_stop, record_btrace_can_execute_reverse) (record_btrace_stopped_by_sw_breakpoint) (record_btrace_supports_stopped_by_sw_breakpoint) (record_btrace_stopped_by_hw_breakpoint) (record_btrace_supports_stopped_by_hw_breakpoint) (record_btrace_update_thread_list, record_btrace_thread_alive) (record_btrace_goto_begin, record_btrace_goto_end) (record_btrace_goto, record_btrace_stop_replaying_all) (record_btrace_execution_direction) (record_btrace_prepare_to_generate_core) (record_btrace_done_generating_core): Refactor as record_btrace_target methods. (init_record_btrace_ops): Delete. (_initialize_record_btrace): Remove reference to init_record_btrace_ops. * record-full.c (RECORD_FULL_IS_REPLAY): Adjust to always refer to the execution_direction global. (record_full_base_target, record_full_target) (record_full_core_target): New classes. (record_full_ops): Now a record_full_target. (record_full_core_ops): Now a record_full_core_target. (record_full_target::detach, record_full_target::disconnect) (record_full_core_target::disconnect) (record_full_target::mourn_inferior, record_full_target::kill): New. (record_full_open, record_full_close, record_full_async): Refactor as methods of the record_full_base_target class. (record_full_resume, record_full_commit_resume): Refactor as methods of the record_full_target class. (record_full_wait, record_full_stopped_by_watchpoint) (record_full_stopped_data_address) (record_full_stopped_by_sw_breakpoint) (record_full_supports_stopped_by_sw_breakpoint) (record_full_stopped_by_hw_breakpoint) (record_full_supports_stopped_by_hw_breakpoint): Refactor as methods of the record_full_base_target class. (record_full_store_registers, record_full_xfer_partial) (record_full_insert_breakpoint, record_full_remove_breakpoint): Refactor as methods of the record_full_target class. (record_full_can_execute_reverse, record_full_get_bookmark) (record_full_goto_bookmark, record_full_execution_direction) (record_full_record_method, record_full_info, record_full_delete) (record_full_is_replaying, record_full_will_replay) (record_full_goto_begin, record_full_goto_end, record_full_goto) (record_full_stop_replaying): Refactor as methods of the record_full_base_target class. (record_full_core_resume, record_full_core_kill) (record_full_core_fetch_registers) (record_full_core_prepare_to_store) (record_full_core_store_registers, record_full_core_xfer_partial) (record_full_core_insert_breakpoint) (record_full_core_remove_breakpoint) (record_full_core_has_execution): Refactor as methods of the record_full_core_target class. (record_full_base_target::supports_delete_record): New. (init_record_full_ops): Delete. (init_record_full_core_ops): Delete. (record_full_save): Refactor as method of the record_full_base_target class. (_initialize_record_full): Remove references to init_record_full_ops and init_record_full_core_ops. * remote.c (remote_target, extended_remote_target): New classes. (remote_ops): Now a remote_target. (extended_remote_ops): Now an extended_remote_target. (remote_insert_fork_catchpoint, remote_remove_fork_catchpoint) (remote_insert_vfork_catchpoint, remote_remove_vfork_catchpoint) (remote_insert_exec_catchpoint, remote_remove_exec_catchpoint) (remote_pass_signals, remote_set_syscall_catchpoint) (remote_program_signals, ) (remote_thread_always_alive): Remove target_ops parameter. (remote_thread_alive, remote_thread_name) (remote_update_thread_list, remote_threads_extra_info) (remote_static_tracepoint_marker_at) (remote_static_tracepoint_markers_by_strid) (remote_get_ada_task_ptid, remote_close, remote_start_remote) (remote_open): Refactor as methods of remote_target. (extended_remote_open, extended_remote_detach) (extended_remote_attach, extended_remote_post_attach): (extended_remote_supports_disable_randomization) (extended_remote_create_inferior): : Refactor as method of extended_remote_target. (remote_set_permissions, remote_open_1, remote_detach) (remote_follow_fork, remote_follow_exec, remote_disconnect) (remote_resume, remote_commit_resume, remote_stop) (remote_interrupt, remote_pass_ctrlc, remote_terminal_inferior) (remote_terminal_ours, remote_wait, remote_fetch_registers) (remote_prepare_to_store, remote_store_registers) (remote_flash_erase, remote_flash_done, remote_files_info) (remote_kill, remote_mourn, remote_insert_breakpoint) (remote_remove_breakpoint, remote_insert_watchpoint) (remote_watchpoint_addr_within_range) (remote_remove_watchpoint, remote_region_ok_for_hw_watchpoint) (remote_check_watch_resources, remote_stopped_by_sw_breakpoint) (remote_supports_stopped_by_sw_breakpoint) (remote_stopped_by_hw_breakpoint) (remote_supports_stopped_by_hw_breakpoint) (remote_stopped_by_watchpoint, remote_stopped_data_address) (remote_insert_hw_breakpoint, remote_remove_hw_breakpoint) (remote_verify_memory): Refactor as methods of remote_target. (remote_write_qxfer, remote_read_qxfer): Remove target_ops parameter. (remote_xfer_partial, remote_get_memory_xfer_limit) (remote_search_memory, remote_rcmd, remote_memory_map) (remote_pid_to_str, remote_get_thread_local_address) (remote_get_tib_address, remote_read_description): Refactor as methods of remote_target. (remote_target::fileio_open, remote_target::fileio_pwrite) (remote_target::fileio_pread, remote_target::fileio_close): New. (remote_hostio_readlink, remote_hostio_fstat) (remote_filesystem_is_local, remote_can_execute_reverse) (remote_supports_non_stop, remote_supports_disable_randomization) (remote_supports_multi_process, remote_supports_cond_breakpoints) (remote_supports_enable_disable_tracepoint) (remote_supports_string_tracing) (remote_can_run_breakpoint_commands, remote_trace_init) (remote_download_tracepoint, remote_can_download_tracepoint) (remote_download_trace_state_variable, remote_enable_tracepoint) (remote_disable_tracepoint, remote_trace_set_readonly_regions) (remote_trace_start, remote_get_trace_status) (remote_get_tracepoint_status, remote_trace_stop) (remote_trace_find, remote_get_trace_state_variable_value) (remote_save_trace_data, remote_get_raw_trace_data) (remote_set_disconnected_tracing, remote_core_of_thread) (remote_set_circular_trace_buffer, remote_traceframe_info) (remote_get_min_fast_tracepoint_insn_len) (remote_set_trace_buffer_size, remote_set_trace_notes) (remote_use_agent, remote_can_use_agent, remote_enable_btrace) (remote_disable_btrace, remote_teardown_btrace) (remote_read_btrace, remote_btrace_conf) (remote_augmented_libraries_svr4_read, remote_load) (remote_pid_to_exec_file, remote_can_do_single_step) (remote_execution_direction, remote_thread_handle_to_thread_info): Refactor as methods of remote_target. (init_remote_ops, init_extended_remote_ops): Delete. (remote_can_async_p, remote_is_async_p, remote_async) (remote_thread_events, remote_upload_tracepoints) (remote_upload_trace_state_variables): Refactor as methods of remote_target. (_initialize_remote): Remove references to init_remote_ops and init_extended_remote_ops. * remote-sim.c (gdbsim_target): New class. (gdbsim_fetch_register, gdbsim_store_register, gdbsim_kill) (gdbsim_load, gdbsim_create_inferior, gdbsim_open, gdbsim_close) (gdbsim_detach, gdbsim_resume, gdbsim_interrupt) (gdbsim_wait, gdbsim_prepare_to_store, gdbsim_xfer_partial) (gdbsim_files_info, gdbsim_mourn_inferior, gdbsim_thread_alive) (gdbsim_pid_to_str, gdbsim_has_all_memory, gdbsim_has_memory): Refactor as methods of gdbsim_target. (gdbsim_ops): Now a gdbsim_target. (init_gdbsim_ops): Delete. (gdbsim_cntrl_c): Adjust. (_initialize_remote_sim): Remove reference to init_gdbsim_ops. * amd64-linux-nat.c (amd64_linux_nat_target): New class. (the_amd64_linux_nat_target): New. (amd64_linux_fetch_inferior_registers) (amd64_linux_store_inferior_registers): Refactor as methods of amd64_linux_nat_target. (_initialize_amd64_linux_nat): Adjust. Set linux_target. * i386-linux-nat.c: Don't include "linux-nat.h". (i386_linux_nat_target): New class. (the_i386_linux_nat_target): New. (i386_linux_fetch_inferior_registers) (i386_linux_store_inferior_registers, i386_linux_resume): Refactor as methods of i386_linux_nat_target. (_initialize_i386_linux_nat): Adjust. Set linux_target. * inf-child.c (inf_child_ops): Delete. (inf_child_fetch_inferior_registers) (inf_child_store_inferior_registers): Delete. (inf_child_post_attach, inf_child_prepare_to_store): Refactor as methods of inf_child_target. (inf_child_target::supports_terminal_ours) (inf_child_target::terminal_init) (inf_child_target::terminal_inferior) (inf_child_target::terminal_ours_for_output) (inf_child_target::terminal_ours, inf_child_target::interrupt) (inf_child_target::pass_ctrlc, inf_child_target::terminal_info): New. (inf_child_open, inf_child_disconnect, inf_child_close) (inf_child_mourn_inferior, inf_child_maybe_unpush_target) (inf_child_post_startup_inferior, inf_child_can_run) (inf_child_pid_to_exec_file): Refactor as methods of inf_child_target. (inf_child_follow_fork): Delete. (inf_child_target::can_create_inferior) (inf_child_target::can_attach): New. (inf_child_target::has_all_memory, inf_child_target::has_memory) (inf_child_target::has_stack, inf_child_target::has_registers) (inf_child_target::has_execution): New. (inf_child_fileio_open, inf_child_fileio_pwrite) (inf_child_fileio_pread, inf_child_fileio_fstat) (inf_child_fileio_close, inf_child_fileio_unlink) (inf_child_fileio_readlink, inf_child_use_agent) (inf_child_can_use_agent): Refactor as methods of inf_child_target. (return_zero, inf_child_target): Delete. (inf_child_target::inf_child_target): New. * inf-child.h: Include "target.h". (inf_child_target): Delete function prototype. (inf_child_target): New class. (inf_child_open_target, inf_child_mourn_inferior) (inf_child_maybe_unpush_target): Delete. * inf-ptrace.c (inf_ptrace_target::~inf_ptrace_target): New. (inf_ptrace_follow_fork, inf_ptrace_insert_fork_catchpoint) (inf_ptrace_remove_fork_catchpoint, inf_ptrace_create_inferior) (inf_ptrace_post_startup_inferior, inf_ptrace_mourn_inferior) (inf_ptrace_attach, inf_ptrace_post_attach, inf_ptrace_detach) (inf_ptrace_detach_success, inf_ptrace_kill, inf_ptrace_resume) (inf_ptrace_wait, inf_ptrace_xfer_partial) (inf_ptrace_thread_alive, inf_ptrace_files_info) (inf_ptrace_pid_to_str, inf_ptrace_auxv_parse): Refactor as methods of inf_ptrace_target. (inf_ptrace_target): Delete function. * inf-ptrace.h: Include "inf-child.h". (inf_ptrace_target): Delete function declaration. (inf_ptrace_target): New class. (inf_ptrace_trad_target, inf_ptrace_detach_success): Delete. * linux-nat.c (linux_target): New. (linux_ops, linux_ops_saved, super_xfer_partial): Delete. (linux_nat_target::~linux_nat_target): New. (linux_child_post_attach, linux_child_post_startup_inferior) (linux_child_follow_fork, linux_child_insert_fork_catchpoint) (linux_child_remove_fork_catchpoint) (linux_child_insert_vfork_catchpoint) (linux_child_remove_vfork_catchpoint) (linux_child_insert_exec_catchpoint) (linux_child_remove_exec_catchpoint) (linux_child_set_syscall_catchpoint, linux_nat_pass_signals) (linux_nat_create_inferior, linux_nat_attach, linux_nat_detach) (linux_nat_resume, linux_nat_stopped_by_watchpoint) (linux_nat_stopped_data_address) (linux_nat_stopped_by_sw_breakpoint) (linux_nat_supports_stopped_by_sw_breakpoint) (linux_nat_stopped_by_hw_breakpoint) (linux_nat_supports_stopped_by_hw_breakpoint, linux_nat_wait) (linux_nat_kill, linux_nat_mourn_inferior) (linux_nat_xfer_partial, linux_nat_thread_alive) (linux_nat_update_thread_list, linux_nat_pid_to_str) (linux_nat_thread_name, linux_child_pid_to_exec_file) (linux_child_static_tracepoint_markers_by_strid) (linux_nat_is_async_p, linux_nat_can_async_p) (linux_nat_supports_non_stop, linux_nat_always_non_stop_p) (linux_nat_supports_multi_process) (linux_nat_supports_disable_randomization, linux_nat_async) (linux_nat_stop, linux_nat_close, linux_nat_thread_address_space) (linux_nat_core_of_thread, linux_nat_filesystem_is_local) (linux_nat_fileio_open, linux_nat_fileio_readlink) (linux_nat_fileio_unlink, linux_nat_thread_events): Refactor as methods of linux_nat_target. (linux_nat_wait_1, linux_xfer_siginfo, linux_proc_xfer_partial) (linux_proc_xfer_spu, linux_nat_xfer_osdata): Remove target_ops parameter. (check_stopped_by_watchpoint): Adjust. (linux_xfer_partial): Delete. (linux_target_install_ops, linux_target, linux_nat_add_target): Delete. (linux_nat_target::linux_nat_target): New. * linux-nat.h: Include "inf-ptrace.h". (linux_nat_target): New. (linux_target, linux_target_install_ops, linux_nat_add_target): Delete function declarations. (linux_target): Declare global. * linux-thread-db.c (thread_db_target): New. (thread_db_target::thread_db_target): New. (thread_db_ops): Delete. (the_thread_db_target): New. (thread_db_detach, thread_db_wait, thread_db_mourn_inferior) (thread_db_update_thread_list, thread_db_pid_to_str) (thread_db_extra_thread_info) (thread_db_thread_handle_to_thread_info) (thread_db_get_thread_local_address, thread_db_get_ada_task_ptid) (thread_db_resume): Refactor as methods of thread_db_target. (init_thread_db_ops): Delete. (_initialize_thread_db): Remove reference to init_thread_db_ops. * x86-linux-nat.c: Don't include "linux-nat.h". (super_post_startup_inferior): Delete. (x86_linux_nat_target::~x86_linux_nat_target): New. (x86_linux_child_post_startup_inferior) (x86_linux_read_description, x86_linux_enable_btrace) (x86_linux_disable_btrace, x86_linux_teardown_btrace) (x86_linux_read_btrace, x86_linux_btrace_conf): Refactor as methods of x86_linux_nat_target. (x86_linux_create_target): Delete. Bits folded ... (x86_linux_add_target): ... here. Now takes a linux_nat_target pointer. * x86-linux-nat.h: Include "linux-nat.h" and "x86-nat.h". (x86_linux_nat_target): New class. (x86_linux_create_target): Delete. (x86_linux_add_target): Now takes a linux_nat_target pointer. * x86-nat.c (x86_insert_watchpoint, x86_remove_watchpoint) (x86_region_ok_for_watchpoint, x86_stopped_data_address) (x86_stopped_by_watchpoint, x86_insert_hw_breakpoint) (x86_remove_hw_breakpoint, x86_can_use_hw_breakpoint) (x86_stopped_by_hw_breakpoint): Remove target_ops parameter and make extern. (x86_use_watchpoints): Delete. * x86-nat.h: Include "breakpoint.h" and "target.h". (x86_use_watchpoints): Delete. (x86_can_use_hw_breakpoint, x86_region_ok_for_hw_watchpoint) (x86_stopped_by_watchpoint, x86_stopped_data_address) (x86_insert_watchpoint, x86_remove_watchpoint) (x86_insert_hw_breakpoint, x86_remove_hw_breakpoint) (x86_stopped_by_hw_breakpoint): New declarations. (x86_nat_target): New template class. * ppc-linux-nat.c (ppc_linux_nat_target): New class. (the_ppc_linux_nat_target): New. (ppc_linux_fetch_inferior_registers) (ppc_linux_can_use_hw_breakpoint) (ppc_linux_region_ok_for_hw_watchpoint) (ppc_linux_ranged_break_num_registers) (ppc_linux_insert_hw_breakpoint, ppc_linux_remove_hw_breakpoint) (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_can_accel_watchpoint_condition) (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint) (ppc_linux_stopped_data_address, ppc_linux_stopped_by_watchpoint) (ppc_linux_watchpoint_addr_within_range) (ppc_linux_masked_watch_num_registers) (ppc_linux_store_inferior_registers, ppc_linux_auxv_parse) (ppc_linux_read_description): Refactor as methods of ppc_linux_nat_target. (_initialize_ppc_linux_nat): Adjust. Set linux_target. * procfs.c (procfs_xfer_partial): Delete forward declaration. (procfs_target): New class. (the_procfs_target): New. (procfs_target): Delete function. (procfs_auxv_parse, procfs_attach, procfs_detach) (procfs_fetch_registers, procfs_store_registers, procfs_wait) (procfs_xfer_partial, procfs_resume, procfs_pass_signals) (procfs_files_info, procfs_kill_inferior, procfs_mourn_inferior) (procfs_create_inferior, procfs_update_thread_list) (procfs_thread_alive, procfs_pid_to_str) (procfs_can_use_hw_breakpoint, procfs_stopped_by_watchpoint) (procfs_stopped_data_address, procfs_insert_watchpoint) (procfs_remove_watchpoint, procfs_region_ok_for_hw_watchpoint) (proc_find_memory_regions, procfs_info_proc) (procfs_make_note_section): Refactor as methods of procfs_target. (_initialize_procfs): Adjust. * sol-thread.c (sol_thread_target): New class. (sol_thread_ops): Now a sol_thread_target. (sol_thread_detach, sol_thread_resume, sol_thread_wait) (sol_thread_fetch_registers, sol_thread_store_registers) (sol_thread_xfer_partial, sol_thread_mourn_inferior) (sol_thread_alive, solaris_pid_to_str, sol_update_thread_list) (sol_get_ada_task_ptid): Refactor as methods of sol_thread_target. (init_sol_thread_ops): Delete. (_initialize_sol_thread): Adjust. Remove references to init_sol_thread_ops and complete_target_initialization. * windows-nat.c (windows_nat_target): New class. (windows_fetch_inferior_registers) (windows_store_inferior_registers, windows_resume, windows_wait) (windows_attach, windows_detach, windows_pid_to_exec_file) (windows_files_info, windows_create_inferior) (windows_mourn_inferior, windows_interrupt, windows_kill_inferior) (windows_close, windows_pid_to_str, windows_xfer_partial) (windows_get_tib_address, windows_get_ada_task_ptid) (windows_thread_name, windows_thread_alive): Refactor as windows_nat_target methods. (do_initial_windows_stuff): Adjust. (windows_target): Delete function. (_initialize_windows_nat): Adjust. * darwin-nat.c (darwin_resume, darwin_wait_to, darwin_interrupt) (darwin_mourn_inferior, darwin_kill_inferior) (darwin_create_inferior, darwin_attach, darwin_detach) (darwin_pid_to_str, darwin_thread_alive, darwin_xfer_partial) (darwin_pid_to_exec_file, darwin_get_ada_task_ptid) (darwin_supports_multi_process): Refactor as darwin_nat_target methods. (darwin_resume_to, darwin_files_info): Delete. (_initialize_darwin_inferior): Rename to ... (_initialize_darwin_nat): ... this. Adjust to C++ification. * darwin-nat.h: Include "inf-child.h". (darwin_nat_target): New class. (darwin_complete_target): Delete. * i386-darwin-nat.c (i386_darwin_nat_target): New class. (darwin_target): New. (i386_darwin_fetch_inferior_registers) (i386_darwin_store_inferior_registers): Refactor as methods of darwin_nat_target. (darwin_complete_target): Delete, with ... (_initialize_i386_darwin_nat): ... bits factored out here. * alpha-linux-nat.c (alpha_linux_nat_target): New class. (the_alpha_linux_nat_target): New. (alpha_linux_register_u_offset): Refactor as alpha_linux_nat_target method. (_initialize_alpha_linux_nat): Adjust. * linux-nat-trad.c (inf_ptrace_register_u_offset): Delete. (inf_ptrace_fetch_register, inf_ptrace_fetch_registers) (inf_ptrace_store_register, inf_ptrace_store_registers): Refact as methods of linux_nat_trad_target. (linux_trad_target): Delete. * linux-nat-trad.h (linux_trad_target): Delete function. (linux_nat_trad_target): New class. * mips-linux-nat.c (mips_linux_nat_target): New class. (super_fetch_registers, super_store_registers, super_close): Delete. (the_mips_linux_nat_target): New. (mips64_linux_regsets_fetch_registers) (mips64_linux_regsets_store_registers) (mips64_linux_fetch_registers, mips64_linux_store_registers) (mips_linux_register_u_offset, mips_linux_read_description) (mips_linux_can_use_hw_breakpoint) (mips_linux_stopped_by_watchpoint) (mips_linux_stopped_data_address) (mips_linux_region_ok_for_hw_watchpoint) (mips_linux_insert_watchpoint, mips_linux_remove_watchpoint) (mips_linux_close): Refactor as methods of mips_linux_nat. (_initialize_mips_linux_nat): Adjust to C++ification. * aix-thread.c (aix_thread_target): New class. (aix_thread_ops): Now an aix_thread_target. (aix_thread_detach, aix_thread_resume, aix_thread_wait) (aix_thread_fetch_registers, aix_thread_store_registers) (aix_thread_xfer_partial, aix_thread_mourn_inferior) (aix_thread_thread_alive, aix_thread_pid_to_str) (aix_thread_extra_thread_info, aix_thread_get_ada_task_ptid): Refactor as methods of aix_thread_target. (init_aix_thread_ops): Delete. (_initialize_aix_thread): Remove references to init_aix_thread_ops and complete_target_initialization. * rs6000-nat.c (rs6000_xfer_shared_libraries): Delete. (rs6000_nat_target): New class. (the_rs6000_nat_target): New. (rs6000_fetch_inferior_registers, rs6000_store_inferior_registers) (rs6000_xfer_partial, rs6000_wait, rs6000_create_inferior) (rs6000_xfer_shared_libraries): Refactor as rs6000_nat_target methods. (super_create_inferior): Delete. (_initialize_rs6000_nat): Adjust to C++ification. * arm-linux-nat.c (arm_linux_nat_target): New class. (the_arm_linux_nat_target): New. (arm_linux_fetch_inferior_registers) (arm_linux_store_inferior_registers, arm_linux_read_description) (arm_linux_can_use_hw_breakpoint, arm_linux_insert_hw_breakpoint) (arm_linux_remove_hw_breakpoint) (arm_linux_region_ok_for_hw_watchpoint) (arm_linux_insert_watchpoint, arm_linux_remove_watchpoint) (arm_linux_stopped_data_address, arm_linux_stopped_by_watchpoint) (arm_linux_watchpoint_addr_within_range): Refactor as methods of arm_linux_nat_target. (_initialize_arm_linux_nat): Adjust to C++ification. * aarch64-linux-nat.c (aarch64_linux_nat_target): New class. (the_aarch64_linux_nat_target): New. (aarch64_linux_fetch_inferior_registers) (aarch64_linux_store_inferior_registers) (aarch64_linux_child_post_startup_inferior) (aarch64_linux_read_description) (aarch64_linux_can_use_hw_breakpoint) (aarch64_linux_insert_hw_breakpoint) (aarch64_linux_remove_hw_breakpoint) (aarch64_linux_insert_watchpoint, aarch64_linux_remove_watchpoint) (aarch64_linux_region_ok_for_hw_watchpoint) (aarch64_linux_stopped_data_address) (aarch64_linux_stopped_by_watchpoint) (aarch64_linux_watchpoint_addr_within_range) (aarch64_linux_can_do_single_step): Refactor as methods of aarch64_linux_nat_target. (super_post_startup_inferior): Delete. (_initialize_aarch64_linux_nat): Adjust to C++ification. * hppa-linux-nat.c (hppa_linux_nat_target): New class. (the_hppa_linux_nat_target): New. (hppa_linux_fetch_inferior_registers) (hppa_linux_store_inferior_registers): Refactor as methods of hppa_linux_nat_target. (_initialize_hppa_linux_nat): Adjust to C++ification. * ia64-linux-nat.c (ia64_linux_nat_target): New class. (the_ia64_linux_nat_target): New. (ia64_linux_insert_watchpoint, ia64_linux_remove_watchpoint) (ia64_linux_stopped_data_address) (ia64_linux_stopped_by_watchpoint, ia64_linux_fetch_registers) (ia64_linux_store_registers, ia64_linux_xfer_partial): Refactor as ia64_linux_nat_target methods. (super_xfer_partial): Delete. (_initialize_ia64_linux_nat): Adjust to C++ification. * m32r-linux-nat.c (m32r_linux_nat_target): New class. (the_m32r_linux_nat_target): New. (m32r_linux_fetch_inferior_registers) (m32r_linux_store_inferior_registers): Refactor as m32r_linux_nat_target methods. (_initialize_m32r_linux_nat): Adjust to C++ification. * m68k-linux-nat.c (m68k_linux_nat_target): New class. (the_m68k_linux_nat_target): New. (m68k_linux_fetch_inferior_registers) (m68k_linux_store_inferior_registers): Refactor as m68k_linux_nat_target methods. (_initialize_m68k_linux_nat): Adjust to C++ification. * s390-linux-nat.c (s390_linux_nat_target): New class. (the_s390_linux_nat_target): New. (s390_linux_fetch_inferior_registers) (s390_linux_store_inferior_registers, s390_stopped_by_watchpoint) (s390_insert_watchpoint, s390_remove_watchpoint) (s390_can_use_hw_breakpoint, s390_insert_hw_breakpoint) (s390_remove_hw_breakpoint, s390_region_ok_for_hw_watchpoint) (s390_auxv_parse, s390_read_description): Refactor as methods of s390_linux_nat_target. (_initialize_s390_nat): Adjust to C++ification. * sparc-linux-nat.c (sparc_linux_nat_target): New class. (the_sparc_linux_nat_target): New. (_initialize_sparc_linux_nat): Adjust to C++ification. * sparc-nat.c (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc64-linux-nat.c (sparc64_linux_nat_target): New class. (the_sparc64_linux_nat_target): New. (_initialize_sparc64_linux_nat): Adjust to C++ification. * spu-linux-nat.c (spu_linux_nat_target): New class. (the_spu_linux_nat_target): New. (spu_child_post_startup_inferior, spu_child_post_attach) (spu_child_wait, spu_fetch_inferior_registers) (spu_store_inferior_registers, spu_xfer_partial) (spu_can_use_hw_breakpoint): Refactor as spu_linux_nat_target methods. (_initialize_spu_nat): Adjust to C++ification. * tilegx-linux-nat.c (tilegx_linux_nat_target): New class. (the_tilegx_linux_nat_target): New. (fetch_inferior_registers, store_inferior_registers): Refactor as methods. (_initialize_tile_linux_nat): Adjust to C++ification. * xtensa-linux-nat.c (xtensa_linux_nat_target): New class. (the_xtensa_linux_nat_target): New. (xtensa_linux_fetch_inferior_registers) (xtensa_linux_store_inferior_registers): Refactor as xtensa_linux_nat_target methods. (_initialize_xtensa_linux_nat): Adjust to C++ification. * fbsd-nat.c (USE_SIGTRAP_SIGINFO): Delete. (fbsd_pid_to_exec_file, fbsd_find_memory_regions) (fbsd_find_memory_regions, fbsd_info_proc, fbsd_xfer_partial) (fbsd_thread_alive, fbsd_pid_to_str, fbsd_thread_name) (fbsd_update_thread_list, fbsd_resume, fbsd_wait) (fbsd_stopped_by_sw_breakpoint) (fbsd_supports_stopped_by_sw_breakpoint, fbsd_follow_fork) (fbsd_insert_fork_catchpoint, fbsd_remove_fork_catchpoint) (fbsd_insert_vfork_catchpoint, fbsd_remove_vfork_catchpoint) (fbsd_post_startup_inferior, fbsd_post_attach) (fbsd_insert_exec_catchpoint, fbsd_remove_exec_catchpoint) (fbsd_set_syscall_catchpoint) (super_xfer_partial, super_resume, super_wait) (fbsd_supports_stopped_by_hw_breakpoint): Delete. (fbsd_handle_debug_trap): Remove target_ops parameter. (fbsd_nat_add_target): Delete. * fbsd-nat.h: Include "inf-ptrace.h". (fbsd_nat_add_target): Delete. (USE_SIGTRAP_SIGINFO): Define. (fbsd_nat_target): New class. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers) (amd64bsd_store_inferior_registers): Remove target_ops parameter. (amd64bsd_target): Delete. * amd64-bsd-nat.h: New file. * amd64-fbsd-nat.c: Include "amd64-bsd-nat.h" instead of "x86-bsd-nat.h". (amd64_fbsd_nat_target): New class. (the_amd64_fbsd_nat_target): New. (amd64fbsd_read_description): Refactor as method of amd64_fbsd_nat_target. (amd64_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_amd64fbsd_nat): Adjust to C++ification. * amd64-nat.h (amd64bsd_target): Delete function declaration. * i386-bsd-nat.c (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Remove target_ops parameter. (i386bsd_target): Delete. * i386-bsd-nat.h (i386bsd_target): Delete function declaration. (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Declare. (i386_bsd_nat_target): New class. * i386-fbsd-nat.c (i386_fbsd_nat_target): New class. (the_i386_fbsd_nat_target): New. (i386fbsd_resume, i386fbsd_read_description): Refactor as i386_fbsd_nat_target methods. (i386_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_i386fbsd_nat): Adjust to C++ification. * x86-bsd-nat.c (super_mourn_inferior): Delete. (x86bsd_mourn_inferior, x86bsd_target): Delete. (_initialize_x86_bsd_nat): Adjust to C++ification. * x86-bsd-nat.h: Include "x86-nat.h". (x86bsd_target): Delete declaration. (x86bsd_nat_target): New class. * aarch64-fbsd-nat.c (aarch64_fbsd_nat_target): New class. (the_aarch64_fbsd_nat_target): New. (aarch64_fbsd_fetch_inferior_registers) (aarch64_fbsd_store_inferior_registers): Refactor as methods of aarch64_fbsd_nat_target. (_initialize_aarch64_fbsd_nat): Adjust to C++ification. * alpha-bsd-nat.c (alpha_bsd_nat_target): New class. (the_alpha_bsd_nat_target): New. (alphabsd_fetch_inferior_registers) (alphabsd_store_inferior_registers): Refactor as alpha_bsd_nat_target methods. (_initialize_alphabsd_nat): Refactor as methods of alpha_bsd_nat_target. * amd64-nbsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_nbsd_nat_target): New. (_initialize_amd64nbsd_nat): Adjust to C++ification. * amd64-obsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_obsd_nat_target): New. (_initialize_amd64obsd_nat): Adjust to C++ification. * arm-fbsd-nat.c (arm_fbsd_nat_target): New. (the_arm_fbsd_nat_target): New. (arm_fbsd_fetch_inferior_registers) (arm_fbsd_store_inferior_registers, arm_fbsd_read_description): (_initialize_arm_fbsd_nat): Refactor as methods of arm_fbsd_nat_target. (_initialize_arm_fbsd_nat): Adjust to C++ification. * arm-nbsd-nat.c (arm_netbsd_nat_target): New class. (the_arm_netbsd_nat_target): New. (armnbsd_fetch_registers, armnbsd_store_registers): Refactor as arm_netbsd_nat_target. (_initialize_arm_netbsd_nat): Adjust to C++ification. * hppa-nbsd-nat.c (hppa_nbsd_nat_target): New class. (the_hppa_nbsd_nat_target): New. (hppanbsd_fetch_registers, hppanbsd_store_registers): Refactor as hppa_nbsd_nat_target methods. (_initialize_hppanbsd_nat): Adjust to C++ification. * hppa-obsd-nat.c (hppa_obsd_nat_target): New class. (the_hppa_obsd_nat_target): New. (hppaobsd_fetch_registers, hppaobsd_store_registers): Refactor as methods of hppa_obsd_nat_target. (_initialize_hppaobsd_nat): Adjust to C++ification. Use add_target. * i386-nbsd-nat.c (the_i386_nbsd_nat_target): New. (_initialize_i386nbsd_nat): Adjust to C++ification. Use add_target. * i386-obsd-nat.c (the_i386_obsd_nat_target): New. (_initialize_i386obsd_nat): Use add_target. * m68k-bsd-nat.c (m68k_bsd_nat_target): New class. (the_m68k_bsd_nat_target): New. (m68kbsd_fetch_inferior_registers) (m68kbsd_store_inferior_registers): Refactor as methods of m68k_bsd_nat_target. (_initialize_m68kbsd_nat): Adjust to C++ification. * mips-fbsd-nat.c (mips_fbsd_nat_target): New class. (the_mips_fbsd_nat_target): New. (mips_fbsd_fetch_inferior_registers) (mips_fbsd_store_inferior_registers): Refactor as methods of mips_fbsd_nat_target. (_initialize_mips_fbsd_nat): Adjust to C++ification. Use add_target. * mips-nbsd-nat.c (mips_nbsd_nat_target): New class. (the_mips_nbsd_nat_target): New. (mipsnbsd_fetch_inferior_registers) (mipsnbsd_store_inferior_registers): Refactor as methods of mips_nbsd_nat_target. (_initialize_mipsnbsd_nat): Adjust to C++ification. * mips64-obsd-nat.c (mips64_obsd_nat_target): New class. (the_mips64_obsd_nat_target): New. (mips64obsd_fetch_inferior_registers) (mips64obsd_store_inferior_registers): Refactor as methods of mips64_obsd_nat_target. (_initialize_mips64obsd_nat): Adjust to C++ification. Use add_target. * nbsd-nat.c (nbsd_pid_to_exec_file): Refactor as method of nbsd_nat_target. * nbsd-nat.h: Include "inf-ptrace.h". (nbsd_nat_target): New class. * obsd-nat.c (obsd_pid_to_str, obsd_update_thread_list) (obsd_wait): Refactor as methods of obsd_nat_target. (obsd_add_target): Delete. * obsd-nat.h: Include "inf-ptrace.h". (obsd_nat_target): New class. * ppc-fbsd-nat.c (ppc_fbsd_nat_target): New class. (the_ppc_fbsd_nat_target): New. (ppcfbsd_fetch_inferior_registers) (ppcfbsd_store_inferior_registers): Refactor as methods of ppc_fbsd_nat_target. (_initialize_ppcfbsd_nat): Adjust to C++ification. Use add_target. * ppc-nbsd-nat.c (ppc_nbsd_nat_target): New class. (the_ppc_nbsd_nat_target): New. (ppcnbsd_fetch_inferior_registers) (ppcnbsd_store_inferior_registers): Refactor as methods of ppc_nbsd_nat_target. (_initialize_ppcnbsd_nat): Adjust to C++ification. * ppc-obsd-nat.c (ppc_obsd_nat_target): New class. (the_ppc_obsd_nat_target): New. (ppcobsd_fetch_registers, ppcobsd_store_registers): Refactor as methods of ppc_obsd_nat_target. (_initialize_ppcobsd_nat): Adjust to C++ification. Use add_target. * sh-nbsd-nat.c (sh_nbsd_nat_target): New class. (the_sh_nbsd_nat_target): New. (shnbsd_fetch_inferior_registers) (shnbsd_store_inferior_registers): Refactor as methods of sh_nbsd_nat_target. (_initialize_shnbsd_nat): Adjust to C++ification. * sparc-nat.c (sparc_xfer_wcookie): Make extern. (inf_ptrace_xfer_partial): Delete. (sparc_xfer_partial, sparc_target): Delete. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers, sparc_xfer_wcookie): Declare. (sparc_target): Delete function declaration. (sparc_target): New template class. * sparc-nbsd-nat.c (the_sparc_nbsd_nat_target): New. (_initialize_sparcnbsd_nat): Adjust to C++ification. * sparc64-fbsd-nat.c (the_sparc64_fbsd_nat_target): New. (_initialize_sparc64fbsd_nat): Adjust to C++ification. Use add_target. * sparc64-nbsd-nat.c (the_sparc64_nbsd_nat_target): New. (_initialize_sparc64nbsd_nat): Adjust to C++ification. * sparc64-obsd-nat.c (the_sparc64_obsd_nat_target): New. (_initialize_sparc64obsd_nat): Adjust to C++ification. Use add_target. * vax-bsd-nat.c (vax_bsd_nat_target): New class. (the_vax_bsd_nat_target): New. (vaxbsd_fetch_inferior_registers) (vaxbsd_store_inferior_registers): Refactor as vax_bsd_nat_target methods. (_initialize_vaxbsd_nat): Adjust to C++ification. * bsd-kvm.c (bsd_kvm_target): New class. (bsd_kvm_ops): Now a bsd_kvm_target. (bsd_kvm_open, bsd_kvm_close, bsd_kvm_xfer_partial) (bsd_kvm_files_info, bsd_kvm_fetch_registers) (bsd_kvm_thread_alive, bsd_kvm_pid_to_str): Refactor as methods of bsd_kvm_target. (bsd_kvm_return_one): Delete. (bsd_kvm_add_target): Adjust to C++ification. * nto-procfs.c (nto_procfs_target, nto_procfs_target_native) (nto_procfs_target_procfs): New classes. (procfs_open_1, procfs_thread_alive, procfs_update_thread_list) (procfs_files_info, procfs_pid_to_exec_file, procfs_attach) (procfs_post_attach, procfs_wait, procfs_fetch_registers) (procfs_xfer_partial, procfs_detach, procfs_insert_breakpoint) (procfs_remove_breakpoint, procfs_insert_hw_breakpoint) (procfs_remove_hw_breakpoint, procfs_resume) (procfs_mourn_inferior, procfs_create_inferior, procfs_interrupt) (procfs_kill_inferior, procfs_store_registers) (procfs_pass_signals, procfs_pid_to_str, procfs_can_run): Refactor as methods of nto_procfs_target. (nto_procfs_ops): Now an nto_procfs_target_procfs. (nto_native_ops): Delete. (procfs_open, procfs_native_open): Delete. (nto_native_ops): Now an nto_procfs_target_native. (init_procfs_targets): Adjust to C++ification. (procfs_can_use_hw_breakpoint, procfs_remove_hw_watchpoint) (procfs_insert_hw_watchpoint, procfs_stopped_by_watchpoint): Refactor as methods of nto_procfs_target. * go32-nat.c (go32_nat_target): New class. (the_go32_nat_target): New. (go32_attach, go32_resume, go32_wait, go32_fetch_registers) (go32_store_registers, go32_xfer_partial, go32_files_info) (go32_kill_inferior, go32_create_inferior, go32_mourn_inferior) (go32_terminal_init, go32_terminal_info, go32_terminal_inferior) (go32_terminal_ours, go32_pass_ctrlc, go32_thread_alive) (go32_pid_to_str): Refactor as methods of go32_nat_target. (go32_target): Delete. (_initialize_go32_nat): Adjust to C++ification. * gnu-nat.c (gnu_wait, gnu_resume, gnu_kill_inferior) (gnu_mourn_inferior, gnu_create_inferior, gnu_attach, gnu_detach) (gnu_stop, gnu_thread_alive, gnu_xfer_partial) (gnu_find_memory_regions, gnu_pid_to_str): Refactor as methods of gnu_nat_target. (gnu_target): Delete. * gnu-nat.h (gnu_target): Delete. (gnu_nat_target): New class. * i386-gnu-nat.c (gnu_base_target): New. (i386_gnu_nat_target): New class. (the_i386_gnu_nat_target): New. (_initialize_i386gnu_nat): Adjust to C++ification. gdb/testsuite/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * gdb.base/breakpoint-in-ro-region.exp: Adjust to to_resume and to_log_command renames. * gdb.base/sss-bp-on-user-bp-2.exp: Likewise.
2018-05-03 07:37:22 +08:00
struct ppc_linux_nat_target final : public linux_nat_target
{
/* Add our register access methods. */
void fetch_registers (struct regcache *, int) override;
void store_registers (struct regcache *, int) override;
/* Add our breakpoint/watchpoint methods. */
int can_use_hw_breakpoint (enum bptype, int, int) override;
int insert_hw_breakpoint (struct gdbarch *, struct bp_target_info *)
override;
int remove_hw_breakpoint (struct gdbarch *, struct bp_target_info *)
override;
int region_ok_for_hw_watchpoint (CORE_ADDR, int) override;
int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
struct expression *) override;
int remove_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
struct expression *) override;
int insert_mask_watchpoint (CORE_ADDR, CORE_ADDR, enum target_hw_bp_type)
override;
int remove_mask_watchpoint (CORE_ADDR, CORE_ADDR, enum target_hw_bp_type)
override;
target_ops: Use bool throughout After the previous target_ops/C++ patches are all squashed and merged, this one can go in separately. This patch adjusts all the target methods to return bool instead of int when they're returning a boolean. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * target.h (target_ops) <stopped_by_sw_breakpoint, supports_stopped_by_sw_breakpoint, stopped_by_hw_breakpoint, supports_stopped_by_hw_breakpoint, stopped_by_watchpoint, have_continuable_watchpoint, stopped_data_address, watchpoint_addr_within_range, can_accel_watchpoint_condition, can_run, thread_alive, has_all_memory, has_memory, has_stack, has_registers, has_execution, can_async_p, is_async_p, supports_non_stop, always_non_stop_p, can_execute_reverse, supports_multi_process, supports_enable_disable_tracepoint, supports_disable_randomization, supports_string_tracing, supports_evaluation_of_breakpoint_conditions, can_run_breakpoint_commands, filesystem_is_local, can_download_tracepoint, get_trace_state_variable_value, set_trace_notes, get_tib_address, use_agent, can_use_agent, record_is_replaying, record_will_replay, augmented_libraries_svr4_read>: Adjust to return bool. * aarch64-linux-nat.c: All implementations adjusted. * aix-thread.c: All implementations adjusted. * arm-linux-nat.c: All implementations adjusted. * breakpoint.c: All implementations adjusted. * bsd-kvm.c: All implementations adjusted. * bsd-uthread.c: All implementations adjusted. * corelow.c: All implementations adjusted. * ctf.c: All implementations adjusted. * darwin-nat.c: All implementations adjusted. * darwin-nat.h: All implementations adjusted. * exec.c: All implementations adjusted. * fbsd-nat.c: All implementations adjusted. * fbsd-nat.h: All implementations adjusted. * gnu-nat.c: All implementations adjusted. * gnu-nat.h: All implementations adjusted. * go32-nat.c: All implementations adjusted. * ia64-linux-nat.c: All implementations adjusted. * inf-child.c: All implementations adjusted. * inf-child.h: All implementations adjusted. * inf-ptrace.c: All implementations adjusted. * inf-ptrace.h: All implementations adjusted. * linux-nat.c: All implementations adjusted. * linux-nat.h: All implementations adjusted. * mips-linux-nat.c: All implementations adjusted. * nto-procfs.c: All implementations adjusted. * ppc-linux-nat.c: All implementations adjusted. * procfs.c: All implementations adjusted. * ravenscar-thread.c: All implementations adjusted. * record-btrace.c: All implementations adjusted. * record-full.c: All implementations adjusted. * remote-sim.c: All implementations adjusted. * remote.c: All implementations adjusted. * s390-linux-nat.c: All implementations adjusted. * sol-thread.c: All implementations adjusted. * spu-multiarch.c: All implementations adjusted. * target-delegates.c: All implementations adjusted. * target.c: All implementations adjusted. * target.h: All implementations adjusted. * tracefile-tfile.c: All implementations adjusted. * tracefile.c: All implementations adjusted. * tracefile.h: All implementations adjusted. * windows-nat.c: All implementations adjusted. * x86-linux-nat.h: All implementations adjusted. * x86-nat.h: All implementations adjusted.
2018-05-03 07:37:26 +08:00
bool watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int) override;
Convert struct target_ops to C++ I.e., use C++ virtual methods and inheritance instead of tables of function pointers. Unfortunately, there's no way to do a smooth transition. ALL native targets in the tree must be converted at the same time. I've tested all I could with cross compilers and with help from GCC compile farm, but naturally I haven't been able to test many of the ports. Still, I made a best effort to port everything over, and while I expect some build problems due to typos and such, which should be trivial to fix, I don't expect any design problems. * Implementation notes: - The flattened current_target is gone. References to current_target or current_target.beneath are replaced with references to target_stack (the top of the stack) directly. - To keep "set debug target" working, this adds a new debug_stratum layer that sits on top of the stack, prints the debug, and delegates to the target beneath. In addition, this makes the shortname and longname properties of target_ops be virtual methods instead of data fields, and makes the debug target defer those to the target beneath. This is so that debug code sprinkled around that does "if (debugtarget) ..." can transparently print the name of the target beneath. A patch later in the series actually splits out the shortname/longname methods to a separate structure, but I preferred to keep that chance separate as it is associated with changing a bit the design of how targets are registered and open. - Since you can't check whether a C++ virtual method is overridden, the old method of checking whether a target_ops implements a method by comparing the function pointer must be replaced with something else. Some cases are fixed by adding a parallel "can_do_foo" target_ops methods. E.g.,: + for (t = target_stack; t != NULL; t = t->beneath) { - if (t->to_create_inferior != NULL) + if (t->can_create_inferior ()) break; } Others are fixed by changing void return type to bool or int return type, and have the default implementation return false or -1, to indicate lack of support. - make-target-delegates was adjusted to generate C++ classes and methods. It needed tweaks to grok "virtual" in front of the target method name, and for the fact that methods are no longer function pointers. (In particular, the current code parsing the return type was simple because it could simply parse up until the '(' in '(*to_foo)'. It now generates a couple C++ classes that inherit target_ops: dummy_target and debug_target. Since we need to generate the class declarations as well, i.e., we need to emit methods twice, we now generate the code in two passes. - The core_target global is renamed to avoid conflict with the "core_target" class. - ctf/tfile targets init_tracefile_ops is replaced by a base class that is inherited by both ctf and tfile. - bsd-uthread The bsd_uthread_ops_hack hack is gone. It's not needed because nothing was extending a target created by bsd_uthread_target. - remote/extended-remote targets This is a first pass, just enough to C++ify target_ops. A later pass will convert more free functions to methods, and make remote_state be truly per remote instance, allowing multiple simultaneous instances of remote targets. - inf-child/"native" is converted to an actual base class (inf_child_target), that is inherited by all native targets. - GNU/Linux The old weird double-target linux_ops mechanism in linux-nat.c, is gone, replaced by adding a few virtual methods to linux-nat.h's target_ops, called low_XXX, that the concrete linux-nat implementations override. Sort of like gdbserver's linux_target_ops, but simpler, for requiring only one target_ops-like hierarchy, which spares implementing the same method twice when we need to forward the method to a low implementation. The low target simply reimplements the target_ops method directly in that case. There are a few remaining linux-nat.c hooks that would be better converted to low_ methods like above too. E.g.: linux_nat_set_new_thread (t, x86_linux_new_thread); linux_nat_set_new_fork (t, x86_linux_new_fork); linux_nat_set_forget_process That'll be done in a follow up patch. - We can no longer use functions like x86_use_watchpoints to install custom methods on an arbitrary base target. The patch replaces instances of such a pattern with template mixins. For example memory_breakpoint_target defined in target.h, or x86_nat_target in x86-nat.h. - linux_trad_target, MIPS and Alpha GNU/Linux The code in the new linux-nat-trad.h/c files which was split off of inf-ptrace.h/c recently, is converted to a C++ base class, and used by the MIPS and Alpha GNU/Linux ports. - BSD targets The $architecture x NetBSD/OpenBSD/FreeBSD support matrix complicates things a bit. There's common BSD target code, and there's common architecture-specific code shared between the different BSDs. Currently, all that is stiched together to form a final target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target functions etc. This introduces new fbsd_nat_target, obsd_nat_target and nbsd_nat_target classes that serve as base/prototype target for the corresponding BSD variant. And introduces generic i386/AMD64 BSD targets, to be used as template mixin to build a final target. Similarly, a generic SPARC target is added, used by both BSD and Linux ports. - bsd_kvm_add_target, BSD libkvm target I considered making bsd_kvm_supply_pcb a virtual method, and then have each port inherit bsd_kvm_target and override that method, but that was resulting in lots of unjustified churn, so I left the function pointer mechanism alone. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> John Baldwin <jhb@freebsd.org> * target.h (enum strata) <debug_stratum>: New. (struct target_ops) <all delegation methods>: Replace by C++ virtual methods, and drop "to_" prefix. All references updated throughout. <to_shortname, to_longname, to_doc, to_data, to_have_steppable_watchpoint, to_have_continuable_watchpoint, to_has_thread_control, to_attach_no_wait>: Delete, replaced by virtual methods. All references updated throughout. <can_attach, supports_terminal_ours, can_create_inferior, get_thread_control_capabilities, attach_no_wait>: New virtual methods. <insert_breakpoint, remove_breakpoint>: Now TARGET_DEFAULT_NORETURN methods. <info_proc>: Now returns bool. <to_magic>: Delete. (OPS_MAGIC): Delete. (current_target): Delete. All references replaced by references to ... (target_stack): ... this. New. (target_shortname, target_longname): Adjust. (target_can_run): Now a function declaration. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (memory_breakpoint_target): New template class. (test_target_ops): Refactor as a C++ class with virtual methods. * make-target-delegates (NAME_PART): Tighten. (POINTER_PART, CP_SYMBOL): New. (SIMPLE_RETURN_PART): Reimplement. (VEC_RETURN_PART): Expect less. (RETURN_PART, VIRTUAL_PART): New. (METHOD): Adjust to C++ virtual methods. (scan_target_h): Remove reference to C99. (dname): Output "target_ops::" prefix. (write_function_header): Adjust to output a C++ class method. (write_declaration): New. (write_delegator): Adjust to output a C++ class method. (tdname): Output "dummy_target::" prefix. (write_tdefault, write_debugmethod): Adjust to output a C++ class method. (tdefault_names, debug_names): Delete. (return_types, tdefaults, styles, argtypes_array): New. (top level): All methods are delegators. (print_class): New. (top level): Print dummy_target and debug_target classes. * target-delegates.c: Regenerate. * target-debug.h (target_debug_print_enum_info_proc_what) (target_debug_print_thread_control_capabilities) (target_debug_print_thread_info_p): New. * target.c (dummy_target): Delete. (the_dummy_target, the_debug_target): New. (target_stack): Now extern. (set_targetdebug): Push/unpush debug target. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (add_target_with_completer): No longer call complete_target_initialization. (target_supports_terminal_ours): Use regular delegation. (update_current_target): Delete. (push_target): No longer check magic number. Don't call update_current_target. (unpush_target): Don't call update_current_target. (target_is_pushed): No longer check magic number. (target_require_runnable): Skip for all stratums over process_stratum. (target_ops::info_proc): New. (target_info_proc): Use find_target_at and find_default_run_target. (target_supports_disable_randomization): Use regular delegation. (target_get_osdata): Use find_target_at. (target_ops::open, target_ops::close, target_ops::can_attach) (target_ops::attach, target_ops::can_create_inferior) (target_ops::create_inferior, target_ops::can_run) (target_can_run): New. (default_fileio_target): Use regular delegation. (target_ops::fileio_open, target_ops::fileio_pwrite) (target_ops::fileio_pread, target_ops::fileio_fstat) (target_ops::fileio_close, target_ops::fileio_unlink) (target_ops::fileio_readlink): New. (target_fileio_open_1, target_fileio_unlink) (target_fileio_readlink): Always call the target method. Handle FILEIO_ENOSYS. (return_zero, return_zero_has_execution): Delete. (init_dummy_target): Delete. (dummy_target::dummy_target, dummy_target::shortname) (dummy_target::longname, dummy_target::doc) (debug_target::debug_target, debug_target::shortname) (debug_target::longname, debug_target::doc): New. (target_supports_delete_record): Use regular delegation. (setup_target_debug): Delete. (maintenance_print_target_stack): Skip debug_stratum. (initialize_targets): Instantiate the_dummy_target and the_debug_target. * auxv.c (target_auxv_parse): Remove 'ops' parameter. Adjust to use target_stack. (target_auxv_search, fprint_target_auxv): Adjust. (info_auxv_command): Adjust to use target_stack. * auxv.h (target_auxv_parse): Remove 'ops' parameter. * exceptions.c (print_flush): Handle a NULL target_stack. * regcache.c (target_ops_no_register): Refactor as class with virtual methods. * exec.c (exec_target): New class. (exec_ops): Now an exec_target. (exec_open, exec_close_1, exec_get_section_table) (exec_xfer_partial, exec_files_info, exec_has_memory) (exec_make_note_section): Refactor as exec_target methods. (exec_file_clear, ignore, exec_remove_breakpoint, init_exec_ops): Delete. (exec_target::find_memory_regions): New. (_initialize_exec): Don't call init_exec_ops. * gdbcore.h (exec_file_clear): Delete. * corefile.c (core_target): Delete. (core_file_command): Adjust. * corelow.c (core_target): New class. (the_core_target): New. (core_close): Remove target_ops parameter. (core_close_cleanup): Adjust. (core_target::close): New. (core_open, core_detach, get_core_registers, core_files_info) (core_xfer_partial, core_thread_alive, core_read_description) (core_pid_to_str, core_thread_name, core_has_memory) (core_has_stack, core_has_registers, core_info_proc): Rework as core_target methods. (ignore, core_remove_breakpoint, init_core_ops): Delete. (_initialize_corelow): Initialize the_core_target. * gdbcore.h (core_target): Delete. (the_core_target): New. * ctf.c: (ctf_target): New class. (ctf_ops): Now a ctf_target. (ctf_open, ctf_close, ctf_files_info, ctf_fetch_registers) (ctf_xfer_partial, ctf_get_trace_state_variable_value) (ctf_trace_find, ctf_traceframe_info): Refactor as ctf_target methods. (init_ctf_ops): Delete. (_initialize_ctf): Don't call it. * tracefile-tfile.c (tfile_target): New class. (tfile_ops): Now a tfile_target. (tfile_open, tfile_close, tfile_files_info) (tfile_get_tracepoint_status, tfile_trace_find) (tfile_fetch_registers, tfile_xfer_partial) (tfile_get_trace_state_variable_value, tfile_traceframe_info): Refactor as tfile_target methods. (tfile_xfer_partial_features): Remove target_ops parameter. (init_tfile_ops): Delete. (_initialize_tracefile_tfile): Don't call it. * tracefile.c (tracefile_has_all_memory, tracefile_has_memory) (tracefile_has_stack, tracefile_has_registers) (tracefile_thread_alive, tracefile_get_trace_status): Refactor as tracefile_target methods. (init_tracefile_ops): Delete. (tracefile_target::tracefile_target): New. * tracefile.h: Include "target.h". (tracefile_target): New class. (init_tracefile_ops): Delete. * spu-multiarch.c (spu_multiarch_target): New class. (spu_ops): Now a spu_multiarch_target. (spu_thread_architecture, spu_region_ok_for_hw_watchpoint) (spu_fetch_registers, spu_store_registers, spu_xfer_partial) (spu_search_memory, spu_mourn_inferior): Refactor as spu_multiarch_target methods. (init_spu_ops): Delete. (_initialize_spu_multiarch): Remove references to init_spu_ops, complete_target_initialization. * ravenscar-thread.c (ravenscar_thread_target): New class. (ravenscar_ops): Now a ravenscar_thread_target. (ravenscar_resume, ravenscar_wait, ravenscar_update_thread_list) (ravenscar_thread_alive, ravenscar_pid_to_str) (ravenscar_fetch_registers, ravenscar_store_registers) (ravenscar_prepare_to_store, ravenscar_stopped_by_sw_breakpoint) (ravenscar_stopped_by_hw_breakpoint) (ravenscar_stopped_by_watchpoint, ravenscar_stopped_data_address) (ravenscar_mourn_inferior, ravenscar_core_of_thread) (ravenscar_get_ada_task_ptid): Refactor as ravenscar_thread_target methods. (init_ravenscar_thread_ops): Delete. (_initialize_ravenscar): Remove references to init_ravenscar_thread_ops and complete_target_initialization. * bsd-uthread.c (bsd_uthread_ops_hack): Delete. (bsd_uthread_target): New class. (bsd_uthread_ops): Now a bsd_uthread_target. (bsd_uthread_activate): Adjust to refer to bsd_uthread_ops. (bsd_uthread_close, bsd_uthread_mourn_inferior) (bsd_uthread_fetch_registers, bsd_uthread_store_registers) (bsd_uthread_wait, bsd_uthread_resume, bsd_uthread_thread_alive) (bsd_uthread_update_thread_list, bsd_uthread_extra_thread_info) (bsd_uthread_pid_to_str): Refactor as bsd_uthread_target methods. (bsd_uthread_target): Delete function. (_initialize_bsd_uthread): Remove reference to complete_target_initialization. * bfd-target.c (target_bfd_data): Delete. Fields folded into ... (target_bfd): ... this new class. (target_bfd_xfer_partial, target_bfd_get_section_table) (target_bfd_close): Refactor as target_bfd methods. (target_bfd::~target_bfd): New. (target_bfd_reopen): Adjust. (target_bfd::close): New. * record-btrace.c (record_btrace_target): New class. (record_btrace_ops): Now a record_btrace_target. (record_btrace_open, record_btrace_stop_recording) (record_btrace_disconnect, record_btrace_close) (record_btrace_async, record_btrace_info) (record_btrace_insn_history, record_btrace_insn_history_range) (record_btrace_insn_history_from, record_btrace_call_history) (record_btrace_call_history_range) (record_btrace_call_history_from, record_btrace_record_method) (record_btrace_is_replaying, record_btrace_will_replay) (record_btrace_xfer_partial, record_btrace_insert_breakpoint) (record_btrace_remove_breakpoint, record_btrace_fetch_registers) (record_btrace_store_registers, record_btrace_prepare_to_store) (record_btrace_to_get_unwinder) (record_btrace_to_get_tailcall_unwinder, record_btrace_resume) (record_btrace_commit_resume, record_btrace_wait) (record_btrace_stop, record_btrace_can_execute_reverse) (record_btrace_stopped_by_sw_breakpoint) (record_btrace_supports_stopped_by_sw_breakpoint) (record_btrace_stopped_by_hw_breakpoint) (record_btrace_supports_stopped_by_hw_breakpoint) (record_btrace_update_thread_list, record_btrace_thread_alive) (record_btrace_goto_begin, record_btrace_goto_end) (record_btrace_goto, record_btrace_stop_replaying_all) (record_btrace_execution_direction) (record_btrace_prepare_to_generate_core) (record_btrace_done_generating_core): Refactor as record_btrace_target methods. (init_record_btrace_ops): Delete. (_initialize_record_btrace): Remove reference to init_record_btrace_ops. * record-full.c (RECORD_FULL_IS_REPLAY): Adjust to always refer to the execution_direction global. (record_full_base_target, record_full_target) (record_full_core_target): New classes. (record_full_ops): Now a record_full_target. (record_full_core_ops): Now a record_full_core_target. (record_full_target::detach, record_full_target::disconnect) (record_full_core_target::disconnect) (record_full_target::mourn_inferior, record_full_target::kill): New. (record_full_open, record_full_close, record_full_async): Refactor as methods of the record_full_base_target class. (record_full_resume, record_full_commit_resume): Refactor as methods of the record_full_target class. (record_full_wait, record_full_stopped_by_watchpoint) (record_full_stopped_data_address) (record_full_stopped_by_sw_breakpoint) (record_full_supports_stopped_by_sw_breakpoint) (record_full_stopped_by_hw_breakpoint) (record_full_supports_stopped_by_hw_breakpoint): Refactor as methods of the record_full_base_target class. (record_full_store_registers, record_full_xfer_partial) (record_full_insert_breakpoint, record_full_remove_breakpoint): Refactor as methods of the record_full_target class. (record_full_can_execute_reverse, record_full_get_bookmark) (record_full_goto_bookmark, record_full_execution_direction) (record_full_record_method, record_full_info, record_full_delete) (record_full_is_replaying, record_full_will_replay) (record_full_goto_begin, record_full_goto_end, record_full_goto) (record_full_stop_replaying): Refactor as methods of the record_full_base_target class. (record_full_core_resume, record_full_core_kill) (record_full_core_fetch_registers) (record_full_core_prepare_to_store) (record_full_core_store_registers, record_full_core_xfer_partial) (record_full_core_insert_breakpoint) (record_full_core_remove_breakpoint) (record_full_core_has_execution): Refactor as methods of the record_full_core_target class. (record_full_base_target::supports_delete_record): New. (init_record_full_ops): Delete. (init_record_full_core_ops): Delete. (record_full_save): Refactor as method of the record_full_base_target class. (_initialize_record_full): Remove references to init_record_full_ops and init_record_full_core_ops. * remote.c (remote_target, extended_remote_target): New classes. (remote_ops): Now a remote_target. (extended_remote_ops): Now an extended_remote_target. (remote_insert_fork_catchpoint, remote_remove_fork_catchpoint) (remote_insert_vfork_catchpoint, remote_remove_vfork_catchpoint) (remote_insert_exec_catchpoint, remote_remove_exec_catchpoint) (remote_pass_signals, remote_set_syscall_catchpoint) (remote_program_signals, ) (remote_thread_always_alive): Remove target_ops parameter. (remote_thread_alive, remote_thread_name) (remote_update_thread_list, remote_threads_extra_info) (remote_static_tracepoint_marker_at) (remote_static_tracepoint_markers_by_strid) (remote_get_ada_task_ptid, remote_close, remote_start_remote) (remote_open): Refactor as methods of remote_target. (extended_remote_open, extended_remote_detach) (extended_remote_attach, extended_remote_post_attach): (extended_remote_supports_disable_randomization) (extended_remote_create_inferior): : Refactor as method of extended_remote_target. (remote_set_permissions, remote_open_1, remote_detach) (remote_follow_fork, remote_follow_exec, remote_disconnect) (remote_resume, remote_commit_resume, remote_stop) (remote_interrupt, remote_pass_ctrlc, remote_terminal_inferior) (remote_terminal_ours, remote_wait, remote_fetch_registers) (remote_prepare_to_store, remote_store_registers) (remote_flash_erase, remote_flash_done, remote_files_info) (remote_kill, remote_mourn, remote_insert_breakpoint) (remote_remove_breakpoint, remote_insert_watchpoint) (remote_watchpoint_addr_within_range) (remote_remove_watchpoint, remote_region_ok_for_hw_watchpoint) (remote_check_watch_resources, remote_stopped_by_sw_breakpoint) (remote_supports_stopped_by_sw_breakpoint) (remote_stopped_by_hw_breakpoint) (remote_supports_stopped_by_hw_breakpoint) (remote_stopped_by_watchpoint, remote_stopped_data_address) (remote_insert_hw_breakpoint, remote_remove_hw_breakpoint) (remote_verify_memory): Refactor as methods of remote_target. (remote_write_qxfer, remote_read_qxfer): Remove target_ops parameter. (remote_xfer_partial, remote_get_memory_xfer_limit) (remote_search_memory, remote_rcmd, remote_memory_map) (remote_pid_to_str, remote_get_thread_local_address) (remote_get_tib_address, remote_read_description): Refactor as methods of remote_target. (remote_target::fileio_open, remote_target::fileio_pwrite) (remote_target::fileio_pread, remote_target::fileio_close): New. (remote_hostio_readlink, remote_hostio_fstat) (remote_filesystem_is_local, remote_can_execute_reverse) (remote_supports_non_stop, remote_supports_disable_randomization) (remote_supports_multi_process, remote_supports_cond_breakpoints) (remote_supports_enable_disable_tracepoint) (remote_supports_string_tracing) (remote_can_run_breakpoint_commands, remote_trace_init) (remote_download_tracepoint, remote_can_download_tracepoint) (remote_download_trace_state_variable, remote_enable_tracepoint) (remote_disable_tracepoint, remote_trace_set_readonly_regions) (remote_trace_start, remote_get_trace_status) (remote_get_tracepoint_status, remote_trace_stop) (remote_trace_find, remote_get_trace_state_variable_value) (remote_save_trace_data, remote_get_raw_trace_data) (remote_set_disconnected_tracing, remote_core_of_thread) (remote_set_circular_trace_buffer, remote_traceframe_info) (remote_get_min_fast_tracepoint_insn_len) (remote_set_trace_buffer_size, remote_set_trace_notes) (remote_use_agent, remote_can_use_agent, remote_enable_btrace) (remote_disable_btrace, remote_teardown_btrace) (remote_read_btrace, remote_btrace_conf) (remote_augmented_libraries_svr4_read, remote_load) (remote_pid_to_exec_file, remote_can_do_single_step) (remote_execution_direction, remote_thread_handle_to_thread_info): Refactor as methods of remote_target. (init_remote_ops, init_extended_remote_ops): Delete. (remote_can_async_p, remote_is_async_p, remote_async) (remote_thread_events, remote_upload_tracepoints) (remote_upload_trace_state_variables): Refactor as methods of remote_target. (_initialize_remote): Remove references to init_remote_ops and init_extended_remote_ops. * remote-sim.c (gdbsim_target): New class. (gdbsim_fetch_register, gdbsim_store_register, gdbsim_kill) (gdbsim_load, gdbsim_create_inferior, gdbsim_open, gdbsim_close) (gdbsim_detach, gdbsim_resume, gdbsim_interrupt) (gdbsim_wait, gdbsim_prepare_to_store, gdbsim_xfer_partial) (gdbsim_files_info, gdbsim_mourn_inferior, gdbsim_thread_alive) (gdbsim_pid_to_str, gdbsim_has_all_memory, gdbsim_has_memory): Refactor as methods of gdbsim_target. (gdbsim_ops): Now a gdbsim_target. (init_gdbsim_ops): Delete. (gdbsim_cntrl_c): Adjust. (_initialize_remote_sim): Remove reference to init_gdbsim_ops. * amd64-linux-nat.c (amd64_linux_nat_target): New class. (the_amd64_linux_nat_target): New. (amd64_linux_fetch_inferior_registers) (amd64_linux_store_inferior_registers): Refactor as methods of amd64_linux_nat_target. (_initialize_amd64_linux_nat): Adjust. Set linux_target. * i386-linux-nat.c: Don't include "linux-nat.h". (i386_linux_nat_target): New class. (the_i386_linux_nat_target): New. (i386_linux_fetch_inferior_registers) (i386_linux_store_inferior_registers, i386_linux_resume): Refactor as methods of i386_linux_nat_target. (_initialize_i386_linux_nat): Adjust. Set linux_target. * inf-child.c (inf_child_ops): Delete. (inf_child_fetch_inferior_registers) (inf_child_store_inferior_registers): Delete. (inf_child_post_attach, inf_child_prepare_to_store): Refactor as methods of inf_child_target. (inf_child_target::supports_terminal_ours) (inf_child_target::terminal_init) (inf_child_target::terminal_inferior) (inf_child_target::terminal_ours_for_output) (inf_child_target::terminal_ours, inf_child_target::interrupt) (inf_child_target::pass_ctrlc, inf_child_target::terminal_info): New. (inf_child_open, inf_child_disconnect, inf_child_close) (inf_child_mourn_inferior, inf_child_maybe_unpush_target) (inf_child_post_startup_inferior, inf_child_can_run) (inf_child_pid_to_exec_file): Refactor as methods of inf_child_target. (inf_child_follow_fork): Delete. (inf_child_target::can_create_inferior) (inf_child_target::can_attach): New. (inf_child_target::has_all_memory, inf_child_target::has_memory) (inf_child_target::has_stack, inf_child_target::has_registers) (inf_child_target::has_execution): New. (inf_child_fileio_open, inf_child_fileio_pwrite) (inf_child_fileio_pread, inf_child_fileio_fstat) (inf_child_fileio_close, inf_child_fileio_unlink) (inf_child_fileio_readlink, inf_child_use_agent) (inf_child_can_use_agent): Refactor as methods of inf_child_target. (return_zero, inf_child_target): Delete. (inf_child_target::inf_child_target): New. * inf-child.h: Include "target.h". (inf_child_target): Delete function prototype. (inf_child_target): New class. (inf_child_open_target, inf_child_mourn_inferior) (inf_child_maybe_unpush_target): Delete. * inf-ptrace.c (inf_ptrace_target::~inf_ptrace_target): New. (inf_ptrace_follow_fork, inf_ptrace_insert_fork_catchpoint) (inf_ptrace_remove_fork_catchpoint, inf_ptrace_create_inferior) (inf_ptrace_post_startup_inferior, inf_ptrace_mourn_inferior) (inf_ptrace_attach, inf_ptrace_post_attach, inf_ptrace_detach) (inf_ptrace_detach_success, inf_ptrace_kill, inf_ptrace_resume) (inf_ptrace_wait, inf_ptrace_xfer_partial) (inf_ptrace_thread_alive, inf_ptrace_files_info) (inf_ptrace_pid_to_str, inf_ptrace_auxv_parse): Refactor as methods of inf_ptrace_target. (inf_ptrace_target): Delete function. * inf-ptrace.h: Include "inf-child.h". (inf_ptrace_target): Delete function declaration. (inf_ptrace_target): New class. (inf_ptrace_trad_target, inf_ptrace_detach_success): Delete. * linux-nat.c (linux_target): New. (linux_ops, linux_ops_saved, super_xfer_partial): Delete. (linux_nat_target::~linux_nat_target): New. (linux_child_post_attach, linux_child_post_startup_inferior) (linux_child_follow_fork, linux_child_insert_fork_catchpoint) (linux_child_remove_fork_catchpoint) (linux_child_insert_vfork_catchpoint) (linux_child_remove_vfork_catchpoint) (linux_child_insert_exec_catchpoint) (linux_child_remove_exec_catchpoint) (linux_child_set_syscall_catchpoint, linux_nat_pass_signals) (linux_nat_create_inferior, linux_nat_attach, linux_nat_detach) (linux_nat_resume, linux_nat_stopped_by_watchpoint) (linux_nat_stopped_data_address) (linux_nat_stopped_by_sw_breakpoint) (linux_nat_supports_stopped_by_sw_breakpoint) (linux_nat_stopped_by_hw_breakpoint) (linux_nat_supports_stopped_by_hw_breakpoint, linux_nat_wait) (linux_nat_kill, linux_nat_mourn_inferior) (linux_nat_xfer_partial, linux_nat_thread_alive) (linux_nat_update_thread_list, linux_nat_pid_to_str) (linux_nat_thread_name, linux_child_pid_to_exec_file) (linux_child_static_tracepoint_markers_by_strid) (linux_nat_is_async_p, linux_nat_can_async_p) (linux_nat_supports_non_stop, linux_nat_always_non_stop_p) (linux_nat_supports_multi_process) (linux_nat_supports_disable_randomization, linux_nat_async) (linux_nat_stop, linux_nat_close, linux_nat_thread_address_space) (linux_nat_core_of_thread, linux_nat_filesystem_is_local) (linux_nat_fileio_open, linux_nat_fileio_readlink) (linux_nat_fileio_unlink, linux_nat_thread_events): Refactor as methods of linux_nat_target. (linux_nat_wait_1, linux_xfer_siginfo, linux_proc_xfer_partial) (linux_proc_xfer_spu, linux_nat_xfer_osdata): Remove target_ops parameter. (check_stopped_by_watchpoint): Adjust. (linux_xfer_partial): Delete. (linux_target_install_ops, linux_target, linux_nat_add_target): Delete. (linux_nat_target::linux_nat_target): New. * linux-nat.h: Include "inf-ptrace.h". (linux_nat_target): New. (linux_target, linux_target_install_ops, linux_nat_add_target): Delete function declarations. (linux_target): Declare global. * linux-thread-db.c (thread_db_target): New. (thread_db_target::thread_db_target): New. (thread_db_ops): Delete. (the_thread_db_target): New. (thread_db_detach, thread_db_wait, thread_db_mourn_inferior) (thread_db_update_thread_list, thread_db_pid_to_str) (thread_db_extra_thread_info) (thread_db_thread_handle_to_thread_info) (thread_db_get_thread_local_address, thread_db_get_ada_task_ptid) (thread_db_resume): Refactor as methods of thread_db_target. (init_thread_db_ops): Delete. (_initialize_thread_db): Remove reference to init_thread_db_ops. * x86-linux-nat.c: Don't include "linux-nat.h". (super_post_startup_inferior): Delete. (x86_linux_nat_target::~x86_linux_nat_target): New. (x86_linux_child_post_startup_inferior) (x86_linux_read_description, x86_linux_enable_btrace) (x86_linux_disable_btrace, x86_linux_teardown_btrace) (x86_linux_read_btrace, x86_linux_btrace_conf): Refactor as methods of x86_linux_nat_target. (x86_linux_create_target): Delete. Bits folded ... (x86_linux_add_target): ... here. Now takes a linux_nat_target pointer. * x86-linux-nat.h: Include "linux-nat.h" and "x86-nat.h". (x86_linux_nat_target): New class. (x86_linux_create_target): Delete. (x86_linux_add_target): Now takes a linux_nat_target pointer. * x86-nat.c (x86_insert_watchpoint, x86_remove_watchpoint) (x86_region_ok_for_watchpoint, x86_stopped_data_address) (x86_stopped_by_watchpoint, x86_insert_hw_breakpoint) (x86_remove_hw_breakpoint, x86_can_use_hw_breakpoint) (x86_stopped_by_hw_breakpoint): Remove target_ops parameter and make extern. (x86_use_watchpoints): Delete. * x86-nat.h: Include "breakpoint.h" and "target.h". (x86_use_watchpoints): Delete. (x86_can_use_hw_breakpoint, x86_region_ok_for_hw_watchpoint) (x86_stopped_by_watchpoint, x86_stopped_data_address) (x86_insert_watchpoint, x86_remove_watchpoint) (x86_insert_hw_breakpoint, x86_remove_hw_breakpoint) (x86_stopped_by_hw_breakpoint): New declarations. (x86_nat_target): New template class. * ppc-linux-nat.c (ppc_linux_nat_target): New class. (the_ppc_linux_nat_target): New. (ppc_linux_fetch_inferior_registers) (ppc_linux_can_use_hw_breakpoint) (ppc_linux_region_ok_for_hw_watchpoint) (ppc_linux_ranged_break_num_registers) (ppc_linux_insert_hw_breakpoint, ppc_linux_remove_hw_breakpoint) (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_can_accel_watchpoint_condition) (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint) (ppc_linux_stopped_data_address, ppc_linux_stopped_by_watchpoint) (ppc_linux_watchpoint_addr_within_range) (ppc_linux_masked_watch_num_registers) (ppc_linux_store_inferior_registers, ppc_linux_auxv_parse) (ppc_linux_read_description): Refactor as methods of ppc_linux_nat_target. (_initialize_ppc_linux_nat): Adjust. Set linux_target. * procfs.c (procfs_xfer_partial): Delete forward declaration. (procfs_target): New class. (the_procfs_target): New. (procfs_target): Delete function. (procfs_auxv_parse, procfs_attach, procfs_detach) (procfs_fetch_registers, procfs_store_registers, procfs_wait) (procfs_xfer_partial, procfs_resume, procfs_pass_signals) (procfs_files_info, procfs_kill_inferior, procfs_mourn_inferior) (procfs_create_inferior, procfs_update_thread_list) (procfs_thread_alive, procfs_pid_to_str) (procfs_can_use_hw_breakpoint, procfs_stopped_by_watchpoint) (procfs_stopped_data_address, procfs_insert_watchpoint) (procfs_remove_watchpoint, procfs_region_ok_for_hw_watchpoint) (proc_find_memory_regions, procfs_info_proc) (procfs_make_note_section): Refactor as methods of procfs_target. (_initialize_procfs): Adjust. * sol-thread.c (sol_thread_target): New class. (sol_thread_ops): Now a sol_thread_target. (sol_thread_detach, sol_thread_resume, sol_thread_wait) (sol_thread_fetch_registers, sol_thread_store_registers) (sol_thread_xfer_partial, sol_thread_mourn_inferior) (sol_thread_alive, solaris_pid_to_str, sol_update_thread_list) (sol_get_ada_task_ptid): Refactor as methods of sol_thread_target. (init_sol_thread_ops): Delete. (_initialize_sol_thread): Adjust. Remove references to init_sol_thread_ops and complete_target_initialization. * windows-nat.c (windows_nat_target): New class. (windows_fetch_inferior_registers) (windows_store_inferior_registers, windows_resume, windows_wait) (windows_attach, windows_detach, windows_pid_to_exec_file) (windows_files_info, windows_create_inferior) (windows_mourn_inferior, windows_interrupt, windows_kill_inferior) (windows_close, windows_pid_to_str, windows_xfer_partial) (windows_get_tib_address, windows_get_ada_task_ptid) (windows_thread_name, windows_thread_alive): Refactor as windows_nat_target methods. (do_initial_windows_stuff): Adjust. (windows_target): Delete function. (_initialize_windows_nat): Adjust. * darwin-nat.c (darwin_resume, darwin_wait_to, darwin_interrupt) (darwin_mourn_inferior, darwin_kill_inferior) (darwin_create_inferior, darwin_attach, darwin_detach) (darwin_pid_to_str, darwin_thread_alive, darwin_xfer_partial) (darwin_pid_to_exec_file, darwin_get_ada_task_ptid) (darwin_supports_multi_process): Refactor as darwin_nat_target methods. (darwin_resume_to, darwin_files_info): Delete. (_initialize_darwin_inferior): Rename to ... (_initialize_darwin_nat): ... this. Adjust to C++ification. * darwin-nat.h: Include "inf-child.h". (darwin_nat_target): New class. (darwin_complete_target): Delete. * i386-darwin-nat.c (i386_darwin_nat_target): New class. (darwin_target): New. (i386_darwin_fetch_inferior_registers) (i386_darwin_store_inferior_registers): Refactor as methods of darwin_nat_target. (darwin_complete_target): Delete, with ... (_initialize_i386_darwin_nat): ... bits factored out here. * alpha-linux-nat.c (alpha_linux_nat_target): New class. (the_alpha_linux_nat_target): New. (alpha_linux_register_u_offset): Refactor as alpha_linux_nat_target method. (_initialize_alpha_linux_nat): Adjust. * linux-nat-trad.c (inf_ptrace_register_u_offset): Delete. (inf_ptrace_fetch_register, inf_ptrace_fetch_registers) (inf_ptrace_store_register, inf_ptrace_store_registers): Refact as methods of linux_nat_trad_target. (linux_trad_target): Delete. * linux-nat-trad.h (linux_trad_target): Delete function. (linux_nat_trad_target): New class. * mips-linux-nat.c (mips_linux_nat_target): New class. (super_fetch_registers, super_store_registers, super_close): Delete. (the_mips_linux_nat_target): New. (mips64_linux_regsets_fetch_registers) (mips64_linux_regsets_store_registers) (mips64_linux_fetch_registers, mips64_linux_store_registers) (mips_linux_register_u_offset, mips_linux_read_description) (mips_linux_can_use_hw_breakpoint) (mips_linux_stopped_by_watchpoint) (mips_linux_stopped_data_address) (mips_linux_region_ok_for_hw_watchpoint) (mips_linux_insert_watchpoint, mips_linux_remove_watchpoint) (mips_linux_close): Refactor as methods of mips_linux_nat. (_initialize_mips_linux_nat): Adjust to C++ification. * aix-thread.c (aix_thread_target): New class. (aix_thread_ops): Now an aix_thread_target. (aix_thread_detach, aix_thread_resume, aix_thread_wait) (aix_thread_fetch_registers, aix_thread_store_registers) (aix_thread_xfer_partial, aix_thread_mourn_inferior) (aix_thread_thread_alive, aix_thread_pid_to_str) (aix_thread_extra_thread_info, aix_thread_get_ada_task_ptid): Refactor as methods of aix_thread_target. (init_aix_thread_ops): Delete. (_initialize_aix_thread): Remove references to init_aix_thread_ops and complete_target_initialization. * rs6000-nat.c (rs6000_xfer_shared_libraries): Delete. (rs6000_nat_target): New class. (the_rs6000_nat_target): New. (rs6000_fetch_inferior_registers, rs6000_store_inferior_registers) (rs6000_xfer_partial, rs6000_wait, rs6000_create_inferior) (rs6000_xfer_shared_libraries): Refactor as rs6000_nat_target methods. (super_create_inferior): Delete. (_initialize_rs6000_nat): Adjust to C++ification. * arm-linux-nat.c (arm_linux_nat_target): New class. (the_arm_linux_nat_target): New. (arm_linux_fetch_inferior_registers) (arm_linux_store_inferior_registers, arm_linux_read_description) (arm_linux_can_use_hw_breakpoint, arm_linux_insert_hw_breakpoint) (arm_linux_remove_hw_breakpoint) (arm_linux_region_ok_for_hw_watchpoint) (arm_linux_insert_watchpoint, arm_linux_remove_watchpoint) (arm_linux_stopped_data_address, arm_linux_stopped_by_watchpoint) (arm_linux_watchpoint_addr_within_range): Refactor as methods of arm_linux_nat_target. (_initialize_arm_linux_nat): Adjust to C++ification. * aarch64-linux-nat.c (aarch64_linux_nat_target): New class. (the_aarch64_linux_nat_target): New. (aarch64_linux_fetch_inferior_registers) (aarch64_linux_store_inferior_registers) (aarch64_linux_child_post_startup_inferior) (aarch64_linux_read_description) (aarch64_linux_can_use_hw_breakpoint) (aarch64_linux_insert_hw_breakpoint) (aarch64_linux_remove_hw_breakpoint) (aarch64_linux_insert_watchpoint, aarch64_linux_remove_watchpoint) (aarch64_linux_region_ok_for_hw_watchpoint) (aarch64_linux_stopped_data_address) (aarch64_linux_stopped_by_watchpoint) (aarch64_linux_watchpoint_addr_within_range) (aarch64_linux_can_do_single_step): Refactor as methods of aarch64_linux_nat_target. (super_post_startup_inferior): Delete. (_initialize_aarch64_linux_nat): Adjust to C++ification. * hppa-linux-nat.c (hppa_linux_nat_target): New class. (the_hppa_linux_nat_target): New. (hppa_linux_fetch_inferior_registers) (hppa_linux_store_inferior_registers): Refactor as methods of hppa_linux_nat_target. (_initialize_hppa_linux_nat): Adjust to C++ification. * ia64-linux-nat.c (ia64_linux_nat_target): New class. (the_ia64_linux_nat_target): New. (ia64_linux_insert_watchpoint, ia64_linux_remove_watchpoint) (ia64_linux_stopped_data_address) (ia64_linux_stopped_by_watchpoint, ia64_linux_fetch_registers) (ia64_linux_store_registers, ia64_linux_xfer_partial): Refactor as ia64_linux_nat_target methods. (super_xfer_partial): Delete. (_initialize_ia64_linux_nat): Adjust to C++ification. * m32r-linux-nat.c (m32r_linux_nat_target): New class. (the_m32r_linux_nat_target): New. (m32r_linux_fetch_inferior_registers) (m32r_linux_store_inferior_registers): Refactor as m32r_linux_nat_target methods. (_initialize_m32r_linux_nat): Adjust to C++ification. * m68k-linux-nat.c (m68k_linux_nat_target): New class. (the_m68k_linux_nat_target): New. (m68k_linux_fetch_inferior_registers) (m68k_linux_store_inferior_registers): Refactor as m68k_linux_nat_target methods. (_initialize_m68k_linux_nat): Adjust to C++ification. * s390-linux-nat.c (s390_linux_nat_target): New class. (the_s390_linux_nat_target): New. (s390_linux_fetch_inferior_registers) (s390_linux_store_inferior_registers, s390_stopped_by_watchpoint) (s390_insert_watchpoint, s390_remove_watchpoint) (s390_can_use_hw_breakpoint, s390_insert_hw_breakpoint) (s390_remove_hw_breakpoint, s390_region_ok_for_hw_watchpoint) (s390_auxv_parse, s390_read_description): Refactor as methods of s390_linux_nat_target. (_initialize_s390_nat): Adjust to C++ification. * sparc-linux-nat.c (sparc_linux_nat_target): New class. (the_sparc_linux_nat_target): New. (_initialize_sparc_linux_nat): Adjust to C++ification. * sparc-nat.c (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc64-linux-nat.c (sparc64_linux_nat_target): New class. (the_sparc64_linux_nat_target): New. (_initialize_sparc64_linux_nat): Adjust to C++ification. * spu-linux-nat.c (spu_linux_nat_target): New class. (the_spu_linux_nat_target): New. (spu_child_post_startup_inferior, spu_child_post_attach) (spu_child_wait, spu_fetch_inferior_registers) (spu_store_inferior_registers, spu_xfer_partial) (spu_can_use_hw_breakpoint): Refactor as spu_linux_nat_target methods. (_initialize_spu_nat): Adjust to C++ification. * tilegx-linux-nat.c (tilegx_linux_nat_target): New class. (the_tilegx_linux_nat_target): New. (fetch_inferior_registers, store_inferior_registers): Refactor as methods. (_initialize_tile_linux_nat): Adjust to C++ification. * xtensa-linux-nat.c (xtensa_linux_nat_target): New class. (the_xtensa_linux_nat_target): New. (xtensa_linux_fetch_inferior_registers) (xtensa_linux_store_inferior_registers): Refactor as xtensa_linux_nat_target methods. (_initialize_xtensa_linux_nat): Adjust to C++ification. * fbsd-nat.c (USE_SIGTRAP_SIGINFO): Delete. (fbsd_pid_to_exec_file, fbsd_find_memory_regions) (fbsd_find_memory_regions, fbsd_info_proc, fbsd_xfer_partial) (fbsd_thread_alive, fbsd_pid_to_str, fbsd_thread_name) (fbsd_update_thread_list, fbsd_resume, fbsd_wait) (fbsd_stopped_by_sw_breakpoint) (fbsd_supports_stopped_by_sw_breakpoint, fbsd_follow_fork) (fbsd_insert_fork_catchpoint, fbsd_remove_fork_catchpoint) (fbsd_insert_vfork_catchpoint, fbsd_remove_vfork_catchpoint) (fbsd_post_startup_inferior, fbsd_post_attach) (fbsd_insert_exec_catchpoint, fbsd_remove_exec_catchpoint) (fbsd_set_syscall_catchpoint) (super_xfer_partial, super_resume, super_wait) (fbsd_supports_stopped_by_hw_breakpoint): Delete. (fbsd_handle_debug_trap): Remove target_ops parameter. (fbsd_nat_add_target): Delete. * fbsd-nat.h: Include "inf-ptrace.h". (fbsd_nat_add_target): Delete. (USE_SIGTRAP_SIGINFO): Define. (fbsd_nat_target): New class. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers) (amd64bsd_store_inferior_registers): Remove target_ops parameter. (amd64bsd_target): Delete. * amd64-bsd-nat.h: New file. * amd64-fbsd-nat.c: Include "amd64-bsd-nat.h" instead of "x86-bsd-nat.h". (amd64_fbsd_nat_target): New class. (the_amd64_fbsd_nat_target): New. (amd64fbsd_read_description): Refactor as method of amd64_fbsd_nat_target. (amd64_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_amd64fbsd_nat): Adjust to C++ification. * amd64-nat.h (amd64bsd_target): Delete function declaration. * i386-bsd-nat.c (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Remove target_ops parameter. (i386bsd_target): Delete. * i386-bsd-nat.h (i386bsd_target): Delete function declaration. (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Declare. (i386_bsd_nat_target): New class. * i386-fbsd-nat.c (i386_fbsd_nat_target): New class. (the_i386_fbsd_nat_target): New. (i386fbsd_resume, i386fbsd_read_description): Refactor as i386_fbsd_nat_target methods. (i386_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_i386fbsd_nat): Adjust to C++ification. * x86-bsd-nat.c (super_mourn_inferior): Delete. (x86bsd_mourn_inferior, x86bsd_target): Delete. (_initialize_x86_bsd_nat): Adjust to C++ification. * x86-bsd-nat.h: Include "x86-nat.h". (x86bsd_target): Delete declaration. (x86bsd_nat_target): New class. * aarch64-fbsd-nat.c (aarch64_fbsd_nat_target): New class. (the_aarch64_fbsd_nat_target): New. (aarch64_fbsd_fetch_inferior_registers) (aarch64_fbsd_store_inferior_registers): Refactor as methods of aarch64_fbsd_nat_target. (_initialize_aarch64_fbsd_nat): Adjust to C++ification. * alpha-bsd-nat.c (alpha_bsd_nat_target): New class. (the_alpha_bsd_nat_target): New. (alphabsd_fetch_inferior_registers) (alphabsd_store_inferior_registers): Refactor as alpha_bsd_nat_target methods. (_initialize_alphabsd_nat): Refactor as methods of alpha_bsd_nat_target. * amd64-nbsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_nbsd_nat_target): New. (_initialize_amd64nbsd_nat): Adjust to C++ification. * amd64-obsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_obsd_nat_target): New. (_initialize_amd64obsd_nat): Adjust to C++ification. * arm-fbsd-nat.c (arm_fbsd_nat_target): New. (the_arm_fbsd_nat_target): New. (arm_fbsd_fetch_inferior_registers) (arm_fbsd_store_inferior_registers, arm_fbsd_read_description): (_initialize_arm_fbsd_nat): Refactor as methods of arm_fbsd_nat_target. (_initialize_arm_fbsd_nat): Adjust to C++ification. * arm-nbsd-nat.c (arm_netbsd_nat_target): New class. (the_arm_netbsd_nat_target): New. (armnbsd_fetch_registers, armnbsd_store_registers): Refactor as arm_netbsd_nat_target. (_initialize_arm_netbsd_nat): Adjust to C++ification. * hppa-nbsd-nat.c (hppa_nbsd_nat_target): New class. (the_hppa_nbsd_nat_target): New. (hppanbsd_fetch_registers, hppanbsd_store_registers): Refactor as hppa_nbsd_nat_target methods. (_initialize_hppanbsd_nat): Adjust to C++ification. * hppa-obsd-nat.c (hppa_obsd_nat_target): New class. (the_hppa_obsd_nat_target): New. (hppaobsd_fetch_registers, hppaobsd_store_registers): Refactor as methods of hppa_obsd_nat_target. (_initialize_hppaobsd_nat): Adjust to C++ification. Use add_target. * i386-nbsd-nat.c (the_i386_nbsd_nat_target): New. (_initialize_i386nbsd_nat): Adjust to C++ification. Use add_target. * i386-obsd-nat.c (the_i386_obsd_nat_target): New. (_initialize_i386obsd_nat): Use add_target. * m68k-bsd-nat.c (m68k_bsd_nat_target): New class. (the_m68k_bsd_nat_target): New. (m68kbsd_fetch_inferior_registers) (m68kbsd_store_inferior_registers): Refactor as methods of m68k_bsd_nat_target. (_initialize_m68kbsd_nat): Adjust to C++ification. * mips-fbsd-nat.c (mips_fbsd_nat_target): New class. (the_mips_fbsd_nat_target): New. (mips_fbsd_fetch_inferior_registers) (mips_fbsd_store_inferior_registers): Refactor as methods of mips_fbsd_nat_target. (_initialize_mips_fbsd_nat): Adjust to C++ification. Use add_target. * mips-nbsd-nat.c (mips_nbsd_nat_target): New class. (the_mips_nbsd_nat_target): New. (mipsnbsd_fetch_inferior_registers) (mipsnbsd_store_inferior_registers): Refactor as methods of mips_nbsd_nat_target. (_initialize_mipsnbsd_nat): Adjust to C++ification. * mips64-obsd-nat.c (mips64_obsd_nat_target): New class. (the_mips64_obsd_nat_target): New. (mips64obsd_fetch_inferior_registers) (mips64obsd_store_inferior_registers): Refactor as methods of mips64_obsd_nat_target. (_initialize_mips64obsd_nat): Adjust to C++ification. Use add_target. * nbsd-nat.c (nbsd_pid_to_exec_file): Refactor as method of nbsd_nat_target. * nbsd-nat.h: Include "inf-ptrace.h". (nbsd_nat_target): New class. * obsd-nat.c (obsd_pid_to_str, obsd_update_thread_list) (obsd_wait): Refactor as methods of obsd_nat_target. (obsd_add_target): Delete. * obsd-nat.h: Include "inf-ptrace.h". (obsd_nat_target): New class. * ppc-fbsd-nat.c (ppc_fbsd_nat_target): New class. (the_ppc_fbsd_nat_target): New. (ppcfbsd_fetch_inferior_registers) (ppcfbsd_store_inferior_registers): Refactor as methods of ppc_fbsd_nat_target. (_initialize_ppcfbsd_nat): Adjust to C++ification. Use add_target. * ppc-nbsd-nat.c (ppc_nbsd_nat_target): New class. (the_ppc_nbsd_nat_target): New. (ppcnbsd_fetch_inferior_registers) (ppcnbsd_store_inferior_registers): Refactor as methods of ppc_nbsd_nat_target. (_initialize_ppcnbsd_nat): Adjust to C++ification. * ppc-obsd-nat.c (ppc_obsd_nat_target): New class. (the_ppc_obsd_nat_target): New. (ppcobsd_fetch_registers, ppcobsd_store_registers): Refactor as methods of ppc_obsd_nat_target. (_initialize_ppcobsd_nat): Adjust to C++ification. Use add_target. * sh-nbsd-nat.c (sh_nbsd_nat_target): New class. (the_sh_nbsd_nat_target): New. (shnbsd_fetch_inferior_registers) (shnbsd_store_inferior_registers): Refactor as methods of sh_nbsd_nat_target. (_initialize_shnbsd_nat): Adjust to C++ification. * sparc-nat.c (sparc_xfer_wcookie): Make extern. (inf_ptrace_xfer_partial): Delete. (sparc_xfer_partial, sparc_target): Delete. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers, sparc_xfer_wcookie): Declare. (sparc_target): Delete function declaration. (sparc_target): New template class. * sparc-nbsd-nat.c (the_sparc_nbsd_nat_target): New. (_initialize_sparcnbsd_nat): Adjust to C++ification. * sparc64-fbsd-nat.c (the_sparc64_fbsd_nat_target): New. (_initialize_sparc64fbsd_nat): Adjust to C++ification. Use add_target. * sparc64-nbsd-nat.c (the_sparc64_nbsd_nat_target): New. (_initialize_sparc64nbsd_nat): Adjust to C++ification. * sparc64-obsd-nat.c (the_sparc64_obsd_nat_target): New. (_initialize_sparc64obsd_nat): Adjust to C++ification. Use add_target. * vax-bsd-nat.c (vax_bsd_nat_target): New class. (the_vax_bsd_nat_target): New. (vaxbsd_fetch_inferior_registers) (vaxbsd_store_inferior_registers): Refactor as vax_bsd_nat_target methods. (_initialize_vaxbsd_nat): Adjust to C++ification. * bsd-kvm.c (bsd_kvm_target): New class. (bsd_kvm_ops): Now a bsd_kvm_target. (bsd_kvm_open, bsd_kvm_close, bsd_kvm_xfer_partial) (bsd_kvm_files_info, bsd_kvm_fetch_registers) (bsd_kvm_thread_alive, bsd_kvm_pid_to_str): Refactor as methods of bsd_kvm_target. (bsd_kvm_return_one): Delete. (bsd_kvm_add_target): Adjust to C++ification. * nto-procfs.c (nto_procfs_target, nto_procfs_target_native) (nto_procfs_target_procfs): New classes. (procfs_open_1, procfs_thread_alive, procfs_update_thread_list) (procfs_files_info, procfs_pid_to_exec_file, procfs_attach) (procfs_post_attach, procfs_wait, procfs_fetch_registers) (procfs_xfer_partial, procfs_detach, procfs_insert_breakpoint) (procfs_remove_breakpoint, procfs_insert_hw_breakpoint) (procfs_remove_hw_breakpoint, procfs_resume) (procfs_mourn_inferior, procfs_create_inferior, procfs_interrupt) (procfs_kill_inferior, procfs_store_registers) (procfs_pass_signals, procfs_pid_to_str, procfs_can_run): Refactor as methods of nto_procfs_target. (nto_procfs_ops): Now an nto_procfs_target_procfs. (nto_native_ops): Delete. (procfs_open, procfs_native_open): Delete. (nto_native_ops): Now an nto_procfs_target_native. (init_procfs_targets): Adjust to C++ification. (procfs_can_use_hw_breakpoint, procfs_remove_hw_watchpoint) (procfs_insert_hw_watchpoint, procfs_stopped_by_watchpoint): Refactor as methods of nto_procfs_target. * go32-nat.c (go32_nat_target): New class. (the_go32_nat_target): New. (go32_attach, go32_resume, go32_wait, go32_fetch_registers) (go32_store_registers, go32_xfer_partial, go32_files_info) (go32_kill_inferior, go32_create_inferior, go32_mourn_inferior) (go32_terminal_init, go32_terminal_info, go32_terminal_inferior) (go32_terminal_ours, go32_pass_ctrlc, go32_thread_alive) (go32_pid_to_str): Refactor as methods of go32_nat_target. (go32_target): Delete. (_initialize_go32_nat): Adjust to C++ification. * gnu-nat.c (gnu_wait, gnu_resume, gnu_kill_inferior) (gnu_mourn_inferior, gnu_create_inferior, gnu_attach, gnu_detach) (gnu_stop, gnu_thread_alive, gnu_xfer_partial) (gnu_find_memory_regions, gnu_pid_to_str): Refactor as methods of gnu_nat_target. (gnu_target): Delete. * gnu-nat.h (gnu_target): Delete. (gnu_nat_target): New class. * i386-gnu-nat.c (gnu_base_target): New. (i386_gnu_nat_target): New class. (the_i386_gnu_nat_target): New. (_initialize_i386gnu_nat): Adjust to C++ification. gdb/testsuite/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * gdb.base/breakpoint-in-ro-region.exp: Adjust to to_resume and to_log_command renames. * gdb.base/sss-bp-on-user-bp-2.exp: Likewise.
2018-05-03 07:37:22 +08:00
target_ops: Use bool throughout After the previous target_ops/C++ patches are all squashed and merged, this one can go in separately. This patch adjusts all the target methods to return bool instead of int when they're returning a boolean. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * target.h (target_ops) <stopped_by_sw_breakpoint, supports_stopped_by_sw_breakpoint, stopped_by_hw_breakpoint, supports_stopped_by_hw_breakpoint, stopped_by_watchpoint, have_continuable_watchpoint, stopped_data_address, watchpoint_addr_within_range, can_accel_watchpoint_condition, can_run, thread_alive, has_all_memory, has_memory, has_stack, has_registers, has_execution, can_async_p, is_async_p, supports_non_stop, always_non_stop_p, can_execute_reverse, supports_multi_process, supports_enable_disable_tracepoint, supports_disable_randomization, supports_string_tracing, supports_evaluation_of_breakpoint_conditions, can_run_breakpoint_commands, filesystem_is_local, can_download_tracepoint, get_trace_state_variable_value, set_trace_notes, get_tib_address, use_agent, can_use_agent, record_is_replaying, record_will_replay, augmented_libraries_svr4_read>: Adjust to return bool. * aarch64-linux-nat.c: All implementations adjusted. * aix-thread.c: All implementations adjusted. * arm-linux-nat.c: All implementations adjusted. * breakpoint.c: All implementations adjusted. * bsd-kvm.c: All implementations adjusted. * bsd-uthread.c: All implementations adjusted. * corelow.c: All implementations adjusted. * ctf.c: All implementations adjusted. * darwin-nat.c: All implementations adjusted. * darwin-nat.h: All implementations adjusted. * exec.c: All implementations adjusted. * fbsd-nat.c: All implementations adjusted. * fbsd-nat.h: All implementations adjusted. * gnu-nat.c: All implementations adjusted. * gnu-nat.h: All implementations adjusted. * go32-nat.c: All implementations adjusted. * ia64-linux-nat.c: All implementations adjusted. * inf-child.c: All implementations adjusted. * inf-child.h: All implementations adjusted. * inf-ptrace.c: All implementations adjusted. * inf-ptrace.h: All implementations adjusted. * linux-nat.c: All implementations adjusted. * linux-nat.h: All implementations adjusted. * mips-linux-nat.c: All implementations adjusted. * nto-procfs.c: All implementations adjusted. * ppc-linux-nat.c: All implementations adjusted. * procfs.c: All implementations adjusted. * ravenscar-thread.c: All implementations adjusted. * record-btrace.c: All implementations adjusted. * record-full.c: All implementations adjusted. * remote-sim.c: All implementations adjusted. * remote.c: All implementations adjusted. * s390-linux-nat.c: All implementations adjusted. * sol-thread.c: All implementations adjusted. * spu-multiarch.c: All implementations adjusted. * target-delegates.c: All implementations adjusted. * target.c: All implementations adjusted. * target.h: All implementations adjusted. * tracefile-tfile.c: All implementations adjusted. * tracefile.c: All implementations adjusted. * tracefile.h: All implementations adjusted. * windows-nat.c: All implementations adjusted. * x86-linux-nat.h: All implementations adjusted. * x86-nat.h: All implementations adjusted.
2018-05-03 07:37:26 +08:00
bool can_accel_watchpoint_condition (CORE_ADDR, int, int, struct expression *)
Convert struct target_ops to C++ I.e., use C++ virtual methods and inheritance instead of tables of function pointers. Unfortunately, there's no way to do a smooth transition. ALL native targets in the tree must be converted at the same time. I've tested all I could with cross compilers and with help from GCC compile farm, but naturally I haven't been able to test many of the ports. Still, I made a best effort to port everything over, and while I expect some build problems due to typos and such, which should be trivial to fix, I don't expect any design problems. * Implementation notes: - The flattened current_target is gone. References to current_target or current_target.beneath are replaced with references to target_stack (the top of the stack) directly. - To keep "set debug target" working, this adds a new debug_stratum layer that sits on top of the stack, prints the debug, and delegates to the target beneath. In addition, this makes the shortname and longname properties of target_ops be virtual methods instead of data fields, and makes the debug target defer those to the target beneath. This is so that debug code sprinkled around that does "if (debugtarget) ..." can transparently print the name of the target beneath. A patch later in the series actually splits out the shortname/longname methods to a separate structure, but I preferred to keep that chance separate as it is associated with changing a bit the design of how targets are registered and open. - Since you can't check whether a C++ virtual method is overridden, the old method of checking whether a target_ops implements a method by comparing the function pointer must be replaced with something else. Some cases are fixed by adding a parallel "can_do_foo" target_ops methods. E.g.,: + for (t = target_stack; t != NULL; t = t->beneath) { - if (t->to_create_inferior != NULL) + if (t->can_create_inferior ()) break; } Others are fixed by changing void return type to bool or int return type, and have the default implementation return false or -1, to indicate lack of support. - make-target-delegates was adjusted to generate C++ classes and methods. It needed tweaks to grok "virtual" in front of the target method name, and for the fact that methods are no longer function pointers. (In particular, the current code parsing the return type was simple because it could simply parse up until the '(' in '(*to_foo)'. It now generates a couple C++ classes that inherit target_ops: dummy_target and debug_target. Since we need to generate the class declarations as well, i.e., we need to emit methods twice, we now generate the code in two passes. - The core_target global is renamed to avoid conflict with the "core_target" class. - ctf/tfile targets init_tracefile_ops is replaced by a base class that is inherited by both ctf and tfile. - bsd-uthread The bsd_uthread_ops_hack hack is gone. It's not needed because nothing was extending a target created by bsd_uthread_target. - remote/extended-remote targets This is a first pass, just enough to C++ify target_ops. A later pass will convert more free functions to methods, and make remote_state be truly per remote instance, allowing multiple simultaneous instances of remote targets. - inf-child/"native" is converted to an actual base class (inf_child_target), that is inherited by all native targets. - GNU/Linux The old weird double-target linux_ops mechanism in linux-nat.c, is gone, replaced by adding a few virtual methods to linux-nat.h's target_ops, called low_XXX, that the concrete linux-nat implementations override. Sort of like gdbserver's linux_target_ops, but simpler, for requiring only one target_ops-like hierarchy, which spares implementing the same method twice when we need to forward the method to a low implementation. The low target simply reimplements the target_ops method directly in that case. There are a few remaining linux-nat.c hooks that would be better converted to low_ methods like above too. E.g.: linux_nat_set_new_thread (t, x86_linux_new_thread); linux_nat_set_new_fork (t, x86_linux_new_fork); linux_nat_set_forget_process That'll be done in a follow up patch. - We can no longer use functions like x86_use_watchpoints to install custom methods on an arbitrary base target. The patch replaces instances of such a pattern with template mixins. For example memory_breakpoint_target defined in target.h, or x86_nat_target in x86-nat.h. - linux_trad_target, MIPS and Alpha GNU/Linux The code in the new linux-nat-trad.h/c files which was split off of inf-ptrace.h/c recently, is converted to a C++ base class, and used by the MIPS and Alpha GNU/Linux ports. - BSD targets The $architecture x NetBSD/OpenBSD/FreeBSD support matrix complicates things a bit. There's common BSD target code, and there's common architecture-specific code shared between the different BSDs. Currently, all that is stiched together to form a final target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target functions etc. This introduces new fbsd_nat_target, obsd_nat_target and nbsd_nat_target classes that serve as base/prototype target for the corresponding BSD variant. And introduces generic i386/AMD64 BSD targets, to be used as template mixin to build a final target. Similarly, a generic SPARC target is added, used by both BSD and Linux ports. - bsd_kvm_add_target, BSD libkvm target I considered making bsd_kvm_supply_pcb a virtual method, and then have each port inherit bsd_kvm_target and override that method, but that was resulting in lots of unjustified churn, so I left the function pointer mechanism alone. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> John Baldwin <jhb@freebsd.org> * target.h (enum strata) <debug_stratum>: New. (struct target_ops) <all delegation methods>: Replace by C++ virtual methods, and drop "to_" prefix. All references updated throughout. <to_shortname, to_longname, to_doc, to_data, to_have_steppable_watchpoint, to_have_continuable_watchpoint, to_has_thread_control, to_attach_no_wait>: Delete, replaced by virtual methods. All references updated throughout. <can_attach, supports_terminal_ours, can_create_inferior, get_thread_control_capabilities, attach_no_wait>: New virtual methods. <insert_breakpoint, remove_breakpoint>: Now TARGET_DEFAULT_NORETURN methods. <info_proc>: Now returns bool. <to_magic>: Delete. (OPS_MAGIC): Delete. (current_target): Delete. All references replaced by references to ... (target_stack): ... this. New. (target_shortname, target_longname): Adjust. (target_can_run): Now a function declaration. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (memory_breakpoint_target): New template class. (test_target_ops): Refactor as a C++ class with virtual methods. * make-target-delegates (NAME_PART): Tighten. (POINTER_PART, CP_SYMBOL): New. (SIMPLE_RETURN_PART): Reimplement. (VEC_RETURN_PART): Expect less. (RETURN_PART, VIRTUAL_PART): New. (METHOD): Adjust to C++ virtual methods. (scan_target_h): Remove reference to C99. (dname): Output "target_ops::" prefix. (write_function_header): Adjust to output a C++ class method. (write_declaration): New. (write_delegator): Adjust to output a C++ class method. (tdname): Output "dummy_target::" prefix. (write_tdefault, write_debugmethod): Adjust to output a C++ class method. (tdefault_names, debug_names): Delete. (return_types, tdefaults, styles, argtypes_array): New. (top level): All methods are delegators. (print_class): New. (top level): Print dummy_target and debug_target classes. * target-delegates.c: Regenerate. * target-debug.h (target_debug_print_enum_info_proc_what) (target_debug_print_thread_control_capabilities) (target_debug_print_thread_info_p): New. * target.c (dummy_target): Delete. (the_dummy_target, the_debug_target): New. (target_stack): Now extern. (set_targetdebug): Push/unpush debug target. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (add_target_with_completer): No longer call complete_target_initialization. (target_supports_terminal_ours): Use regular delegation. (update_current_target): Delete. (push_target): No longer check magic number. Don't call update_current_target. (unpush_target): Don't call update_current_target. (target_is_pushed): No longer check magic number. (target_require_runnable): Skip for all stratums over process_stratum. (target_ops::info_proc): New. (target_info_proc): Use find_target_at and find_default_run_target. (target_supports_disable_randomization): Use regular delegation. (target_get_osdata): Use find_target_at. (target_ops::open, target_ops::close, target_ops::can_attach) (target_ops::attach, target_ops::can_create_inferior) (target_ops::create_inferior, target_ops::can_run) (target_can_run): New. (default_fileio_target): Use regular delegation. (target_ops::fileio_open, target_ops::fileio_pwrite) (target_ops::fileio_pread, target_ops::fileio_fstat) (target_ops::fileio_close, target_ops::fileio_unlink) (target_ops::fileio_readlink): New. (target_fileio_open_1, target_fileio_unlink) (target_fileio_readlink): Always call the target method. Handle FILEIO_ENOSYS. (return_zero, return_zero_has_execution): Delete. (init_dummy_target): Delete. (dummy_target::dummy_target, dummy_target::shortname) (dummy_target::longname, dummy_target::doc) (debug_target::debug_target, debug_target::shortname) (debug_target::longname, debug_target::doc): New. (target_supports_delete_record): Use regular delegation. (setup_target_debug): Delete. (maintenance_print_target_stack): Skip debug_stratum. (initialize_targets): Instantiate the_dummy_target and the_debug_target. * auxv.c (target_auxv_parse): Remove 'ops' parameter. Adjust to use target_stack. (target_auxv_search, fprint_target_auxv): Adjust. (info_auxv_command): Adjust to use target_stack. * auxv.h (target_auxv_parse): Remove 'ops' parameter. * exceptions.c (print_flush): Handle a NULL target_stack. * regcache.c (target_ops_no_register): Refactor as class with virtual methods. * exec.c (exec_target): New class. (exec_ops): Now an exec_target. (exec_open, exec_close_1, exec_get_section_table) (exec_xfer_partial, exec_files_info, exec_has_memory) (exec_make_note_section): Refactor as exec_target methods. (exec_file_clear, ignore, exec_remove_breakpoint, init_exec_ops): Delete. (exec_target::find_memory_regions): New. (_initialize_exec): Don't call init_exec_ops. * gdbcore.h (exec_file_clear): Delete. * corefile.c (core_target): Delete. (core_file_command): Adjust. * corelow.c (core_target): New class. (the_core_target): New. (core_close): Remove target_ops parameter. (core_close_cleanup): Adjust. (core_target::close): New. (core_open, core_detach, get_core_registers, core_files_info) (core_xfer_partial, core_thread_alive, core_read_description) (core_pid_to_str, core_thread_name, core_has_memory) (core_has_stack, core_has_registers, core_info_proc): Rework as core_target methods. (ignore, core_remove_breakpoint, init_core_ops): Delete. (_initialize_corelow): Initialize the_core_target. * gdbcore.h (core_target): Delete. (the_core_target): New. * ctf.c: (ctf_target): New class. (ctf_ops): Now a ctf_target. (ctf_open, ctf_close, ctf_files_info, ctf_fetch_registers) (ctf_xfer_partial, ctf_get_trace_state_variable_value) (ctf_trace_find, ctf_traceframe_info): Refactor as ctf_target methods. (init_ctf_ops): Delete. (_initialize_ctf): Don't call it. * tracefile-tfile.c (tfile_target): New class. (tfile_ops): Now a tfile_target. (tfile_open, tfile_close, tfile_files_info) (tfile_get_tracepoint_status, tfile_trace_find) (tfile_fetch_registers, tfile_xfer_partial) (tfile_get_trace_state_variable_value, tfile_traceframe_info): Refactor as tfile_target methods. (tfile_xfer_partial_features): Remove target_ops parameter. (init_tfile_ops): Delete. (_initialize_tracefile_tfile): Don't call it. * tracefile.c (tracefile_has_all_memory, tracefile_has_memory) (tracefile_has_stack, tracefile_has_registers) (tracefile_thread_alive, tracefile_get_trace_status): Refactor as tracefile_target methods. (init_tracefile_ops): Delete. (tracefile_target::tracefile_target): New. * tracefile.h: Include "target.h". (tracefile_target): New class. (init_tracefile_ops): Delete. * spu-multiarch.c (spu_multiarch_target): New class. (spu_ops): Now a spu_multiarch_target. (spu_thread_architecture, spu_region_ok_for_hw_watchpoint) (spu_fetch_registers, spu_store_registers, spu_xfer_partial) (spu_search_memory, spu_mourn_inferior): Refactor as spu_multiarch_target methods. (init_spu_ops): Delete. (_initialize_spu_multiarch): Remove references to init_spu_ops, complete_target_initialization. * ravenscar-thread.c (ravenscar_thread_target): New class. (ravenscar_ops): Now a ravenscar_thread_target. (ravenscar_resume, ravenscar_wait, ravenscar_update_thread_list) (ravenscar_thread_alive, ravenscar_pid_to_str) (ravenscar_fetch_registers, ravenscar_store_registers) (ravenscar_prepare_to_store, ravenscar_stopped_by_sw_breakpoint) (ravenscar_stopped_by_hw_breakpoint) (ravenscar_stopped_by_watchpoint, ravenscar_stopped_data_address) (ravenscar_mourn_inferior, ravenscar_core_of_thread) (ravenscar_get_ada_task_ptid): Refactor as ravenscar_thread_target methods. (init_ravenscar_thread_ops): Delete. (_initialize_ravenscar): Remove references to init_ravenscar_thread_ops and complete_target_initialization. * bsd-uthread.c (bsd_uthread_ops_hack): Delete. (bsd_uthread_target): New class. (bsd_uthread_ops): Now a bsd_uthread_target. (bsd_uthread_activate): Adjust to refer to bsd_uthread_ops. (bsd_uthread_close, bsd_uthread_mourn_inferior) (bsd_uthread_fetch_registers, bsd_uthread_store_registers) (bsd_uthread_wait, bsd_uthread_resume, bsd_uthread_thread_alive) (bsd_uthread_update_thread_list, bsd_uthread_extra_thread_info) (bsd_uthread_pid_to_str): Refactor as bsd_uthread_target methods. (bsd_uthread_target): Delete function. (_initialize_bsd_uthread): Remove reference to complete_target_initialization. * bfd-target.c (target_bfd_data): Delete. Fields folded into ... (target_bfd): ... this new class. (target_bfd_xfer_partial, target_bfd_get_section_table) (target_bfd_close): Refactor as target_bfd methods. (target_bfd::~target_bfd): New. (target_bfd_reopen): Adjust. (target_bfd::close): New. * record-btrace.c (record_btrace_target): New class. (record_btrace_ops): Now a record_btrace_target. (record_btrace_open, record_btrace_stop_recording) (record_btrace_disconnect, record_btrace_close) (record_btrace_async, record_btrace_info) (record_btrace_insn_history, record_btrace_insn_history_range) (record_btrace_insn_history_from, record_btrace_call_history) (record_btrace_call_history_range) (record_btrace_call_history_from, record_btrace_record_method) (record_btrace_is_replaying, record_btrace_will_replay) (record_btrace_xfer_partial, record_btrace_insert_breakpoint) (record_btrace_remove_breakpoint, record_btrace_fetch_registers) (record_btrace_store_registers, record_btrace_prepare_to_store) (record_btrace_to_get_unwinder) (record_btrace_to_get_tailcall_unwinder, record_btrace_resume) (record_btrace_commit_resume, record_btrace_wait) (record_btrace_stop, record_btrace_can_execute_reverse) (record_btrace_stopped_by_sw_breakpoint) (record_btrace_supports_stopped_by_sw_breakpoint) (record_btrace_stopped_by_hw_breakpoint) (record_btrace_supports_stopped_by_hw_breakpoint) (record_btrace_update_thread_list, record_btrace_thread_alive) (record_btrace_goto_begin, record_btrace_goto_end) (record_btrace_goto, record_btrace_stop_replaying_all) (record_btrace_execution_direction) (record_btrace_prepare_to_generate_core) (record_btrace_done_generating_core): Refactor as record_btrace_target methods. (init_record_btrace_ops): Delete. (_initialize_record_btrace): Remove reference to init_record_btrace_ops. * record-full.c (RECORD_FULL_IS_REPLAY): Adjust to always refer to the execution_direction global. (record_full_base_target, record_full_target) (record_full_core_target): New classes. (record_full_ops): Now a record_full_target. (record_full_core_ops): Now a record_full_core_target. (record_full_target::detach, record_full_target::disconnect) (record_full_core_target::disconnect) (record_full_target::mourn_inferior, record_full_target::kill): New. (record_full_open, record_full_close, record_full_async): Refactor as methods of the record_full_base_target class. (record_full_resume, record_full_commit_resume): Refactor as methods of the record_full_target class. (record_full_wait, record_full_stopped_by_watchpoint) (record_full_stopped_data_address) (record_full_stopped_by_sw_breakpoint) (record_full_supports_stopped_by_sw_breakpoint) (record_full_stopped_by_hw_breakpoint) (record_full_supports_stopped_by_hw_breakpoint): Refactor as methods of the record_full_base_target class. (record_full_store_registers, record_full_xfer_partial) (record_full_insert_breakpoint, record_full_remove_breakpoint): Refactor as methods of the record_full_target class. (record_full_can_execute_reverse, record_full_get_bookmark) (record_full_goto_bookmark, record_full_execution_direction) (record_full_record_method, record_full_info, record_full_delete) (record_full_is_replaying, record_full_will_replay) (record_full_goto_begin, record_full_goto_end, record_full_goto) (record_full_stop_replaying): Refactor as methods of the record_full_base_target class. (record_full_core_resume, record_full_core_kill) (record_full_core_fetch_registers) (record_full_core_prepare_to_store) (record_full_core_store_registers, record_full_core_xfer_partial) (record_full_core_insert_breakpoint) (record_full_core_remove_breakpoint) (record_full_core_has_execution): Refactor as methods of the record_full_core_target class. (record_full_base_target::supports_delete_record): New. (init_record_full_ops): Delete. (init_record_full_core_ops): Delete. (record_full_save): Refactor as method of the record_full_base_target class. (_initialize_record_full): Remove references to init_record_full_ops and init_record_full_core_ops. * remote.c (remote_target, extended_remote_target): New classes. (remote_ops): Now a remote_target. (extended_remote_ops): Now an extended_remote_target. (remote_insert_fork_catchpoint, remote_remove_fork_catchpoint) (remote_insert_vfork_catchpoint, remote_remove_vfork_catchpoint) (remote_insert_exec_catchpoint, remote_remove_exec_catchpoint) (remote_pass_signals, remote_set_syscall_catchpoint) (remote_program_signals, ) (remote_thread_always_alive): Remove target_ops parameter. (remote_thread_alive, remote_thread_name) (remote_update_thread_list, remote_threads_extra_info) (remote_static_tracepoint_marker_at) (remote_static_tracepoint_markers_by_strid) (remote_get_ada_task_ptid, remote_close, remote_start_remote) (remote_open): Refactor as methods of remote_target. (extended_remote_open, extended_remote_detach) (extended_remote_attach, extended_remote_post_attach): (extended_remote_supports_disable_randomization) (extended_remote_create_inferior): : Refactor as method of extended_remote_target. (remote_set_permissions, remote_open_1, remote_detach) (remote_follow_fork, remote_follow_exec, remote_disconnect) (remote_resume, remote_commit_resume, remote_stop) (remote_interrupt, remote_pass_ctrlc, remote_terminal_inferior) (remote_terminal_ours, remote_wait, remote_fetch_registers) (remote_prepare_to_store, remote_store_registers) (remote_flash_erase, remote_flash_done, remote_files_info) (remote_kill, remote_mourn, remote_insert_breakpoint) (remote_remove_breakpoint, remote_insert_watchpoint) (remote_watchpoint_addr_within_range) (remote_remove_watchpoint, remote_region_ok_for_hw_watchpoint) (remote_check_watch_resources, remote_stopped_by_sw_breakpoint) (remote_supports_stopped_by_sw_breakpoint) (remote_stopped_by_hw_breakpoint) (remote_supports_stopped_by_hw_breakpoint) (remote_stopped_by_watchpoint, remote_stopped_data_address) (remote_insert_hw_breakpoint, remote_remove_hw_breakpoint) (remote_verify_memory): Refactor as methods of remote_target. (remote_write_qxfer, remote_read_qxfer): Remove target_ops parameter. (remote_xfer_partial, remote_get_memory_xfer_limit) (remote_search_memory, remote_rcmd, remote_memory_map) (remote_pid_to_str, remote_get_thread_local_address) (remote_get_tib_address, remote_read_description): Refactor as methods of remote_target. (remote_target::fileio_open, remote_target::fileio_pwrite) (remote_target::fileio_pread, remote_target::fileio_close): New. (remote_hostio_readlink, remote_hostio_fstat) (remote_filesystem_is_local, remote_can_execute_reverse) (remote_supports_non_stop, remote_supports_disable_randomization) (remote_supports_multi_process, remote_supports_cond_breakpoints) (remote_supports_enable_disable_tracepoint) (remote_supports_string_tracing) (remote_can_run_breakpoint_commands, remote_trace_init) (remote_download_tracepoint, remote_can_download_tracepoint) (remote_download_trace_state_variable, remote_enable_tracepoint) (remote_disable_tracepoint, remote_trace_set_readonly_regions) (remote_trace_start, remote_get_trace_status) (remote_get_tracepoint_status, remote_trace_stop) (remote_trace_find, remote_get_trace_state_variable_value) (remote_save_trace_data, remote_get_raw_trace_data) (remote_set_disconnected_tracing, remote_core_of_thread) (remote_set_circular_trace_buffer, remote_traceframe_info) (remote_get_min_fast_tracepoint_insn_len) (remote_set_trace_buffer_size, remote_set_trace_notes) (remote_use_agent, remote_can_use_agent, remote_enable_btrace) (remote_disable_btrace, remote_teardown_btrace) (remote_read_btrace, remote_btrace_conf) (remote_augmented_libraries_svr4_read, remote_load) (remote_pid_to_exec_file, remote_can_do_single_step) (remote_execution_direction, remote_thread_handle_to_thread_info): Refactor as methods of remote_target. (init_remote_ops, init_extended_remote_ops): Delete. (remote_can_async_p, remote_is_async_p, remote_async) (remote_thread_events, remote_upload_tracepoints) (remote_upload_trace_state_variables): Refactor as methods of remote_target. (_initialize_remote): Remove references to init_remote_ops and init_extended_remote_ops. * remote-sim.c (gdbsim_target): New class. (gdbsim_fetch_register, gdbsim_store_register, gdbsim_kill) (gdbsim_load, gdbsim_create_inferior, gdbsim_open, gdbsim_close) (gdbsim_detach, gdbsim_resume, gdbsim_interrupt) (gdbsim_wait, gdbsim_prepare_to_store, gdbsim_xfer_partial) (gdbsim_files_info, gdbsim_mourn_inferior, gdbsim_thread_alive) (gdbsim_pid_to_str, gdbsim_has_all_memory, gdbsim_has_memory): Refactor as methods of gdbsim_target. (gdbsim_ops): Now a gdbsim_target. (init_gdbsim_ops): Delete. (gdbsim_cntrl_c): Adjust. (_initialize_remote_sim): Remove reference to init_gdbsim_ops. * amd64-linux-nat.c (amd64_linux_nat_target): New class. (the_amd64_linux_nat_target): New. (amd64_linux_fetch_inferior_registers) (amd64_linux_store_inferior_registers): Refactor as methods of amd64_linux_nat_target. (_initialize_amd64_linux_nat): Adjust. Set linux_target. * i386-linux-nat.c: Don't include "linux-nat.h". (i386_linux_nat_target): New class. (the_i386_linux_nat_target): New. (i386_linux_fetch_inferior_registers) (i386_linux_store_inferior_registers, i386_linux_resume): Refactor as methods of i386_linux_nat_target. (_initialize_i386_linux_nat): Adjust. Set linux_target. * inf-child.c (inf_child_ops): Delete. (inf_child_fetch_inferior_registers) (inf_child_store_inferior_registers): Delete. (inf_child_post_attach, inf_child_prepare_to_store): Refactor as methods of inf_child_target. (inf_child_target::supports_terminal_ours) (inf_child_target::terminal_init) (inf_child_target::terminal_inferior) (inf_child_target::terminal_ours_for_output) (inf_child_target::terminal_ours, inf_child_target::interrupt) (inf_child_target::pass_ctrlc, inf_child_target::terminal_info): New. (inf_child_open, inf_child_disconnect, inf_child_close) (inf_child_mourn_inferior, inf_child_maybe_unpush_target) (inf_child_post_startup_inferior, inf_child_can_run) (inf_child_pid_to_exec_file): Refactor as methods of inf_child_target. (inf_child_follow_fork): Delete. (inf_child_target::can_create_inferior) (inf_child_target::can_attach): New. (inf_child_target::has_all_memory, inf_child_target::has_memory) (inf_child_target::has_stack, inf_child_target::has_registers) (inf_child_target::has_execution): New. (inf_child_fileio_open, inf_child_fileio_pwrite) (inf_child_fileio_pread, inf_child_fileio_fstat) (inf_child_fileio_close, inf_child_fileio_unlink) (inf_child_fileio_readlink, inf_child_use_agent) (inf_child_can_use_agent): Refactor as methods of inf_child_target. (return_zero, inf_child_target): Delete. (inf_child_target::inf_child_target): New. * inf-child.h: Include "target.h". (inf_child_target): Delete function prototype. (inf_child_target): New class. (inf_child_open_target, inf_child_mourn_inferior) (inf_child_maybe_unpush_target): Delete. * inf-ptrace.c (inf_ptrace_target::~inf_ptrace_target): New. (inf_ptrace_follow_fork, inf_ptrace_insert_fork_catchpoint) (inf_ptrace_remove_fork_catchpoint, inf_ptrace_create_inferior) (inf_ptrace_post_startup_inferior, inf_ptrace_mourn_inferior) (inf_ptrace_attach, inf_ptrace_post_attach, inf_ptrace_detach) (inf_ptrace_detach_success, inf_ptrace_kill, inf_ptrace_resume) (inf_ptrace_wait, inf_ptrace_xfer_partial) (inf_ptrace_thread_alive, inf_ptrace_files_info) (inf_ptrace_pid_to_str, inf_ptrace_auxv_parse): Refactor as methods of inf_ptrace_target. (inf_ptrace_target): Delete function. * inf-ptrace.h: Include "inf-child.h". (inf_ptrace_target): Delete function declaration. (inf_ptrace_target): New class. (inf_ptrace_trad_target, inf_ptrace_detach_success): Delete. * linux-nat.c (linux_target): New. (linux_ops, linux_ops_saved, super_xfer_partial): Delete. (linux_nat_target::~linux_nat_target): New. (linux_child_post_attach, linux_child_post_startup_inferior) (linux_child_follow_fork, linux_child_insert_fork_catchpoint) (linux_child_remove_fork_catchpoint) (linux_child_insert_vfork_catchpoint) (linux_child_remove_vfork_catchpoint) (linux_child_insert_exec_catchpoint) (linux_child_remove_exec_catchpoint) (linux_child_set_syscall_catchpoint, linux_nat_pass_signals) (linux_nat_create_inferior, linux_nat_attach, linux_nat_detach) (linux_nat_resume, linux_nat_stopped_by_watchpoint) (linux_nat_stopped_data_address) (linux_nat_stopped_by_sw_breakpoint) (linux_nat_supports_stopped_by_sw_breakpoint) (linux_nat_stopped_by_hw_breakpoint) (linux_nat_supports_stopped_by_hw_breakpoint, linux_nat_wait) (linux_nat_kill, linux_nat_mourn_inferior) (linux_nat_xfer_partial, linux_nat_thread_alive) (linux_nat_update_thread_list, linux_nat_pid_to_str) (linux_nat_thread_name, linux_child_pid_to_exec_file) (linux_child_static_tracepoint_markers_by_strid) (linux_nat_is_async_p, linux_nat_can_async_p) (linux_nat_supports_non_stop, linux_nat_always_non_stop_p) (linux_nat_supports_multi_process) (linux_nat_supports_disable_randomization, linux_nat_async) (linux_nat_stop, linux_nat_close, linux_nat_thread_address_space) (linux_nat_core_of_thread, linux_nat_filesystem_is_local) (linux_nat_fileio_open, linux_nat_fileio_readlink) (linux_nat_fileio_unlink, linux_nat_thread_events): Refactor as methods of linux_nat_target. (linux_nat_wait_1, linux_xfer_siginfo, linux_proc_xfer_partial) (linux_proc_xfer_spu, linux_nat_xfer_osdata): Remove target_ops parameter. (check_stopped_by_watchpoint): Adjust. (linux_xfer_partial): Delete. (linux_target_install_ops, linux_target, linux_nat_add_target): Delete. (linux_nat_target::linux_nat_target): New. * linux-nat.h: Include "inf-ptrace.h". (linux_nat_target): New. (linux_target, linux_target_install_ops, linux_nat_add_target): Delete function declarations. (linux_target): Declare global. * linux-thread-db.c (thread_db_target): New. (thread_db_target::thread_db_target): New. (thread_db_ops): Delete. (the_thread_db_target): New. (thread_db_detach, thread_db_wait, thread_db_mourn_inferior) (thread_db_update_thread_list, thread_db_pid_to_str) (thread_db_extra_thread_info) (thread_db_thread_handle_to_thread_info) (thread_db_get_thread_local_address, thread_db_get_ada_task_ptid) (thread_db_resume): Refactor as methods of thread_db_target. (init_thread_db_ops): Delete. (_initialize_thread_db): Remove reference to init_thread_db_ops. * x86-linux-nat.c: Don't include "linux-nat.h". (super_post_startup_inferior): Delete. (x86_linux_nat_target::~x86_linux_nat_target): New. (x86_linux_child_post_startup_inferior) (x86_linux_read_description, x86_linux_enable_btrace) (x86_linux_disable_btrace, x86_linux_teardown_btrace) (x86_linux_read_btrace, x86_linux_btrace_conf): Refactor as methods of x86_linux_nat_target. (x86_linux_create_target): Delete. Bits folded ... (x86_linux_add_target): ... here. Now takes a linux_nat_target pointer. * x86-linux-nat.h: Include "linux-nat.h" and "x86-nat.h". (x86_linux_nat_target): New class. (x86_linux_create_target): Delete. (x86_linux_add_target): Now takes a linux_nat_target pointer. * x86-nat.c (x86_insert_watchpoint, x86_remove_watchpoint) (x86_region_ok_for_watchpoint, x86_stopped_data_address) (x86_stopped_by_watchpoint, x86_insert_hw_breakpoint) (x86_remove_hw_breakpoint, x86_can_use_hw_breakpoint) (x86_stopped_by_hw_breakpoint): Remove target_ops parameter and make extern. (x86_use_watchpoints): Delete. * x86-nat.h: Include "breakpoint.h" and "target.h". (x86_use_watchpoints): Delete. (x86_can_use_hw_breakpoint, x86_region_ok_for_hw_watchpoint) (x86_stopped_by_watchpoint, x86_stopped_data_address) (x86_insert_watchpoint, x86_remove_watchpoint) (x86_insert_hw_breakpoint, x86_remove_hw_breakpoint) (x86_stopped_by_hw_breakpoint): New declarations. (x86_nat_target): New template class. * ppc-linux-nat.c (ppc_linux_nat_target): New class. (the_ppc_linux_nat_target): New. (ppc_linux_fetch_inferior_registers) (ppc_linux_can_use_hw_breakpoint) (ppc_linux_region_ok_for_hw_watchpoint) (ppc_linux_ranged_break_num_registers) (ppc_linux_insert_hw_breakpoint, ppc_linux_remove_hw_breakpoint) (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_can_accel_watchpoint_condition) (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint) (ppc_linux_stopped_data_address, ppc_linux_stopped_by_watchpoint) (ppc_linux_watchpoint_addr_within_range) (ppc_linux_masked_watch_num_registers) (ppc_linux_store_inferior_registers, ppc_linux_auxv_parse) (ppc_linux_read_description): Refactor as methods of ppc_linux_nat_target. (_initialize_ppc_linux_nat): Adjust. Set linux_target. * procfs.c (procfs_xfer_partial): Delete forward declaration. (procfs_target): New class. (the_procfs_target): New. (procfs_target): Delete function. (procfs_auxv_parse, procfs_attach, procfs_detach) (procfs_fetch_registers, procfs_store_registers, procfs_wait) (procfs_xfer_partial, procfs_resume, procfs_pass_signals) (procfs_files_info, procfs_kill_inferior, procfs_mourn_inferior) (procfs_create_inferior, procfs_update_thread_list) (procfs_thread_alive, procfs_pid_to_str) (procfs_can_use_hw_breakpoint, procfs_stopped_by_watchpoint) (procfs_stopped_data_address, procfs_insert_watchpoint) (procfs_remove_watchpoint, procfs_region_ok_for_hw_watchpoint) (proc_find_memory_regions, procfs_info_proc) (procfs_make_note_section): Refactor as methods of procfs_target. (_initialize_procfs): Adjust. * sol-thread.c (sol_thread_target): New class. (sol_thread_ops): Now a sol_thread_target. (sol_thread_detach, sol_thread_resume, sol_thread_wait) (sol_thread_fetch_registers, sol_thread_store_registers) (sol_thread_xfer_partial, sol_thread_mourn_inferior) (sol_thread_alive, solaris_pid_to_str, sol_update_thread_list) (sol_get_ada_task_ptid): Refactor as methods of sol_thread_target. (init_sol_thread_ops): Delete. (_initialize_sol_thread): Adjust. Remove references to init_sol_thread_ops and complete_target_initialization. * windows-nat.c (windows_nat_target): New class. (windows_fetch_inferior_registers) (windows_store_inferior_registers, windows_resume, windows_wait) (windows_attach, windows_detach, windows_pid_to_exec_file) (windows_files_info, windows_create_inferior) (windows_mourn_inferior, windows_interrupt, windows_kill_inferior) (windows_close, windows_pid_to_str, windows_xfer_partial) (windows_get_tib_address, windows_get_ada_task_ptid) (windows_thread_name, windows_thread_alive): Refactor as windows_nat_target methods. (do_initial_windows_stuff): Adjust. (windows_target): Delete function. (_initialize_windows_nat): Adjust. * darwin-nat.c (darwin_resume, darwin_wait_to, darwin_interrupt) (darwin_mourn_inferior, darwin_kill_inferior) (darwin_create_inferior, darwin_attach, darwin_detach) (darwin_pid_to_str, darwin_thread_alive, darwin_xfer_partial) (darwin_pid_to_exec_file, darwin_get_ada_task_ptid) (darwin_supports_multi_process): Refactor as darwin_nat_target methods. (darwin_resume_to, darwin_files_info): Delete. (_initialize_darwin_inferior): Rename to ... (_initialize_darwin_nat): ... this. Adjust to C++ification. * darwin-nat.h: Include "inf-child.h". (darwin_nat_target): New class. (darwin_complete_target): Delete. * i386-darwin-nat.c (i386_darwin_nat_target): New class. (darwin_target): New. (i386_darwin_fetch_inferior_registers) (i386_darwin_store_inferior_registers): Refactor as methods of darwin_nat_target. (darwin_complete_target): Delete, with ... (_initialize_i386_darwin_nat): ... bits factored out here. * alpha-linux-nat.c (alpha_linux_nat_target): New class. (the_alpha_linux_nat_target): New. (alpha_linux_register_u_offset): Refactor as alpha_linux_nat_target method. (_initialize_alpha_linux_nat): Adjust. * linux-nat-trad.c (inf_ptrace_register_u_offset): Delete. (inf_ptrace_fetch_register, inf_ptrace_fetch_registers) (inf_ptrace_store_register, inf_ptrace_store_registers): Refact as methods of linux_nat_trad_target. (linux_trad_target): Delete. * linux-nat-trad.h (linux_trad_target): Delete function. (linux_nat_trad_target): New class. * mips-linux-nat.c (mips_linux_nat_target): New class. (super_fetch_registers, super_store_registers, super_close): Delete. (the_mips_linux_nat_target): New. (mips64_linux_regsets_fetch_registers) (mips64_linux_regsets_store_registers) (mips64_linux_fetch_registers, mips64_linux_store_registers) (mips_linux_register_u_offset, mips_linux_read_description) (mips_linux_can_use_hw_breakpoint) (mips_linux_stopped_by_watchpoint) (mips_linux_stopped_data_address) (mips_linux_region_ok_for_hw_watchpoint) (mips_linux_insert_watchpoint, mips_linux_remove_watchpoint) (mips_linux_close): Refactor as methods of mips_linux_nat. (_initialize_mips_linux_nat): Adjust to C++ification. * aix-thread.c (aix_thread_target): New class. (aix_thread_ops): Now an aix_thread_target. (aix_thread_detach, aix_thread_resume, aix_thread_wait) (aix_thread_fetch_registers, aix_thread_store_registers) (aix_thread_xfer_partial, aix_thread_mourn_inferior) (aix_thread_thread_alive, aix_thread_pid_to_str) (aix_thread_extra_thread_info, aix_thread_get_ada_task_ptid): Refactor as methods of aix_thread_target. (init_aix_thread_ops): Delete. (_initialize_aix_thread): Remove references to init_aix_thread_ops and complete_target_initialization. * rs6000-nat.c (rs6000_xfer_shared_libraries): Delete. (rs6000_nat_target): New class. (the_rs6000_nat_target): New. (rs6000_fetch_inferior_registers, rs6000_store_inferior_registers) (rs6000_xfer_partial, rs6000_wait, rs6000_create_inferior) (rs6000_xfer_shared_libraries): Refactor as rs6000_nat_target methods. (super_create_inferior): Delete. (_initialize_rs6000_nat): Adjust to C++ification. * arm-linux-nat.c (arm_linux_nat_target): New class. (the_arm_linux_nat_target): New. (arm_linux_fetch_inferior_registers) (arm_linux_store_inferior_registers, arm_linux_read_description) (arm_linux_can_use_hw_breakpoint, arm_linux_insert_hw_breakpoint) (arm_linux_remove_hw_breakpoint) (arm_linux_region_ok_for_hw_watchpoint) (arm_linux_insert_watchpoint, arm_linux_remove_watchpoint) (arm_linux_stopped_data_address, arm_linux_stopped_by_watchpoint) (arm_linux_watchpoint_addr_within_range): Refactor as methods of arm_linux_nat_target. (_initialize_arm_linux_nat): Adjust to C++ification. * aarch64-linux-nat.c (aarch64_linux_nat_target): New class. (the_aarch64_linux_nat_target): New. (aarch64_linux_fetch_inferior_registers) (aarch64_linux_store_inferior_registers) (aarch64_linux_child_post_startup_inferior) (aarch64_linux_read_description) (aarch64_linux_can_use_hw_breakpoint) (aarch64_linux_insert_hw_breakpoint) (aarch64_linux_remove_hw_breakpoint) (aarch64_linux_insert_watchpoint, aarch64_linux_remove_watchpoint) (aarch64_linux_region_ok_for_hw_watchpoint) (aarch64_linux_stopped_data_address) (aarch64_linux_stopped_by_watchpoint) (aarch64_linux_watchpoint_addr_within_range) (aarch64_linux_can_do_single_step): Refactor as methods of aarch64_linux_nat_target. (super_post_startup_inferior): Delete. (_initialize_aarch64_linux_nat): Adjust to C++ification. * hppa-linux-nat.c (hppa_linux_nat_target): New class. (the_hppa_linux_nat_target): New. (hppa_linux_fetch_inferior_registers) (hppa_linux_store_inferior_registers): Refactor as methods of hppa_linux_nat_target. (_initialize_hppa_linux_nat): Adjust to C++ification. * ia64-linux-nat.c (ia64_linux_nat_target): New class. (the_ia64_linux_nat_target): New. (ia64_linux_insert_watchpoint, ia64_linux_remove_watchpoint) (ia64_linux_stopped_data_address) (ia64_linux_stopped_by_watchpoint, ia64_linux_fetch_registers) (ia64_linux_store_registers, ia64_linux_xfer_partial): Refactor as ia64_linux_nat_target methods. (super_xfer_partial): Delete. (_initialize_ia64_linux_nat): Adjust to C++ification. * m32r-linux-nat.c (m32r_linux_nat_target): New class. (the_m32r_linux_nat_target): New. (m32r_linux_fetch_inferior_registers) (m32r_linux_store_inferior_registers): Refactor as m32r_linux_nat_target methods. (_initialize_m32r_linux_nat): Adjust to C++ification. * m68k-linux-nat.c (m68k_linux_nat_target): New class. (the_m68k_linux_nat_target): New. (m68k_linux_fetch_inferior_registers) (m68k_linux_store_inferior_registers): Refactor as m68k_linux_nat_target methods. (_initialize_m68k_linux_nat): Adjust to C++ification. * s390-linux-nat.c (s390_linux_nat_target): New class. (the_s390_linux_nat_target): New. (s390_linux_fetch_inferior_registers) (s390_linux_store_inferior_registers, s390_stopped_by_watchpoint) (s390_insert_watchpoint, s390_remove_watchpoint) (s390_can_use_hw_breakpoint, s390_insert_hw_breakpoint) (s390_remove_hw_breakpoint, s390_region_ok_for_hw_watchpoint) (s390_auxv_parse, s390_read_description): Refactor as methods of s390_linux_nat_target. (_initialize_s390_nat): Adjust to C++ification. * sparc-linux-nat.c (sparc_linux_nat_target): New class. (the_sparc_linux_nat_target): New. (_initialize_sparc_linux_nat): Adjust to C++ification. * sparc-nat.c (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc64-linux-nat.c (sparc64_linux_nat_target): New class. (the_sparc64_linux_nat_target): New. (_initialize_sparc64_linux_nat): Adjust to C++ification. * spu-linux-nat.c (spu_linux_nat_target): New class. (the_spu_linux_nat_target): New. (spu_child_post_startup_inferior, spu_child_post_attach) (spu_child_wait, spu_fetch_inferior_registers) (spu_store_inferior_registers, spu_xfer_partial) (spu_can_use_hw_breakpoint): Refactor as spu_linux_nat_target methods. (_initialize_spu_nat): Adjust to C++ification. * tilegx-linux-nat.c (tilegx_linux_nat_target): New class. (the_tilegx_linux_nat_target): New. (fetch_inferior_registers, store_inferior_registers): Refactor as methods. (_initialize_tile_linux_nat): Adjust to C++ification. * xtensa-linux-nat.c (xtensa_linux_nat_target): New class. (the_xtensa_linux_nat_target): New. (xtensa_linux_fetch_inferior_registers) (xtensa_linux_store_inferior_registers): Refactor as xtensa_linux_nat_target methods. (_initialize_xtensa_linux_nat): Adjust to C++ification. * fbsd-nat.c (USE_SIGTRAP_SIGINFO): Delete. (fbsd_pid_to_exec_file, fbsd_find_memory_regions) (fbsd_find_memory_regions, fbsd_info_proc, fbsd_xfer_partial) (fbsd_thread_alive, fbsd_pid_to_str, fbsd_thread_name) (fbsd_update_thread_list, fbsd_resume, fbsd_wait) (fbsd_stopped_by_sw_breakpoint) (fbsd_supports_stopped_by_sw_breakpoint, fbsd_follow_fork) (fbsd_insert_fork_catchpoint, fbsd_remove_fork_catchpoint) (fbsd_insert_vfork_catchpoint, fbsd_remove_vfork_catchpoint) (fbsd_post_startup_inferior, fbsd_post_attach) (fbsd_insert_exec_catchpoint, fbsd_remove_exec_catchpoint) (fbsd_set_syscall_catchpoint) (super_xfer_partial, super_resume, super_wait) (fbsd_supports_stopped_by_hw_breakpoint): Delete. (fbsd_handle_debug_trap): Remove target_ops parameter. (fbsd_nat_add_target): Delete. * fbsd-nat.h: Include "inf-ptrace.h". (fbsd_nat_add_target): Delete. (USE_SIGTRAP_SIGINFO): Define. (fbsd_nat_target): New class. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers) (amd64bsd_store_inferior_registers): Remove target_ops parameter. (amd64bsd_target): Delete. * amd64-bsd-nat.h: New file. * amd64-fbsd-nat.c: Include "amd64-bsd-nat.h" instead of "x86-bsd-nat.h". (amd64_fbsd_nat_target): New class. (the_amd64_fbsd_nat_target): New. (amd64fbsd_read_description): Refactor as method of amd64_fbsd_nat_target. (amd64_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_amd64fbsd_nat): Adjust to C++ification. * amd64-nat.h (amd64bsd_target): Delete function declaration. * i386-bsd-nat.c (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Remove target_ops parameter. (i386bsd_target): Delete. * i386-bsd-nat.h (i386bsd_target): Delete function declaration. (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Declare. (i386_bsd_nat_target): New class. * i386-fbsd-nat.c (i386_fbsd_nat_target): New class. (the_i386_fbsd_nat_target): New. (i386fbsd_resume, i386fbsd_read_description): Refactor as i386_fbsd_nat_target methods. (i386_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_i386fbsd_nat): Adjust to C++ification. * x86-bsd-nat.c (super_mourn_inferior): Delete. (x86bsd_mourn_inferior, x86bsd_target): Delete. (_initialize_x86_bsd_nat): Adjust to C++ification. * x86-bsd-nat.h: Include "x86-nat.h". (x86bsd_target): Delete declaration. (x86bsd_nat_target): New class. * aarch64-fbsd-nat.c (aarch64_fbsd_nat_target): New class. (the_aarch64_fbsd_nat_target): New. (aarch64_fbsd_fetch_inferior_registers) (aarch64_fbsd_store_inferior_registers): Refactor as methods of aarch64_fbsd_nat_target. (_initialize_aarch64_fbsd_nat): Adjust to C++ification. * alpha-bsd-nat.c (alpha_bsd_nat_target): New class. (the_alpha_bsd_nat_target): New. (alphabsd_fetch_inferior_registers) (alphabsd_store_inferior_registers): Refactor as alpha_bsd_nat_target methods. (_initialize_alphabsd_nat): Refactor as methods of alpha_bsd_nat_target. * amd64-nbsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_nbsd_nat_target): New. (_initialize_amd64nbsd_nat): Adjust to C++ification. * amd64-obsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_obsd_nat_target): New. (_initialize_amd64obsd_nat): Adjust to C++ification. * arm-fbsd-nat.c (arm_fbsd_nat_target): New. (the_arm_fbsd_nat_target): New. (arm_fbsd_fetch_inferior_registers) (arm_fbsd_store_inferior_registers, arm_fbsd_read_description): (_initialize_arm_fbsd_nat): Refactor as methods of arm_fbsd_nat_target. (_initialize_arm_fbsd_nat): Adjust to C++ification. * arm-nbsd-nat.c (arm_netbsd_nat_target): New class. (the_arm_netbsd_nat_target): New. (armnbsd_fetch_registers, armnbsd_store_registers): Refactor as arm_netbsd_nat_target. (_initialize_arm_netbsd_nat): Adjust to C++ification. * hppa-nbsd-nat.c (hppa_nbsd_nat_target): New class. (the_hppa_nbsd_nat_target): New. (hppanbsd_fetch_registers, hppanbsd_store_registers): Refactor as hppa_nbsd_nat_target methods. (_initialize_hppanbsd_nat): Adjust to C++ification. * hppa-obsd-nat.c (hppa_obsd_nat_target): New class. (the_hppa_obsd_nat_target): New. (hppaobsd_fetch_registers, hppaobsd_store_registers): Refactor as methods of hppa_obsd_nat_target. (_initialize_hppaobsd_nat): Adjust to C++ification. Use add_target. * i386-nbsd-nat.c (the_i386_nbsd_nat_target): New. (_initialize_i386nbsd_nat): Adjust to C++ification. Use add_target. * i386-obsd-nat.c (the_i386_obsd_nat_target): New. (_initialize_i386obsd_nat): Use add_target. * m68k-bsd-nat.c (m68k_bsd_nat_target): New class. (the_m68k_bsd_nat_target): New. (m68kbsd_fetch_inferior_registers) (m68kbsd_store_inferior_registers): Refactor as methods of m68k_bsd_nat_target. (_initialize_m68kbsd_nat): Adjust to C++ification. * mips-fbsd-nat.c (mips_fbsd_nat_target): New class. (the_mips_fbsd_nat_target): New. (mips_fbsd_fetch_inferior_registers) (mips_fbsd_store_inferior_registers): Refactor as methods of mips_fbsd_nat_target. (_initialize_mips_fbsd_nat): Adjust to C++ification. Use add_target. * mips-nbsd-nat.c (mips_nbsd_nat_target): New class. (the_mips_nbsd_nat_target): New. (mipsnbsd_fetch_inferior_registers) (mipsnbsd_store_inferior_registers): Refactor as methods of mips_nbsd_nat_target. (_initialize_mipsnbsd_nat): Adjust to C++ification. * mips64-obsd-nat.c (mips64_obsd_nat_target): New class. (the_mips64_obsd_nat_target): New. (mips64obsd_fetch_inferior_registers) (mips64obsd_store_inferior_registers): Refactor as methods of mips64_obsd_nat_target. (_initialize_mips64obsd_nat): Adjust to C++ification. Use add_target. * nbsd-nat.c (nbsd_pid_to_exec_file): Refactor as method of nbsd_nat_target. * nbsd-nat.h: Include "inf-ptrace.h". (nbsd_nat_target): New class. * obsd-nat.c (obsd_pid_to_str, obsd_update_thread_list) (obsd_wait): Refactor as methods of obsd_nat_target. (obsd_add_target): Delete. * obsd-nat.h: Include "inf-ptrace.h". (obsd_nat_target): New class. * ppc-fbsd-nat.c (ppc_fbsd_nat_target): New class. (the_ppc_fbsd_nat_target): New. (ppcfbsd_fetch_inferior_registers) (ppcfbsd_store_inferior_registers): Refactor as methods of ppc_fbsd_nat_target. (_initialize_ppcfbsd_nat): Adjust to C++ification. Use add_target. * ppc-nbsd-nat.c (ppc_nbsd_nat_target): New class. (the_ppc_nbsd_nat_target): New. (ppcnbsd_fetch_inferior_registers) (ppcnbsd_store_inferior_registers): Refactor as methods of ppc_nbsd_nat_target. (_initialize_ppcnbsd_nat): Adjust to C++ification. * ppc-obsd-nat.c (ppc_obsd_nat_target): New class. (the_ppc_obsd_nat_target): New. (ppcobsd_fetch_registers, ppcobsd_store_registers): Refactor as methods of ppc_obsd_nat_target. (_initialize_ppcobsd_nat): Adjust to C++ification. Use add_target. * sh-nbsd-nat.c (sh_nbsd_nat_target): New class. (the_sh_nbsd_nat_target): New. (shnbsd_fetch_inferior_registers) (shnbsd_store_inferior_registers): Refactor as methods of sh_nbsd_nat_target. (_initialize_shnbsd_nat): Adjust to C++ification. * sparc-nat.c (sparc_xfer_wcookie): Make extern. (inf_ptrace_xfer_partial): Delete. (sparc_xfer_partial, sparc_target): Delete. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers, sparc_xfer_wcookie): Declare. (sparc_target): Delete function declaration. (sparc_target): New template class. * sparc-nbsd-nat.c (the_sparc_nbsd_nat_target): New. (_initialize_sparcnbsd_nat): Adjust to C++ification. * sparc64-fbsd-nat.c (the_sparc64_fbsd_nat_target): New. (_initialize_sparc64fbsd_nat): Adjust to C++ification. Use add_target. * sparc64-nbsd-nat.c (the_sparc64_nbsd_nat_target): New. (_initialize_sparc64nbsd_nat): Adjust to C++ification. * sparc64-obsd-nat.c (the_sparc64_obsd_nat_target): New. (_initialize_sparc64obsd_nat): Adjust to C++ification. Use add_target. * vax-bsd-nat.c (vax_bsd_nat_target): New class. (the_vax_bsd_nat_target): New. (vaxbsd_fetch_inferior_registers) (vaxbsd_store_inferior_registers): Refactor as vax_bsd_nat_target methods. (_initialize_vaxbsd_nat): Adjust to C++ification. * bsd-kvm.c (bsd_kvm_target): New class. (bsd_kvm_ops): Now a bsd_kvm_target. (bsd_kvm_open, bsd_kvm_close, bsd_kvm_xfer_partial) (bsd_kvm_files_info, bsd_kvm_fetch_registers) (bsd_kvm_thread_alive, bsd_kvm_pid_to_str): Refactor as methods of bsd_kvm_target. (bsd_kvm_return_one): Delete. (bsd_kvm_add_target): Adjust to C++ification. * nto-procfs.c (nto_procfs_target, nto_procfs_target_native) (nto_procfs_target_procfs): New classes. (procfs_open_1, procfs_thread_alive, procfs_update_thread_list) (procfs_files_info, procfs_pid_to_exec_file, procfs_attach) (procfs_post_attach, procfs_wait, procfs_fetch_registers) (procfs_xfer_partial, procfs_detach, procfs_insert_breakpoint) (procfs_remove_breakpoint, procfs_insert_hw_breakpoint) (procfs_remove_hw_breakpoint, procfs_resume) (procfs_mourn_inferior, procfs_create_inferior, procfs_interrupt) (procfs_kill_inferior, procfs_store_registers) (procfs_pass_signals, procfs_pid_to_str, procfs_can_run): Refactor as methods of nto_procfs_target. (nto_procfs_ops): Now an nto_procfs_target_procfs. (nto_native_ops): Delete. (procfs_open, procfs_native_open): Delete. (nto_native_ops): Now an nto_procfs_target_native. (init_procfs_targets): Adjust to C++ification. (procfs_can_use_hw_breakpoint, procfs_remove_hw_watchpoint) (procfs_insert_hw_watchpoint, procfs_stopped_by_watchpoint): Refactor as methods of nto_procfs_target. * go32-nat.c (go32_nat_target): New class. (the_go32_nat_target): New. (go32_attach, go32_resume, go32_wait, go32_fetch_registers) (go32_store_registers, go32_xfer_partial, go32_files_info) (go32_kill_inferior, go32_create_inferior, go32_mourn_inferior) (go32_terminal_init, go32_terminal_info, go32_terminal_inferior) (go32_terminal_ours, go32_pass_ctrlc, go32_thread_alive) (go32_pid_to_str): Refactor as methods of go32_nat_target. (go32_target): Delete. (_initialize_go32_nat): Adjust to C++ification. * gnu-nat.c (gnu_wait, gnu_resume, gnu_kill_inferior) (gnu_mourn_inferior, gnu_create_inferior, gnu_attach, gnu_detach) (gnu_stop, gnu_thread_alive, gnu_xfer_partial) (gnu_find_memory_regions, gnu_pid_to_str): Refactor as methods of gnu_nat_target. (gnu_target): Delete. * gnu-nat.h (gnu_target): Delete. (gnu_nat_target): New class. * i386-gnu-nat.c (gnu_base_target): New. (i386_gnu_nat_target): New class. (the_i386_gnu_nat_target): New. (_initialize_i386gnu_nat): Adjust to C++ification. gdb/testsuite/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * gdb.base/breakpoint-in-ro-region.exp: Adjust to to_resume and to_log_command renames. * gdb.base/sss-bp-on-user-bp-2.exp: Likewise.
2018-05-03 07:37:22 +08:00
override;
int masked_watch_num_registers (CORE_ADDR, CORE_ADDR) override;
int ranged_break_num_registers () override;
const struct target_desc *read_description () override;
int auxv_parse (gdb_byte **readptr,
gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
override;
linux_nat_target: More low methods This converts the remaining linux-nat.c hooks low_ methods like had been started in a previous patch. The linux_nat_set_foo routines are all gone with this. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * linux-nat.h (linux_nat_target) <low_new_thread, low_delete_thread, low_new_fork, low_forget_process, low_prepare_to_resume, low_siginfo_fixup, low_status_is_event>: New virtual methods. (linux_nat_set_new_thread, linux_nat_set_delete_thread) (linux_nat_new_fork_ftype, linux_nat_set_new_fork) (linux_nat_forget_process_ftype, linux_nat_set_forget_process) (linux_nat_forget_process, linux_nat_set_siginfo_fixup) (linux_nat_set_prepare_to_resume, linux_nat_set_status_is_event): Delete. * linux-fork.c (delete_fork): Adjust to call low method. * linux-nat.c (linux_nat_new_thread, linux_nat_delete_thread) (linux_nat_new_fork, linux_nat_forget_process_hook) (linux_nat_prepare_to_resume, linux_nat_siginfo_fixup) (linux_nat_status_is_event): (linux_nat_target::follow_fork, lwp_free, add_lwp, detach_one_lwp) (linux_resume_one_lwp_throw, linux_handle_extended_wait): Adjust to call low method. (sigtrap_is_event): Rename to ... (linux_nat_target::low_status_is_event): ... this. (linux_nat_set_status_is_event): Delete. (save_stop_reason, linux_nat_wait_1) (linux_nat_target::mourn_inferior, siginfo_fixup): Adjust to call low methods. (linux_nat_set_new_thread, linux_nat_set_delete_thread) (linux_nat_set_new_fork, linux_nat_set_forget_process) (linux_nat_forget_process, linux_nat_set_siginfo_fixup) (linux_nat_set_prepare_to_resume): Delete. * aarch64-linux-nat.c: All linux_nat_set_* callbacks converted to low virtual methods. * amd64-linux-nat.c: Likewise. * arm-linux-nat.c: Likewise. * i386-linux-nat.c: Likewise. * ia64-linux-nat.c: Likewise. * mips-linux-nat.c: Likewise. * ppc-linux-nat.c: Likewise. * s390-linux-nat.c: Likewise. * sparc64-linux-nat.c: Likewise. * x86-linux-nat.c: Likewise. * x86-linux-nat.h: Include "nat/x86-linux.h". (x86_linux_nat_target) <low_new_fork, low_forget_process, low_prepare_to_resume, low_new_thread, low_delete_thread>: Override methods.
2018-05-03 07:37:27 +08:00
/* Override linux_nat_target low methods. */
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
bool low_stopped_by_watchpoint () override;
bool low_stopped_data_address (CORE_ADDR *) override;
linux_nat_target: More low methods This converts the remaining linux-nat.c hooks low_ methods like had been started in a previous patch. The linux_nat_set_foo routines are all gone with this. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * linux-nat.h (linux_nat_target) <low_new_thread, low_delete_thread, low_new_fork, low_forget_process, low_prepare_to_resume, low_siginfo_fixup, low_status_is_event>: New virtual methods. (linux_nat_set_new_thread, linux_nat_set_delete_thread) (linux_nat_new_fork_ftype, linux_nat_set_new_fork) (linux_nat_forget_process_ftype, linux_nat_set_forget_process) (linux_nat_forget_process, linux_nat_set_siginfo_fixup) (linux_nat_set_prepare_to_resume, linux_nat_set_status_is_event): Delete. * linux-fork.c (delete_fork): Adjust to call low method. * linux-nat.c (linux_nat_new_thread, linux_nat_delete_thread) (linux_nat_new_fork, linux_nat_forget_process_hook) (linux_nat_prepare_to_resume, linux_nat_siginfo_fixup) (linux_nat_status_is_event): (linux_nat_target::follow_fork, lwp_free, add_lwp, detach_one_lwp) (linux_resume_one_lwp_throw, linux_handle_extended_wait): Adjust to call low method. (sigtrap_is_event): Rename to ... (linux_nat_target::low_status_is_event): ... this. (linux_nat_set_status_is_event): Delete. (save_stop_reason, linux_nat_wait_1) (linux_nat_target::mourn_inferior, siginfo_fixup): Adjust to call low methods. (linux_nat_set_new_thread, linux_nat_set_delete_thread) (linux_nat_set_new_fork, linux_nat_set_forget_process) (linux_nat_forget_process, linux_nat_set_siginfo_fixup) (linux_nat_set_prepare_to_resume): Delete. * aarch64-linux-nat.c: All linux_nat_set_* callbacks converted to low virtual methods. * amd64-linux-nat.c: Likewise. * arm-linux-nat.c: Likewise. * i386-linux-nat.c: Likewise. * ia64-linux-nat.c: Likewise. * mips-linux-nat.c: Likewise. * ppc-linux-nat.c: Likewise. * s390-linux-nat.c: Likewise. * sparc64-linux-nat.c: Likewise. * x86-linux-nat.c: Likewise. * x86-linux-nat.h: Include "nat/x86-linux.h". (x86_linux_nat_target) <low_new_fork, low_forget_process, low_prepare_to_resume, low_new_thread, low_delete_thread>: Override methods.
2018-05-03 07:37:27 +08:00
void low_new_thread (struct lwp_info *lp) override;
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
void low_delete_thread (arch_lwp_info *) override;
void low_new_fork (struct lwp_info *, pid_t) override;
void low_new_clone (struct lwp_info *, pid_t) override;
void low_forget_process (pid_t pid) override;
void low_prepare_to_resume (struct lwp_info *) override;
private:
void copy_thread_dreg_state (const ptid_t &parent_ptid,
const ptid_t &child_ptid);
void mark_thread_stale (struct lwp_info *lp);
void mark_debug_registers_changed (pid_t pid);
void register_hw_breakpoint (pid_t pid,
const struct ppc_hw_breakpoint &bp);
void clear_hw_breakpoint (pid_t pid,
const struct ppc_hw_breakpoint &a);
void register_wp (pid_t pid, long wp_value);
void clear_wp (pid_t pid);
bool can_use_watchpoint_cond_accel (void);
void calculate_dvc (CORE_ADDR addr, int len,
CORE_ADDR data_value,
uint32_t *condition_mode,
uint64_t *condition_value);
int check_condition (CORE_ADDR watch_addr,
struct expression *cond,
CORE_ADDR *data_value, int *len);
int num_memory_accesses (const std::vector<value_ref_ptr> &chain);
int get_trigger_type (enum target_hw_bp_type type);
void create_watchpoint_request (struct ppc_hw_breakpoint *p,
CORE_ADDR addr,
int len,
enum target_hw_bp_type type,
struct expression *cond,
int insert);
bool hwdebug_point_cmp (const struct ppc_hw_breakpoint &a,
const struct ppc_hw_breakpoint &b);
void init_arch_lwp_info (struct lwp_info *lp);
arch_lwp_info *get_arch_lwp_info (struct lwp_info *lp);
/* The ptrace interface we'll use to install hardware watchpoints and
breakpoints (debug registers). */
ppc_linux_dreg_interface m_dreg_interface;
/* A map from pids to structs containing info specific to each
process. */
std::unordered_map<pid_t, ppc_linux_process_info> m_process_info;
/* Callable object to hash ptids by their lwp number. */
struct ptid_hash
{
std::size_t operator() (const ptid_t &ptid) const
{
return std::hash<long>{} (ptid.lwp ());
}
};
/* A map from ptid_t objects to a list of pairs of slots and hardware
breakpoint objects. This keeps track of which hardware breakpoints
and watchpoints were last installed in each slot of each thread.
Only used when the interface is HWDEBUG. */
std::unordered_map <ptid_t,
std::list<std::pair<long, ppc_hw_breakpoint>>,
ptid_hash> m_installed_hw_bps;
Convert struct target_ops to C++ I.e., use C++ virtual methods and inheritance instead of tables of function pointers. Unfortunately, there's no way to do a smooth transition. ALL native targets in the tree must be converted at the same time. I've tested all I could with cross compilers and with help from GCC compile farm, but naturally I haven't been able to test many of the ports. Still, I made a best effort to port everything over, and while I expect some build problems due to typos and such, which should be trivial to fix, I don't expect any design problems. * Implementation notes: - The flattened current_target is gone. References to current_target or current_target.beneath are replaced with references to target_stack (the top of the stack) directly. - To keep "set debug target" working, this adds a new debug_stratum layer that sits on top of the stack, prints the debug, and delegates to the target beneath. In addition, this makes the shortname and longname properties of target_ops be virtual methods instead of data fields, and makes the debug target defer those to the target beneath. This is so that debug code sprinkled around that does "if (debugtarget) ..." can transparently print the name of the target beneath. A patch later in the series actually splits out the shortname/longname methods to a separate structure, but I preferred to keep that chance separate as it is associated with changing a bit the design of how targets are registered and open. - Since you can't check whether a C++ virtual method is overridden, the old method of checking whether a target_ops implements a method by comparing the function pointer must be replaced with something else. Some cases are fixed by adding a parallel "can_do_foo" target_ops methods. E.g.,: + for (t = target_stack; t != NULL; t = t->beneath) { - if (t->to_create_inferior != NULL) + if (t->can_create_inferior ()) break; } Others are fixed by changing void return type to bool or int return type, and have the default implementation return false or -1, to indicate lack of support. - make-target-delegates was adjusted to generate C++ classes and methods. It needed tweaks to grok "virtual" in front of the target method name, and for the fact that methods are no longer function pointers. (In particular, the current code parsing the return type was simple because it could simply parse up until the '(' in '(*to_foo)'. It now generates a couple C++ classes that inherit target_ops: dummy_target and debug_target. Since we need to generate the class declarations as well, i.e., we need to emit methods twice, we now generate the code in two passes. - The core_target global is renamed to avoid conflict with the "core_target" class. - ctf/tfile targets init_tracefile_ops is replaced by a base class that is inherited by both ctf and tfile. - bsd-uthread The bsd_uthread_ops_hack hack is gone. It's not needed because nothing was extending a target created by bsd_uthread_target. - remote/extended-remote targets This is a first pass, just enough to C++ify target_ops. A later pass will convert more free functions to methods, and make remote_state be truly per remote instance, allowing multiple simultaneous instances of remote targets. - inf-child/"native" is converted to an actual base class (inf_child_target), that is inherited by all native targets. - GNU/Linux The old weird double-target linux_ops mechanism in linux-nat.c, is gone, replaced by adding a few virtual methods to linux-nat.h's target_ops, called low_XXX, that the concrete linux-nat implementations override. Sort of like gdbserver's linux_target_ops, but simpler, for requiring only one target_ops-like hierarchy, which spares implementing the same method twice when we need to forward the method to a low implementation. The low target simply reimplements the target_ops method directly in that case. There are a few remaining linux-nat.c hooks that would be better converted to low_ methods like above too. E.g.: linux_nat_set_new_thread (t, x86_linux_new_thread); linux_nat_set_new_fork (t, x86_linux_new_fork); linux_nat_set_forget_process That'll be done in a follow up patch. - We can no longer use functions like x86_use_watchpoints to install custom methods on an arbitrary base target. The patch replaces instances of such a pattern with template mixins. For example memory_breakpoint_target defined in target.h, or x86_nat_target in x86-nat.h. - linux_trad_target, MIPS and Alpha GNU/Linux The code in the new linux-nat-trad.h/c files which was split off of inf-ptrace.h/c recently, is converted to a C++ base class, and used by the MIPS and Alpha GNU/Linux ports. - BSD targets The $architecture x NetBSD/OpenBSD/FreeBSD support matrix complicates things a bit. There's common BSD target code, and there's common architecture-specific code shared between the different BSDs. Currently, all that is stiched together to form a final target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target functions etc. This introduces new fbsd_nat_target, obsd_nat_target and nbsd_nat_target classes that serve as base/prototype target for the corresponding BSD variant. And introduces generic i386/AMD64 BSD targets, to be used as template mixin to build a final target. Similarly, a generic SPARC target is added, used by both BSD and Linux ports. - bsd_kvm_add_target, BSD libkvm target I considered making bsd_kvm_supply_pcb a virtual method, and then have each port inherit bsd_kvm_target and override that method, but that was resulting in lots of unjustified churn, so I left the function pointer mechanism alone. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> John Baldwin <jhb@freebsd.org> * target.h (enum strata) <debug_stratum>: New. (struct target_ops) <all delegation methods>: Replace by C++ virtual methods, and drop "to_" prefix. All references updated throughout. <to_shortname, to_longname, to_doc, to_data, to_have_steppable_watchpoint, to_have_continuable_watchpoint, to_has_thread_control, to_attach_no_wait>: Delete, replaced by virtual methods. All references updated throughout. <can_attach, supports_terminal_ours, can_create_inferior, get_thread_control_capabilities, attach_no_wait>: New virtual methods. <insert_breakpoint, remove_breakpoint>: Now TARGET_DEFAULT_NORETURN methods. <info_proc>: Now returns bool. <to_magic>: Delete. (OPS_MAGIC): Delete. (current_target): Delete. All references replaced by references to ... (target_stack): ... this. New. (target_shortname, target_longname): Adjust. (target_can_run): Now a function declaration. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (memory_breakpoint_target): New template class. (test_target_ops): Refactor as a C++ class with virtual methods. * make-target-delegates (NAME_PART): Tighten. (POINTER_PART, CP_SYMBOL): New. (SIMPLE_RETURN_PART): Reimplement. (VEC_RETURN_PART): Expect less. (RETURN_PART, VIRTUAL_PART): New. (METHOD): Adjust to C++ virtual methods. (scan_target_h): Remove reference to C99. (dname): Output "target_ops::" prefix. (write_function_header): Adjust to output a C++ class method. (write_declaration): New. (write_delegator): Adjust to output a C++ class method. (tdname): Output "dummy_target::" prefix. (write_tdefault, write_debugmethod): Adjust to output a C++ class method. (tdefault_names, debug_names): Delete. (return_types, tdefaults, styles, argtypes_array): New. (top level): All methods are delegators. (print_class): New. (top level): Print dummy_target and debug_target classes. * target-delegates.c: Regenerate. * target-debug.h (target_debug_print_enum_info_proc_what) (target_debug_print_thread_control_capabilities) (target_debug_print_thread_info_p): New. * target.c (dummy_target): Delete. (the_dummy_target, the_debug_target): New. (target_stack): Now extern. (set_targetdebug): Push/unpush debug target. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (add_target_with_completer): No longer call complete_target_initialization. (target_supports_terminal_ours): Use regular delegation. (update_current_target): Delete. (push_target): No longer check magic number. Don't call update_current_target. (unpush_target): Don't call update_current_target. (target_is_pushed): No longer check magic number. (target_require_runnable): Skip for all stratums over process_stratum. (target_ops::info_proc): New. (target_info_proc): Use find_target_at and find_default_run_target. (target_supports_disable_randomization): Use regular delegation. (target_get_osdata): Use find_target_at. (target_ops::open, target_ops::close, target_ops::can_attach) (target_ops::attach, target_ops::can_create_inferior) (target_ops::create_inferior, target_ops::can_run) (target_can_run): New. (default_fileio_target): Use regular delegation. (target_ops::fileio_open, target_ops::fileio_pwrite) (target_ops::fileio_pread, target_ops::fileio_fstat) (target_ops::fileio_close, target_ops::fileio_unlink) (target_ops::fileio_readlink): New. (target_fileio_open_1, target_fileio_unlink) (target_fileio_readlink): Always call the target method. Handle FILEIO_ENOSYS. (return_zero, return_zero_has_execution): Delete. (init_dummy_target): Delete. (dummy_target::dummy_target, dummy_target::shortname) (dummy_target::longname, dummy_target::doc) (debug_target::debug_target, debug_target::shortname) (debug_target::longname, debug_target::doc): New. (target_supports_delete_record): Use regular delegation. (setup_target_debug): Delete. (maintenance_print_target_stack): Skip debug_stratum. (initialize_targets): Instantiate the_dummy_target and the_debug_target. * auxv.c (target_auxv_parse): Remove 'ops' parameter. Adjust to use target_stack. (target_auxv_search, fprint_target_auxv): Adjust. (info_auxv_command): Adjust to use target_stack. * auxv.h (target_auxv_parse): Remove 'ops' parameter. * exceptions.c (print_flush): Handle a NULL target_stack. * regcache.c (target_ops_no_register): Refactor as class with virtual methods. * exec.c (exec_target): New class. (exec_ops): Now an exec_target. (exec_open, exec_close_1, exec_get_section_table) (exec_xfer_partial, exec_files_info, exec_has_memory) (exec_make_note_section): Refactor as exec_target methods. (exec_file_clear, ignore, exec_remove_breakpoint, init_exec_ops): Delete. (exec_target::find_memory_regions): New. (_initialize_exec): Don't call init_exec_ops. * gdbcore.h (exec_file_clear): Delete. * corefile.c (core_target): Delete. (core_file_command): Adjust. * corelow.c (core_target): New class. (the_core_target): New. (core_close): Remove target_ops parameter. (core_close_cleanup): Adjust. (core_target::close): New. (core_open, core_detach, get_core_registers, core_files_info) (core_xfer_partial, core_thread_alive, core_read_description) (core_pid_to_str, core_thread_name, core_has_memory) (core_has_stack, core_has_registers, core_info_proc): Rework as core_target methods. (ignore, core_remove_breakpoint, init_core_ops): Delete. (_initialize_corelow): Initialize the_core_target. * gdbcore.h (core_target): Delete. (the_core_target): New. * ctf.c: (ctf_target): New class. (ctf_ops): Now a ctf_target. (ctf_open, ctf_close, ctf_files_info, ctf_fetch_registers) (ctf_xfer_partial, ctf_get_trace_state_variable_value) (ctf_trace_find, ctf_traceframe_info): Refactor as ctf_target methods. (init_ctf_ops): Delete. (_initialize_ctf): Don't call it. * tracefile-tfile.c (tfile_target): New class. (tfile_ops): Now a tfile_target. (tfile_open, tfile_close, tfile_files_info) (tfile_get_tracepoint_status, tfile_trace_find) (tfile_fetch_registers, tfile_xfer_partial) (tfile_get_trace_state_variable_value, tfile_traceframe_info): Refactor as tfile_target methods. (tfile_xfer_partial_features): Remove target_ops parameter. (init_tfile_ops): Delete. (_initialize_tracefile_tfile): Don't call it. * tracefile.c (tracefile_has_all_memory, tracefile_has_memory) (tracefile_has_stack, tracefile_has_registers) (tracefile_thread_alive, tracefile_get_trace_status): Refactor as tracefile_target methods. (init_tracefile_ops): Delete. (tracefile_target::tracefile_target): New. * tracefile.h: Include "target.h". (tracefile_target): New class. (init_tracefile_ops): Delete. * spu-multiarch.c (spu_multiarch_target): New class. (spu_ops): Now a spu_multiarch_target. (spu_thread_architecture, spu_region_ok_for_hw_watchpoint) (spu_fetch_registers, spu_store_registers, spu_xfer_partial) (spu_search_memory, spu_mourn_inferior): Refactor as spu_multiarch_target methods. (init_spu_ops): Delete. (_initialize_spu_multiarch): Remove references to init_spu_ops, complete_target_initialization. * ravenscar-thread.c (ravenscar_thread_target): New class. (ravenscar_ops): Now a ravenscar_thread_target. (ravenscar_resume, ravenscar_wait, ravenscar_update_thread_list) (ravenscar_thread_alive, ravenscar_pid_to_str) (ravenscar_fetch_registers, ravenscar_store_registers) (ravenscar_prepare_to_store, ravenscar_stopped_by_sw_breakpoint) (ravenscar_stopped_by_hw_breakpoint) (ravenscar_stopped_by_watchpoint, ravenscar_stopped_data_address) (ravenscar_mourn_inferior, ravenscar_core_of_thread) (ravenscar_get_ada_task_ptid): Refactor as ravenscar_thread_target methods. (init_ravenscar_thread_ops): Delete. (_initialize_ravenscar): Remove references to init_ravenscar_thread_ops and complete_target_initialization. * bsd-uthread.c (bsd_uthread_ops_hack): Delete. (bsd_uthread_target): New class. (bsd_uthread_ops): Now a bsd_uthread_target. (bsd_uthread_activate): Adjust to refer to bsd_uthread_ops. (bsd_uthread_close, bsd_uthread_mourn_inferior) (bsd_uthread_fetch_registers, bsd_uthread_store_registers) (bsd_uthread_wait, bsd_uthread_resume, bsd_uthread_thread_alive) (bsd_uthread_update_thread_list, bsd_uthread_extra_thread_info) (bsd_uthread_pid_to_str): Refactor as bsd_uthread_target methods. (bsd_uthread_target): Delete function. (_initialize_bsd_uthread): Remove reference to complete_target_initialization. * bfd-target.c (target_bfd_data): Delete. Fields folded into ... (target_bfd): ... this new class. (target_bfd_xfer_partial, target_bfd_get_section_table) (target_bfd_close): Refactor as target_bfd methods. (target_bfd::~target_bfd): New. (target_bfd_reopen): Adjust. (target_bfd::close): New. * record-btrace.c (record_btrace_target): New class. (record_btrace_ops): Now a record_btrace_target. (record_btrace_open, record_btrace_stop_recording) (record_btrace_disconnect, record_btrace_close) (record_btrace_async, record_btrace_info) (record_btrace_insn_history, record_btrace_insn_history_range) (record_btrace_insn_history_from, record_btrace_call_history) (record_btrace_call_history_range) (record_btrace_call_history_from, record_btrace_record_method) (record_btrace_is_replaying, record_btrace_will_replay) (record_btrace_xfer_partial, record_btrace_insert_breakpoint) (record_btrace_remove_breakpoint, record_btrace_fetch_registers) (record_btrace_store_registers, record_btrace_prepare_to_store) (record_btrace_to_get_unwinder) (record_btrace_to_get_tailcall_unwinder, record_btrace_resume) (record_btrace_commit_resume, record_btrace_wait) (record_btrace_stop, record_btrace_can_execute_reverse) (record_btrace_stopped_by_sw_breakpoint) (record_btrace_supports_stopped_by_sw_breakpoint) (record_btrace_stopped_by_hw_breakpoint) (record_btrace_supports_stopped_by_hw_breakpoint) (record_btrace_update_thread_list, record_btrace_thread_alive) (record_btrace_goto_begin, record_btrace_goto_end) (record_btrace_goto, record_btrace_stop_replaying_all) (record_btrace_execution_direction) (record_btrace_prepare_to_generate_core) (record_btrace_done_generating_core): Refactor as record_btrace_target methods. (init_record_btrace_ops): Delete. (_initialize_record_btrace): Remove reference to init_record_btrace_ops. * record-full.c (RECORD_FULL_IS_REPLAY): Adjust to always refer to the execution_direction global. (record_full_base_target, record_full_target) (record_full_core_target): New classes. (record_full_ops): Now a record_full_target. (record_full_core_ops): Now a record_full_core_target. (record_full_target::detach, record_full_target::disconnect) (record_full_core_target::disconnect) (record_full_target::mourn_inferior, record_full_target::kill): New. (record_full_open, record_full_close, record_full_async): Refactor as methods of the record_full_base_target class. (record_full_resume, record_full_commit_resume): Refactor as methods of the record_full_target class. (record_full_wait, record_full_stopped_by_watchpoint) (record_full_stopped_data_address) (record_full_stopped_by_sw_breakpoint) (record_full_supports_stopped_by_sw_breakpoint) (record_full_stopped_by_hw_breakpoint) (record_full_supports_stopped_by_hw_breakpoint): Refactor as methods of the record_full_base_target class. (record_full_store_registers, record_full_xfer_partial) (record_full_insert_breakpoint, record_full_remove_breakpoint): Refactor as methods of the record_full_target class. (record_full_can_execute_reverse, record_full_get_bookmark) (record_full_goto_bookmark, record_full_execution_direction) (record_full_record_method, record_full_info, record_full_delete) (record_full_is_replaying, record_full_will_replay) (record_full_goto_begin, record_full_goto_end, record_full_goto) (record_full_stop_replaying): Refactor as methods of the record_full_base_target class. (record_full_core_resume, record_full_core_kill) (record_full_core_fetch_registers) (record_full_core_prepare_to_store) (record_full_core_store_registers, record_full_core_xfer_partial) (record_full_core_insert_breakpoint) (record_full_core_remove_breakpoint) (record_full_core_has_execution): Refactor as methods of the record_full_core_target class. (record_full_base_target::supports_delete_record): New. (init_record_full_ops): Delete. (init_record_full_core_ops): Delete. (record_full_save): Refactor as method of the record_full_base_target class. (_initialize_record_full): Remove references to init_record_full_ops and init_record_full_core_ops. * remote.c (remote_target, extended_remote_target): New classes. (remote_ops): Now a remote_target. (extended_remote_ops): Now an extended_remote_target. (remote_insert_fork_catchpoint, remote_remove_fork_catchpoint) (remote_insert_vfork_catchpoint, remote_remove_vfork_catchpoint) (remote_insert_exec_catchpoint, remote_remove_exec_catchpoint) (remote_pass_signals, remote_set_syscall_catchpoint) (remote_program_signals, ) (remote_thread_always_alive): Remove target_ops parameter. (remote_thread_alive, remote_thread_name) (remote_update_thread_list, remote_threads_extra_info) (remote_static_tracepoint_marker_at) (remote_static_tracepoint_markers_by_strid) (remote_get_ada_task_ptid, remote_close, remote_start_remote) (remote_open): Refactor as methods of remote_target. (extended_remote_open, extended_remote_detach) (extended_remote_attach, extended_remote_post_attach): (extended_remote_supports_disable_randomization) (extended_remote_create_inferior): : Refactor as method of extended_remote_target. (remote_set_permissions, remote_open_1, remote_detach) (remote_follow_fork, remote_follow_exec, remote_disconnect) (remote_resume, remote_commit_resume, remote_stop) (remote_interrupt, remote_pass_ctrlc, remote_terminal_inferior) (remote_terminal_ours, remote_wait, remote_fetch_registers) (remote_prepare_to_store, remote_store_registers) (remote_flash_erase, remote_flash_done, remote_files_info) (remote_kill, remote_mourn, remote_insert_breakpoint) (remote_remove_breakpoint, remote_insert_watchpoint) (remote_watchpoint_addr_within_range) (remote_remove_watchpoint, remote_region_ok_for_hw_watchpoint) (remote_check_watch_resources, remote_stopped_by_sw_breakpoint) (remote_supports_stopped_by_sw_breakpoint) (remote_stopped_by_hw_breakpoint) (remote_supports_stopped_by_hw_breakpoint) (remote_stopped_by_watchpoint, remote_stopped_data_address) (remote_insert_hw_breakpoint, remote_remove_hw_breakpoint) (remote_verify_memory): Refactor as methods of remote_target. (remote_write_qxfer, remote_read_qxfer): Remove target_ops parameter. (remote_xfer_partial, remote_get_memory_xfer_limit) (remote_search_memory, remote_rcmd, remote_memory_map) (remote_pid_to_str, remote_get_thread_local_address) (remote_get_tib_address, remote_read_description): Refactor as methods of remote_target. (remote_target::fileio_open, remote_target::fileio_pwrite) (remote_target::fileio_pread, remote_target::fileio_close): New. (remote_hostio_readlink, remote_hostio_fstat) (remote_filesystem_is_local, remote_can_execute_reverse) (remote_supports_non_stop, remote_supports_disable_randomization) (remote_supports_multi_process, remote_supports_cond_breakpoints) (remote_supports_enable_disable_tracepoint) (remote_supports_string_tracing) (remote_can_run_breakpoint_commands, remote_trace_init) (remote_download_tracepoint, remote_can_download_tracepoint) (remote_download_trace_state_variable, remote_enable_tracepoint) (remote_disable_tracepoint, remote_trace_set_readonly_regions) (remote_trace_start, remote_get_trace_status) (remote_get_tracepoint_status, remote_trace_stop) (remote_trace_find, remote_get_trace_state_variable_value) (remote_save_trace_data, remote_get_raw_trace_data) (remote_set_disconnected_tracing, remote_core_of_thread) (remote_set_circular_trace_buffer, remote_traceframe_info) (remote_get_min_fast_tracepoint_insn_len) (remote_set_trace_buffer_size, remote_set_trace_notes) (remote_use_agent, remote_can_use_agent, remote_enable_btrace) (remote_disable_btrace, remote_teardown_btrace) (remote_read_btrace, remote_btrace_conf) (remote_augmented_libraries_svr4_read, remote_load) (remote_pid_to_exec_file, remote_can_do_single_step) (remote_execution_direction, remote_thread_handle_to_thread_info): Refactor as methods of remote_target. (init_remote_ops, init_extended_remote_ops): Delete. (remote_can_async_p, remote_is_async_p, remote_async) (remote_thread_events, remote_upload_tracepoints) (remote_upload_trace_state_variables): Refactor as methods of remote_target. (_initialize_remote): Remove references to init_remote_ops and init_extended_remote_ops. * remote-sim.c (gdbsim_target): New class. (gdbsim_fetch_register, gdbsim_store_register, gdbsim_kill) (gdbsim_load, gdbsim_create_inferior, gdbsim_open, gdbsim_close) (gdbsim_detach, gdbsim_resume, gdbsim_interrupt) (gdbsim_wait, gdbsim_prepare_to_store, gdbsim_xfer_partial) (gdbsim_files_info, gdbsim_mourn_inferior, gdbsim_thread_alive) (gdbsim_pid_to_str, gdbsim_has_all_memory, gdbsim_has_memory): Refactor as methods of gdbsim_target. (gdbsim_ops): Now a gdbsim_target. (init_gdbsim_ops): Delete. (gdbsim_cntrl_c): Adjust. (_initialize_remote_sim): Remove reference to init_gdbsim_ops. * amd64-linux-nat.c (amd64_linux_nat_target): New class. (the_amd64_linux_nat_target): New. (amd64_linux_fetch_inferior_registers) (amd64_linux_store_inferior_registers): Refactor as methods of amd64_linux_nat_target. (_initialize_amd64_linux_nat): Adjust. Set linux_target. * i386-linux-nat.c: Don't include "linux-nat.h". (i386_linux_nat_target): New class. (the_i386_linux_nat_target): New. (i386_linux_fetch_inferior_registers) (i386_linux_store_inferior_registers, i386_linux_resume): Refactor as methods of i386_linux_nat_target. (_initialize_i386_linux_nat): Adjust. Set linux_target. * inf-child.c (inf_child_ops): Delete. (inf_child_fetch_inferior_registers) (inf_child_store_inferior_registers): Delete. (inf_child_post_attach, inf_child_prepare_to_store): Refactor as methods of inf_child_target. (inf_child_target::supports_terminal_ours) (inf_child_target::terminal_init) (inf_child_target::terminal_inferior) (inf_child_target::terminal_ours_for_output) (inf_child_target::terminal_ours, inf_child_target::interrupt) (inf_child_target::pass_ctrlc, inf_child_target::terminal_info): New. (inf_child_open, inf_child_disconnect, inf_child_close) (inf_child_mourn_inferior, inf_child_maybe_unpush_target) (inf_child_post_startup_inferior, inf_child_can_run) (inf_child_pid_to_exec_file): Refactor as methods of inf_child_target. (inf_child_follow_fork): Delete. (inf_child_target::can_create_inferior) (inf_child_target::can_attach): New. (inf_child_target::has_all_memory, inf_child_target::has_memory) (inf_child_target::has_stack, inf_child_target::has_registers) (inf_child_target::has_execution): New. (inf_child_fileio_open, inf_child_fileio_pwrite) (inf_child_fileio_pread, inf_child_fileio_fstat) (inf_child_fileio_close, inf_child_fileio_unlink) (inf_child_fileio_readlink, inf_child_use_agent) (inf_child_can_use_agent): Refactor as methods of inf_child_target. (return_zero, inf_child_target): Delete. (inf_child_target::inf_child_target): New. * inf-child.h: Include "target.h". (inf_child_target): Delete function prototype. (inf_child_target): New class. (inf_child_open_target, inf_child_mourn_inferior) (inf_child_maybe_unpush_target): Delete. * inf-ptrace.c (inf_ptrace_target::~inf_ptrace_target): New. (inf_ptrace_follow_fork, inf_ptrace_insert_fork_catchpoint) (inf_ptrace_remove_fork_catchpoint, inf_ptrace_create_inferior) (inf_ptrace_post_startup_inferior, inf_ptrace_mourn_inferior) (inf_ptrace_attach, inf_ptrace_post_attach, inf_ptrace_detach) (inf_ptrace_detach_success, inf_ptrace_kill, inf_ptrace_resume) (inf_ptrace_wait, inf_ptrace_xfer_partial) (inf_ptrace_thread_alive, inf_ptrace_files_info) (inf_ptrace_pid_to_str, inf_ptrace_auxv_parse): Refactor as methods of inf_ptrace_target. (inf_ptrace_target): Delete function. * inf-ptrace.h: Include "inf-child.h". (inf_ptrace_target): Delete function declaration. (inf_ptrace_target): New class. (inf_ptrace_trad_target, inf_ptrace_detach_success): Delete. * linux-nat.c (linux_target): New. (linux_ops, linux_ops_saved, super_xfer_partial): Delete. (linux_nat_target::~linux_nat_target): New. (linux_child_post_attach, linux_child_post_startup_inferior) (linux_child_follow_fork, linux_child_insert_fork_catchpoint) (linux_child_remove_fork_catchpoint) (linux_child_insert_vfork_catchpoint) (linux_child_remove_vfork_catchpoint) (linux_child_insert_exec_catchpoint) (linux_child_remove_exec_catchpoint) (linux_child_set_syscall_catchpoint, linux_nat_pass_signals) (linux_nat_create_inferior, linux_nat_attach, linux_nat_detach) (linux_nat_resume, linux_nat_stopped_by_watchpoint) (linux_nat_stopped_data_address) (linux_nat_stopped_by_sw_breakpoint) (linux_nat_supports_stopped_by_sw_breakpoint) (linux_nat_stopped_by_hw_breakpoint) (linux_nat_supports_stopped_by_hw_breakpoint, linux_nat_wait) (linux_nat_kill, linux_nat_mourn_inferior) (linux_nat_xfer_partial, linux_nat_thread_alive) (linux_nat_update_thread_list, linux_nat_pid_to_str) (linux_nat_thread_name, linux_child_pid_to_exec_file) (linux_child_static_tracepoint_markers_by_strid) (linux_nat_is_async_p, linux_nat_can_async_p) (linux_nat_supports_non_stop, linux_nat_always_non_stop_p) (linux_nat_supports_multi_process) (linux_nat_supports_disable_randomization, linux_nat_async) (linux_nat_stop, linux_nat_close, linux_nat_thread_address_space) (linux_nat_core_of_thread, linux_nat_filesystem_is_local) (linux_nat_fileio_open, linux_nat_fileio_readlink) (linux_nat_fileio_unlink, linux_nat_thread_events): Refactor as methods of linux_nat_target. (linux_nat_wait_1, linux_xfer_siginfo, linux_proc_xfer_partial) (linux_proc_xfer_spu, linux_nat_xfer_osdata): Remove target_ops parameter. (check_stopped_by_watchpoint): Adjust. (linux_xfer_partial): Delete. (linux_target_install_ops, linux_target, linux_nat_add_target): Delete. (linux_nat_target::linux_nat_target): New. * linux-nat.h: Include "inf-ptrace.h". (linux_nat_target): New. (linux_target, linux_target_install_ops, linux_nat_add_target): Delete function declarations. (linux_target): Declare global. * linux-thread-db.c (thread_db_target): New. (thread_db_target::thread_db_target): New. (thread_db_ops): Delete. (the_thread_db_target): New. (thread_db_detach, thread_db_wait, thread_db_mourn_inferior) (thread_db_update_thread_list, thread_db_pid_to_str) (thread_db_extra_thread_info) (thread_db_thread_handle_to_thread_info) (thread_db_get_thread_local_address, thread_db_get_ada_task_ptid) (thread_db_resume): Refactor as methods of thread_db_target. (init_thread_db_ops): Delete. (_initialize_thread_db): Remove reference to init_thread_db_ops. * x86-linux-nat.c: Don't include "linux-nat.h". (super_post_startup_inferior): Delete. (x86_linux_nat_target::~x86_linux_nat_target): New. (x86_linux_child_post_startup_inferior) (x86_linux_read_description, x86_linux_enable_btrace) (x86_linux_disable_btrace, x86_linux_teardown_btrace) (x86_linux_read_btrace, x86_linux_btrace_conf): Refactor as methods of x86_linux_nat_target. (x86_linux_create_target): Delete. Bits folded ... (x86_linux_add_target): ... here. Now takes a linux_nat_target pointer. * x86-linux-nat.h: Include "linux-nat.h" and "x86-nat.h". (x86_linux_nat_target): New class. (x86_linux_create_target): Delete. (x86_linux_add_target): Now takes a linux_nat_target pointer. * x86-nat.c (x86_insert_watchpoint, x86_remove_watchpoint) (x86_region_ok_for_watchpoint, x86_stopped_data_address) (x86_stopped_by_watchpoint, x86_insert_hw_breakpoint) (x86_remove_hw_breakpoint, x86_can_use_hw_breakpoint) (x86_stopped_by_hw_breakpoint): Remove target_ops parameter and make extern. (x86_use_watchpoints): Delete. * x86-nat.h: Include "breakpoint.h" and "target.h". (x86_use_watchpoints): Delete. (x86_can_use_hw_breakpoint, x86_region_ok_for_hw_watchpoint) (x86_stopped_by_watchpoint, x86_stopped_data_address) (x86_insert_watchpoint, x86_remove_watchpoint) (x86_insert_hw_breakpoint, x86_remove_hw_breakpoint) (x86_stopped_by_hw_breakpoint): New declarations. (x86_nat_target): New template class. * ppc-linux-nat.c (ppc_linux_nat_target): New class. (the_ppc_linux_nat_target): New. (ppc_linux_fetch_inferior_registers) (ppc_linux_can_use_hw_breakpoint) (ppc_linux_region_ok_for_hw_watchpoint) (ppc_linux_ranged_break_num_registers) (ppc_linux_insert_hw_breakpoint, ppc_linux_remove_hw_breakpoint) (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_can_accel_watchpoint_condition) (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint) (ppc_linux_stopped_data_address, ppc_linux_stopped_by_watchpoint) (ppc_linux_watchpoint_addr_within_range) (ppc_linux_masked_watch_num_registers) (ppc_linux_store_inferior_registers, ppc_linux_auxv_parse) (ppc_linux_read_description): Refactor as methods of ppc_linux_nat_target. (_initialize_ppc_linux_nat): Adjust. Set linux_target. * procfs.c (procfs_xfer_partial): Delete forward declaration. (procfs_target): New class. (the_procfs_target): New. (procfs_target): Delete function. (procfs_auxv_parse, procfs_attach, procfs_detach) (procfs_fetch_registers, procfs_store_registers, procfs_wait) (procfs_xfer_partial, procfs_resume, procfs_pass_signals) (procfs_files_info, procfs_kill_inferior, procfs_mourn_inferior) (procfs_create_inferior, procfs_update_thread_list) (procfs_thread_alive, procfs_pid_to_str) (procfs_can_use_hw_breakpoint, procfs_stopped_by_watchpoint) (procfs_stopped_data_address, procfs_insert_watchpoint) (procfs_remove_watchpoint, procfs_region_ok_for_hw_watchpoint) (proc_find_memory_regions, procfs_info_proc) (procfs_make_note_section): Refactor as methods of procfs_target. (_initialize_procfs): Adjust. * sol-thread.c (sol_thread_target): New class. (sol_thread_ops): Now a sol_thread_target. (sol_thread_detach, sol_thread_resume, sol_thread_wait) (sol_thread_fetch_registers, sol_thread_store_registers) (sol_thread_xfer_partial, sol_thread_mourn_inferior) (sol_thread_alive, solaris_pid_to_str, sol_update_thread_list) (sol_get_ada_task_ptid): Refactor as methods of sol_thread_target. (init_sol_thread_ops): Delete. (_initialize_sol_thread): Adjust. Remove references to init_sol_thread_ops and complete_target_initialization. * windows-nat.c (windows_nat_target): New class. (windows_fetch_inferior_registers) (windows_store_inferior_registers, windows_resume, windows_wait) (windows_attach, windows_detach, windows_pid_to_exec_file) (windows_files_info, windows_create_inferior) (windows_mourn_inferior, windows_interrupt, windows_kill_inferior) (windows_close, windows_pid_to_str, windows_xfer_partial) (windows_get_tib_address, windows_get_ada_task_ptid) (windows_thread_name, windows_thread_alive): Refactor as windows_nat_target methods. (do_initial_windows_stuff): Adjust. (windows_target): Delete function. (_initialize_windows_nat): Adjust. * darwin-nat.c (darwin_resume, darwin_wait_to, darwin_interrupt) (darwin_mourn_inferior, darwin_kill_inferior) (darwin_create_inferior, darwin_attach, darwin_detach) (darwin_pid_to_str, darwin_thread_alive, darwin_xfer_partial) (darwin_pid_to_exec_file, darwin_get_ada_task_ptid) (darwin_supports_multi_process): Refactor as darwin_nat_target methods. (darwin_resume_to, darwin_files_info): Delete. (_initialize_darwin_inferior): Rename to ... (_initialize_darwin_nat): ... this. Adjust to C++ification. * darwin-nat.h: Include "inf-child.h". (darwin_nat_target): New class. (darwin_complete_target): Delete. * i386-darwin-nat.c (i386_darwin_nat_target): New class. (darwin_target): New. (i386_darwin_fetch_inferior_registers) (i386_darwin_store_inferior_registers): Refactor as methods of darwin_nat_target. (darwin_complete_target): Delete, with ... (_initialize_i386_darwin_nat): ... bits factored out here. * alpha-linux-nat.c (alpha_linux_nat_target): New class. (the_alpha_linux_nat_target): New. (alpha_linux_register_u_offset): Refactor as alpha_linux_nat_target method. (_initialize_alpha_linux_nat): Adjust. * linux-nat-trad.c (inf_ptrace_register_u_offset): Delete. (inf_ptrace_fetch_register, inf_ptrace_fetch_registers) (inf_ptrace_store_register, inf_ptrace_store_registers): Refact as methods of linux_nat_trad_target. (linux_trad_target): Delete. * linux-nat-trad.h (linux_trad_target): Delete function. (linux_nat_trad_target): New class. * mips-linux-nat.c (mips_linux_nat_target): New class. (super_fetch_registers, super_store_registers, super_close): Delete. (the_mips_linux_nat_target): New. (mips64_linux_regsets_fetch_registers) (mips64_linux_regsets_store_registers) (mips64_linux_fetch_registers, mips64_linux_store_registers) (mips_linux_register_u_offset, mips_linux_read_description) (mips_linux_can_use_hw_breakpoint) (mips_linux_stopped_by_watchpoint) (mips_linux_stopped_data_address) (mips_linux_region_ok_for_hw_watchpoint) (mips_linux_insert_watchpoint, mips_linux_remove_watchpoint) (mips_linux_close): Refactor as methods of mips_linux_nat. (_initialize_mips_linux_nat): Adjust to C++ification. * aix-thread.c (aix_thread_target): New class. (aix_thread_ops): Now an aix_thread_target. (aix_thread_detach, aix_thread_resume, aix_thread_wait) (aix_thread_fetch_registers, aix_thread_store_registers) (aix_thread_xfer_partial, aix_thread_mourn_inferior) (aix_thread_thread_alive, aix_thread_pid_to_str) (aix_thread_extra_thread_info, aix_thread_get_ada_task_ptid): Refactor as methods of aix_thread_target. (init_aix_thread_ops): Delete. (_initialize_aix_thread): Remove references to init_aix_thread_ops and complete_target_initialization. * rs6000-nat.c (rs6000_xfer_shared_libraries): Delete. (rs6000_nat_target): New class. (the_rs6000_nat_target): New. (rs6000_fetch_inferior_registers, rs6000_store_inferior_registers) (rs6000_xfer_partial, rs6000_wait, rs6000_create_inferior) (rs6000_xfer_shared_libraries): Refactor as rs6000_nat_target methods. (super_create_inferior): Delete. (_initialize_rs6000_nat): Adjust to C++ification. * arm-linux-nat.c (arm_linux_nat_target): New class. (the_arm_linux_nat_target): New. (arm_linux_fetch_inferior_registers) (arm_linux_store_inferior_registers, arm_linux_read_description) (arm_linux_can_use_hw_breakpoint, arm_linux_insert_hw_breakpoint) (arm_linux_remove_hw_breakpoint) (arm_linux_region_ok_for_hw_watchpoint) (arm_linux_insert_watchpoint, arm_linux_remove_watchpoint) (arm_linux_stopped_data_address, arm_linux_stopped_by_watchpoint) (arm_linux_watchpoint_addr_within_range): Refactor as methods of arm_linux_nat_target. (_initialize_arm_linux_nat): Adjust to C++ification. * aarch64-linux-nat.c (aarch64_linux_nat_target): New class. (the_aarch64_linux_nat_target): New. (aarch64_linux_fetch_inferior_registers) (aarch64_linux_store_inferior_registers) (aarch64_linux_child_post_startup_inferior) (aarch64_linux_read_description) (aarch64_linux_can_use_hw_breakpoint) (aarch64_linux_insert_hw_breakpoint) (aarch64_linux_remove_hw_breakpoint) (aarch64_linux_insert_watchpoint, aarch64_linux_remove_watchpoint) (aarch64_linux_region_ok_for_hw_watchpoint) (aarch64_linux_stopped_data_address) (aarch64_linux_stopped_by_watchpoint) (aarch64_linux_watchpoint_addr_within_range) (aarch64_linux_can_do_single_step): Refactor as methods of aarch64_linux_nat_target. (super_post_startup_inferior): Delete. (_initialize_aarch64_linux_nat): Adjust to C++ification. * hppa-linux-nat.c (hppa_linux_nat_target): New class. (the_hppa_linux_nat_target): New. (hppa_linux_fetch_inferior_registers) (hppa_linux_store_inferior_registers): Refactor as methods of hppa_linux_nat_target. (_initialize_hppa_linux_nat): Adjust to C++ification. * ia64-linux-nat.c (ia64_linux_nat_target): New class. (the_ia64_linux_nat_target): New. (ia64_linux_insert_watchpoint, ia64_linux_remove_watchpoint) (ia64_linux_stopped_data_address) (ia64_linux_stopped_by_watchpoint, ia64_linux_fetch_registers) (ia64_linux_store_registers, ia64_linux_xfer_partial): Refactor as ia64_linux_nat_target methods. (super_xfer_partial): Delete. (_initialize_ia64_linux_nat): Adjust to C++ification. * m32r-linux-nat.c (m32r_linux_nat_target): New class. (the_m32r_linux_nat_target): New. (m32r_linux_fetch_inferior_registers) (m32r_linux_store_inferior_registers): Refactor as m32r_linux_nat_target methods. (_initialize_m32r_linux_nat): Adjust to C++ification. * m68k-linux-nat.c (m68k_linux_nat_target): New class. (the_m68k_linux_nat_target): New. (m68k_linux_fetch_inferior_registers) (m68k_linux_store_inferior_registers): Refactor as m68k_linux_nat_target methods. (_initialize_m68k_linux_nat): Adjust to C++ification. * s390-linux-nat.c (s390_linux_nat_target): New class. (the_s390_linux_nat_target): New. (s390_linux_fetch_inferior_registers) (s390_linux_store_inferior_registers, s390_stopped_by_watchpoint) (s390_insert_watchpoint, s390_remove_watchpoint) (s390_can_use_hw_breakpoint, s390_insert_hw_breakpoint) (s390_remove_hw_breakpoint, s390_region_ok_for_hw_watchpoint) (s390_auxv_parse, s390_read_description): Refactor as methods of s390_linux_nat_target. (_initialize_s390_nat): Adjust to C++ification. * sparc-linux-nat.c (sparc_linux_nat_target): New class. (the_sparc_linux_nat_target): New. (_initialize_sparc_linux_nat): Adjust to C++ification. * sparc-nat.c (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc64-linux-nat.c (sparc64_linux_nat_target): New class. (the_sparc64_linux_nat_target): New. (_initialize_sparc64_linux_nat): Adjust to C++ification. * spu-linux-nat.c (spu_linux_nat_target): New class. (the_spu_linux_nat_target): New. (spu_child_post_startup_inferior, spu_child_post_attach) (spu_child_wait, spu_fetch_inferior_registers) (spu_store_inferior_registers, spu_xfer_partial) (spu_can_use_hw_breakpoint): Refactor as spu_linux_nat_target methods. (_initialize_spu_nat): Adjust to C++ification. * tilegx-linux-nat.c (tilegx_linux_nat_target): New class. (the_tilegx_linux_nat_target): New. (fetch_inferior_registers, store_inferior_registers): Refactor as methods. (_initialize_tile_linux_nat): Adjust to C++ification. * xtensa-linux-nat.c (xtensa_linux_nat_target): New class. (the_xtensa_linux_nat_target): New. (xtensa_linux_fetch_inferior_registers) (xtensa_linux_store_inferior_registers): Refactor as xtensa_linux_nat_target methods. (_initialize_xtensa_linux_nat): Adjust to C++ification. * fbsd-nat.c (USE_SIGTRAP_SIGINFO): Delete. (fbsd_pid_to_exec_file, fbsd_find_memory_regions) (fbsd_find_memory_regions, fbsd_info_proc, fbsd_xfer_partial) (fbsd_thread_alive, fbsd_pid_to_str, fbsd_thread_name) (fbsd_update_thread_list, fbsd_resume, fbsd_wait) (fbsd_stopped_by_sw_breakpoint) (fbsd_supports_stopped_by_sw_breakpoint, fbsd_follow_fork) (fbsd_insert_fork_catchpoint, fbsd_remove_fork_catchpoint) (fbsd_insert_vfork_catchpoint, fbsd_remove_vfork_catchpoint) (fbsd_post_startup_inferior, fbsd_post_attach) (fbsd_insert_exec_catchpoint, fbsd_remove_exec_catchpoint) (fbsd_set_syscall_catchpoint) (super_xfer_partial, super_resume, super_wait) (fbsd_supports_stopped_by_hw_breakpoint): Delete. (fbsd_handle_debug_trap): Remove target_ops parameter. (fbsd_nat_add_target): Delete. * fbsd-nat.h: Include "inf-ptrace.h". (fbsd_nat_add_target): Delete. (USE_SIGTRAP_SIGINFO): Define. (fbsd_nat_target): New class. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers) (amd64bsd_store_inferior_registers): Remove target_ops parameter. (amd64bsd_target): Delete. * amd64-bsd-nat.h: New file. * amd64-fbsd-nat.c: Include "amd64-bsd-nat.h" instead of "x86-bsd-nat.h". (amd64_fbsd_nat_target): New class. (the_amd64_fbsd_nat_target): New. (amd64fbsd_read_description): Refactor as method of amd64_fbsd_nat_target. (amd64_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_amd64fbsd_nat): Adjust to C++ification. * amd64-nat.h (amd64bsd_target): Delete function declaration. * i386-bsd-nat.c (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Remove target_ops parameter. (i386bsd_target): Delete. * i386-bsd-nat.h (i386bsd_target): Delete function declaration. (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Declare. (i386_bsd_nat_target): New class. * i386-fbsd-nat.c (i386_fbsd_nat_target): New class. (the_i386_fbsd_nat_target): New. (i386fbsd_resume, i386fbsd_read_description): Refactor as i386_fbsd_nat_target methods. (i386_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_i386fbsd_nat): Adjust to C++ification. * x86-bsd-nat.c (super_mourn_inferior): Delete. (x86bsd_mourn_inferior, x86bsd_target): Delete. (_initialize_x86_bsd_nat): Adjust to C++ification. * x86-bsd-nat.h: Include "x86-nat.h". (x86bsd_target): Delete declaration. (x86bsd_nat_target): New class. * aarch64-fbsd-nat.c (aarch64_fbsd_nat_target): New class. (the_aarch64_fbsd_nat_target): New. (aarch64_fbsd_fetch_inferior_registers) (aarch64_fbsd_store_inferior_registers): Refactor as methods of aarch64_fbsd_nat_target. (_initialize_aarch64_fbsd_nat): Adjust to C++ification. * alpha-bsd-nat.c (alpha_bsd_nat_target): New class. (the_alpha_bsd_nat_target): New. (alphabsd_fetch_inferior_registers) (alphabsd_store_inferior_registers): Refactor as alpha_bsd_nat_target methods. (_initialize_alphabsd_nat): Refactor as methods of alpha_bsd_nat_target. * amd64-nbsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_nbsd_nat_target): New. (_initialize_amd64nbsd_nat): Adjust to C++ification. * amd64-obsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_obsd_nat_target): New. (_initialize_amd64obsd_nat): Adjust to C++ification. * arm-fbsd-nat.c (arm_fbsd_nat_target): New. (the_arm_fbsd_nat_target): New. (arm_fbsd_fetch_inferior_registers) (arm_fbsd_store_inferior_registers, arm_fbsd_read_description): (_initialize_arm_fbsd_nat): Refactor as methods of arm_fbsd_nat_target. (_initialize_arm_fbsd_nat): Adjust to C++ification. * arm-nbsd-nat.c (arm_netbsd_nat_target): New class. (the_arm_netbsd_nat_target): New. (armnbsd_fetch_registers, armnbsd_store_registers): Refactor as arm_netbsd_nat_target. (_initialize_arm_netbsd_nat): Adjust to C++ification. * hppa-nbsd-nat.c (hppa_nbsd_nat_target): New class. (the_hppa_nbsd_nat_target): New. (hppanbsd_fetch_registers, hppanbsd_store_registers): Refactor as hppa_nbsd_nat_target methods. (_initialize_hppanbsd_nat): Adjust to C++ification. * hppa-obsd-nat.c (hppa_obsd_nat_target): New class. (the_hppa_obsd_nat_target): New. (hppaobsd_fetch_registers, hppaobsd_store_registers): Refactor as methods of hppa_obsd_nat_target. (_initialize_hppaobsd_nat): Adjust to C++ification. Use add_target. * i386-nbsd-nat.c (the_i386_nbsd_nat_target): New. (_initialize_i386nbsd_nat): Adjust to C++ification. Use add_target. * i386-obsd-nat.c (the_i386_obsd_nat_target): New. (_initialize_i386obsd_nat): Use add_target. * m68k-bsd-nat.c (m68k_bsd_nat_target): New class. (the_m68k_bsd_nat_target): New. (m68kbsd_fetch_inferior_registers) (m68kbsd_store_inferior_registers): Refactor as methods of m68k_bsd_nat_target. (_initialize_m68kbsd_nat): Adjust to C++ification. * mips-fbsd-nat.c (mips_fbsd_nat_target): New class. (the_mips_fbsd_nat_target): New. (mips_fbsd_fetch_inferior_registers) (mips_fbsd_store_inferior_registers): Refactor as methods of mips_fbsd_nat_target. (_initialize_mips_fbsd_nat): Adjust to C++ification. Use add_target. * mips-nbsd-nat.c (mips_nbsd_nat_target): New class. (the_mips_nbsd_nat_target): New. (mipsnbsd_fetch_inferior_registers) (mipsnbsd_store_inferior_registers): Refactor as methods of mips_nbsd_nat_target. (_initialize_mipsnbsd_nat): Adjust to C++ification. * mips64-obsd-nat.c (mips64_obsd_nat_target): New class. (the_mips64_obsd_nat_target): New. (mips64obsd_fetch_inferior_registers) (mips64obsd_store_inferior_registers): Refactor as methods of mips64_obsd_nat_target. (_initialize_mips64obsd_nat): Adjust to C++ification. Use add_target. * nbsd-nat.c (nbsd_pid_to_exec_file): Refactor as method of nbsd_nat_target. * nbsd-nat.h: Include "inf-ptrace.h". (nbsd_nat_target): New class. * obsd-nat.c (obsd_pid_to_str, obsd_update_thread_list) (obsd_wait): Refactor as methods of obsd_nat_target. (obsd_add_target): Delete. * obsd-nat.h: Include "inf-ptrace.h". (obsd_nat_target): New class. * ppc-fbsd-nat.c (ppc_fbsd_nat_target): New class. (the_ppc_fbsd_nat_target): New. (ppcfbsd_fetch_inferior_registers) (ppcfbsd_store_inferior_registers): Refactor as methods of ppc_fbsd_nat_target. (_initialize_ppcfbsd_nat): Adjust to C++ification. Use add_target. * ppc-nbsd-nat.c (ppc_nbsd_nat_target): New class. (the_ppc_nbsd_nat_target): New. (ppcnbsd_fetch_inferior_registers) (ppcnbsd_store_inferior_registers): Refactor as methods of ppc_nbsd_nat_target. (_initialize_ppcnbsd_nat): Adjust to C++ification. * ppc-obsd-nat.c (ppc_obsd_nat_target): New class. (the_ppc_obsd_nat_target): New. (ppcobsd_fetch_registers, ppcobsd_store_registers): Refactor as methods of ppc_obsd_nat_target. (_initialize_ppcobsd_nat): Adjust to C++ification. Use add_target. * sh-nbsd-nat.c (sh_nbsd_nat_target): New class. (the_sh_nbsd_nat_target): New. (shnbsd_fetch_inferior_registers) (shnbsd_store_inferior_registers): Refactor as methods of sh_nbsd_nat_target. (_initialize_shnbsd_nat): Adjust to C++ification. * sparc-nat.c (sparc_xfer_wcookie): Make extern. (inf_ptrace_xfer_partial): Delete. (sparc_xfer_partial, sparc_target): Delete. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers, sparc_xfer_wcookie): Declare. (sparc_target): Delete function declaration. (sparc_target): New template class. * sparc-nbsd-nat.c (the_sparc_nbsd_nat_target): New. (_initialize_sparcnbsd_nat): Adjust to C++ification. * sparc64-fbsd-nat.c (the_sparc64_fbsd_nat_target): New. (_initialize_sparc64fbsd_nat): Adjust to C++ification. Use add_target. * sparc64-nbsd-nat.c (the_sparc64_nbsd_nat_target): New. (_initialize_sparc64nbsd_nat): Adjust to C++ification. * sparc64-obsd-nat.c (the_sparc64_obsd_nat_target): New. (_initialize_sparc64obsd_nat): Adjust to C++ification. Use add_target. * vax-bsd-nat.c (vax_bsd_nat_target): New class. (the_vax_bsd_nat_target): New. (vaxbsd_fetch_inferior_registers) (vaxbsd_store_inferior_registers): Refactor as vax_bsd_nat_target methods. (_initialize_vaxbsd_nat): Adjust to C++ification. * bsd-kvm.c (bsd_kvm_target): New class. (bsd_kvm_ops): Now a bsd_kvm_target. (bsd_kvm_open, bsd_kvm_close, bsd_kvm_xfer_partial) (bsd_kvm_files_info, bsd_kvm_fetch_registers) (bsd_kvm_thread_alive, bsd_kvm_pid_to_str): Refactor as methods of bsd_kvm_target. (bsd_kvm_return_one): Delete. (bsd_kvm_add_target): Adjust to C++ification. * nto-procfs.c (nto_procfs_target, nto_procfs_target_native) (nto_procfs_target_procfs): New classes. (procfs_open_1, procfs_thread_alive, procfs_update_thread_list) (procfs_files_info, procfs_pid_to_exec_file, procfs_attach) (procfs_post_attach, procfs_wait, procfs_fetch_registers) (procfs_xfer_partial, procfs_detach, procfs_insert_breakpoint) (procfs_remove_breakpoint, procfs_insert_hw_breakpoint) (procfs_remove_hw_breakpoint, procfs_resume) (procfs_mourn_inferior, procfs_create_inferior, procfs_interrupt) (procfs_kill_inferior, procfs_store_registers) (procfs_pass_signals, procfs_pid_to_str, procfs_can_run): Refactor as methods of nto_procfs_target. (nto_procfs_ops): Now an nto_procfs_target_procfs. (nto_native_ops): Delete. (procfs_open, procfs_native_open): Delete. (nto_native_ops): Now an nto_procfs_target_native. (init_procfs_targets): Adjust to C++ification. (procfs_can_use_hw_breakpoint, procfs_remove_hw_watchpoint) (procfs_insert_hw_watchpoint, procfs_stopped_by_watchpoint): Refactor as methods of nto_procfs_target. * go32-nat.c (go32_nat_target): New class. (the_go32_nat_target): New. (go32_attach, go32_resume, go32_wait, go32_fetch_registers) (go32_store_registers, go32_xfer_partial, go32_files_info) (go32_kill_inferior, go32_create_inferior, go32_mourn_inferior) (go32_terminal_init, go32_terminal_info, go32_terminal_inferior) (go32_terminal_ours, go32_pass_ctrlc, go32_thread_alive) (go32_pid_to_str): Refactor as methods of go32_nat_target. (go32_target): Delete. (_initialize_go32_nat): Adjust to C++ification. * gnu-nat.c (gnu_wait, gnu_resume, gnu_kill_inferior) (gnu_mourn_inferior, gnu_create_inferior, gnu_attach, gnu_detach) (gnu_stop, gnu_thread_alive, gnu_xfer_partial) (gnu_find_memory_regions, gnu_pid_to_str): Refactor as methods of gnu_nat_target. (gnu_target): Delete. * gnu-nat.h (gnu_target): Delete. (gnu_nat_target): New class. * i386-gnu-nat.c (gnu_base_target): New. (i386_gnu_nat_target): New class. (the_i386_gnu_nat_target): New. (_initialize_i386gnu_nat): Adjust to C++ification. gdb/testsuite/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * gdb.base/breakpoint-in-ro-region.exp: Adjust to to_resume and to_log_command renames. * gdb.base/sss-bp-on-user-bp-2.exp: Likewise.
2018-05-03 07:37:22 +08:00
};
static ppc_linux_nat_target the_ppc_linux_nat_target;
/* *INDENT-OFF* */
/* registers layout, as presented by the ptrace interface:
PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5, PT_R6, PT_R7,
PT_R8, PT_R9, PT_R10, PT_R11, PT_R12, PT_R13, PT_R14, PT_R15,
PT_R16, PT_R17, PT_R18, PT_R19, PT_R20, PT_R21, PT_R22, PT_R23,
PT_R24, PT_R25, PT_R26, PT_R27, PT_R28, PT_R29, PT_R30, PT_R31,
PT_FPR0, PT_FPR0 + 2, PT_FPR0 + 4, PT_FPR0 + 6,
PT_FPR0 + 8, PT_FPR0 + 10, PT_FPR0 + 12, PT_FPR0 + 14,
PT_FPR0 + 16, PT_FPR0 + 18, PT_FPR0 + 20, PT_FPR0 + 22,
PT_FPR0 + 24, PT_FPR0 + 26, PT_FPR0 + 28, PT_FPR0 + 30,
PT_FPR0 + 32, PT_FPR0 + 34, PT_FPR0 + 36, PT_FPR0 + 38,
PT_FPR0 + 40, PT_FPR0 + 42, PT_FPR0 + 44, PT_FPR0 + 46,
PT_FPR0 + 48, PT_FPR0 + 50, PT_FPR0 + 52, PT_FPR0 + 54,
PT_FPR0 + 56, PT_FPR0 + 58, PT_FPR0 + 60, PT_FPR0 + 62,
PT_NIP, PT_MSR, PT_CCR, PT_LNK, PT_CTR, PT_XER, PT_MQ */
/* *INDENT_ON * */
static int
ppc_register_u_addr (struct gdbarch *gdbarch, int regno)
{
int u_addr = -1;
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
/* NOTE: cagney/2003-11-25: This is the word size used by the ptrace
interface, and not the wordsize of the program's ABI. */
int wordsize = sizeof (long);
/* General purpose registers occupy 1 slot each in the buffer. */
if (regno >= tdep->ppc_gp0_regnum
&& regno < tdep->ppc_gp0_regnum + ppc_num_gprs)
u_addr = ((regno - tdep->ppc_gp0_regnum + PT_R0) * wordsize);
/* Floating point regs: eight bytes each in both 32- and 64-bit
ptrace interfaces. Thus, two slots each in 32-bit interface, one
slot each in 64-bit interface. */
* ppc-tdep.h (struct gdbarch_tdep): Change definition of ppc_fp0_regnum and ppc_fpscr_regnum: if they are -1, then this processor variant lacks those registers. (ppc_floating_point_unit_p): Change description to make it clear that this returns info about the ISA, not the ABI. * rs6000-tdep.c (ppc_floating_point_unit_p): Decide whether to return true or false by checking tdep->ppc_fp0_regnum and tdep->ppc_fpscr_regnum. The original code replicated the BFD arch/mach switching done in rs6000_gdbarch_init; it's better to keep that logic there, and just check the results here. (rs6000_gdbarch_init): On the E500, set tdep->ppc_fp0_regnum and tdep->ppc_fpscr_regnum to -1 to indicate that we have no floating-point registers. (ppc_supply_fpregset, ppc_collect_fpregset) (rs6000_push_dummy_call, rs6000_extract_return_value) (rs6000_store_return_value): Assert that we have floating-point registers. (rs6000_dwarf2_stab_reg_to_regnum): Add FIXME. (rs6000_frame_cache): Don't note the locations at which floating-point registers were saved if we have no fprs. * aix-thread.c (supply_fprs, fill_fprs): Assert that we have FP registers. (fetch_regs_user_thread, fetch_regs_kernel_thread) (store_regs_user_thread, store_regs_kernel_thread): Only call supply_fprs / fill_fprs if we actually have floating-point registers. (special_register_p): Check ppc_fpscr_regnum before matching against it. (supply_sprs64, supply_sprs32, fill_sprs64, fill_sprs32): Don't supply / collect fpscr if we don't have it. * ppc-bdm.c: #include "gdb_assert.h". (bdm_ppc_fetch_registers, bdm_ppc_store_registers): Assert that we have floating-point registers, since I can't test this code on FP-free systems to adapt it. * ppc-linux-nat.c (ppc_register_u_addr): Don't match against the fpscr and floating point register numbers if they don't exist. (fetch_register): Assert that we have floating-point registers before we reach the code that handles them. (store_register): Same. And use tdep instead of calling gdbarch_tdep again. (fill_fpregset): Don't try to collect FP registers and fpscr if we don't have them. (ppc_linux_sigtramp_cache): Don't record the saved locations of fprs and fpscr if we don't have them. (ppc_linux_supply_fpregset): Don't supply fp regs and fpscr if we don't have them. * ppcnbsd-nat.c: #include "gdb_assert.h". (getfpregs_supplies): Assert that we have floating-point registers. * ppcnbsd-tdep.c (ppcnbsd_supply_fpreg, ppcnbsd_fill_fpreg): Same. * ppcobsd-tdep.c: #include "gdb_assert.h". (ppcobsd_supply_gregset, ppcobsd_collect_gregset): Assert that we have floating-point registers. * rs6000-nat.c (regmap): Don't match against the fpscr and floating point register numbers if they don't exist. (fetch_inferior_registers, store_inferior_registers, fetch_core_registers): Only fetch / store / supply the floating-point registers and the fpscr if we have them. * Makefile.in (ppc-bdm.o, ppc-linux-nat.o, ppcnbsd-nat.o) (ppcobsd-tdep.o): Update dependencies.
2004-05-11 12:55:32 +08:00
if (tdep->ppc_fp0_regnum >= 0
&& regno >= tdep->ppc_fp0_regnum
&& regno < tdep->ppc_fp0_regnum + ppc_num_fprs)
u_addr = (PT_FPR0 * wordsize) + ((regno - tdep->ppc_fp0_regnum) * 8);
/* UISA special purpose registers: 1 slot each. */
if (regno == gdbarch_pc_regnum (gdbarch))
u_addr = PT_NIP * wordsize;
if (regno == tdep->ppc_lr_regnum)
u_addr = PT_LNK * wordsize;
if (regno == tdep->ppc_cr_regnum)
u_addr = PT_CCR * wordsize;
if (regno == tdep->ppc_xer_regnum)
u_addr = PT_XER * wordsize;
if (regno == tdep->ppc_ctr_regnum)
u_addr = PT_CTR * wordsize;
#ifdef PT_MQ
if (regno == tdep->ppc_mq_regnum)
u_addr = PT_MQ * wordsize;
#endif
if (regno == tdep->ppc_ps_regnum)
u_addr = PT_MSR * wordsize;
ChangeLog: * Makefile.in (ppc_linux_tdep_h): New macro. (powerpc_32l_c, powerpc_altivec32_c, powerpc_altivec32l_c): Likewise. (powerpc_64l_c, powerpc_altivec64_c, powerpc_altivec64l_c): Likewise. (powerpc_e500l_c): Likewise. (ppc-linux-nat.o): Update dependencies. (ppc-linux-tdep.o): Update dependencies. (rs6000-tdep.o): Update dependencies. * ppc-tdep.h (ppc_linux_memory_remove_breakpoint): Remove. (ppc_linux_svr4_fetch_link_map_offsets): Remove. (ppc_linux_gregset, ppc_linux_fpregset): Move to ppc-linux-tdep.h (ppc_supply_reg, ppc_collect_reg): Add prototypes. (tdesc_powerpc_e500): Remove. * rs6000.c: Include "features/rs6000/powerpc-altivec32.c" and "features/rs6000/powerpc-altivec64.c". (ppc_supply_reg, ppc_collect_reg): Make global. (variants): Use tdesc_powerpc_32 for "powerpc" and tdesc_powerpc_altivec64 for "powerpc64". (_initialize_rs6000_tdep): Initialize AltiVec descriptions. * ppc-linux-tdep.h: New file. * ppc-linux-tdep.c: Include "ppc-linux-tdep.c". Include "features/rs6000/powerpc-32l.c". Include "features/rs6000/powerpc-altivec32l.c". Include "features/rs6000/powerpc-64l.c". Include "features/rs6000/powerpc-altivec64l.c". Include "features/rs6000/powerpc-e500l.c". (ppc_linux_supply_gregset): New function. (ppc_linux_collect_gregset): Handle orig_r3 and trap registers. (ppc32_linux_gregset): Use ppc_linux_supply_gregset. (ppc64_linux_gregset): Likewise. (ppc_linux_sigtramp_cache): Handle orig_r3 and trap registers. (ppc_linux_trap_reg_p): New function. (ppc_linux_write_pc): New function. (ppc_linux_core_read_description): New function. (ppc_linux_init_abi): Install ppc_linux_write_pc and ppc_linux_core_read_description. Install orig_r3 and trap registers if present in the target description. (_initialize_ppc_linux_tdep): Initialize Linux target descriptions. * ppc-linux-nat.c: Include "ppc-linux-tdep.h". (PT_ORIG_R3, PT_TRAP): Define if necessary. (ppc_register_u_addr): Handle orig_r3 and trap registers. (fetch_ppc_registers): Likewise. (store_ppc_registers): Likewise. (store_register): Likewise. (ppc_linux_read_description): Check whether AltiVec is supported. Check whether inferior is 32-bit or 64-bit. Return the appropriate Linux target description. * features/Makefile (WHICH): Use rs6000/powerpc-32l and rs6000/powerpc-altivec32l instead of rs6000/powerpc-32. Use rs6000/powerpc-64l and rs6000/powerpc-altivec64l instead of rs6000/powerpc-64. Use rs6000/powerpc-e500l instead of rs6000/powerpc-e500. Update -expedite variables accordingly. * features/rs6000/power-spe.xml: Use regnum 73 for "acc". * features/rs6000/powerpc-32.xml: Do not include power-altivec.xml. * features/rs6000/powerpc-64.xml: Do not include power-altivec.xml. * features/rs6000/powerpc-e500.c: Regenerate. * features/rs6000/powerpc-32.c: Regenerate. * features/rs6000/powerpc-64.c: Regenerate. * features/rs6000/power-linux.xml: New file. * features/rs6000/power64-linux.xml: New file. * features/rs6000/powerpc-32l.xml: New file. * features/rs6000/powerpc-altivec32l.xml: New file. * features/rs6000/powerpc-64l.xml: New file. * features/rs6000/powerpc-altivec64l.xml: New file. * features/rs6000/powerpc-e500l.xml: New file. * features/rs6000/powerpc-32l.c: New (generated) file. * features/rs6000/powerpc-altivec32l.c: New (generated) file. * features/rs6000/powerpc-64l.c: New (generated) file. * features/rs6000/powerpc-altivec64l.c: New (generated) file. * features/rs6000/powerpc-e500l.xml: New (generated) file. * regformats/reg-ppc.dat: Remove. * regformats/reg-ppc64.dat: Remove. * regformats/rs6000/powerpc-32.dat: Remove. * regformats/rs6000/powerpc-64.dat: Remove. * regformats/rs6000/powerpc-e500.dat: Remove. * regformats/rs6000/powerpc-32l.dat: New (generated) file. * regformats/rs6000/powerpc-altivec32l.dat: New (generated) file. * regformats/rs6000/powerpc-64l.dat: New (generated) file. * regformats/rs6000/powerpc-altivec64l.dat: New (generated) file. * regformats/rs6000/powerpc-e500l.dat: New (generated) file. gdbserver/ChangeLog: * configure.srv (powerpc*-*-linux*): Set srv_regobj to powerpc-32l.o, powerpc-altivec32l.o, powerpc-e500l.o, powerpc-64l.o, and powerpc-altivec64l.o. Remove rs6000/powerpc-32.xml, rs6000/powerpc-64.xml, and rs6000/powerpc-e500.xml; add rs6000/powerpc-32l.xml, rs6000/powerpc-altivec32l.xml, rs6000/powerpc-e500l.xml, rs6000/powerpc-64l.xml, rs6000/powerpc-altivec64l.xml, rs6000/power-linux.xml, and rs6000/power64-linux.xml to srv_xmlfiles. * Makefile.in (reg-ppc.o, reg-ppc.c): Remove, replace by ... (powerpc-32l.o, powerpc-32l.c): ... these new rules. (powerpc-32.o, powerpc-32.c): Remove, replace by ... (powerpc-altivec32l.o, powerpc-altivec32l.c): ... these new rules. (powerpc-e500.o, powerpc-e500.c): Remove, replace by ... (powerpc-e500l.o, powerpc-e500l.c): ... these new rules. (reg-ppc64.o, reg-ppc64.c): Remove, replace by ... (powerpc-64l.o, powerpc-64l.c): ... these new rules. (powerpc-64.o, powerpc-64.c): Remove, replace by ... (powerpc-altivec64l.o, powerpc-altivec64l.c): ... these new rules. (clean): Update. * linux-ppc-low.c (init_registers_ppc): Remove, replace by ... (init_registers_powerpc_32l): ... this new prototype. (init_registers_powerpc_32): Remove, replace by ... (init_registers_powerpc_altivec32l): ... this new prototype. (init_registers_powerpc_e500): Remove, replace by ... (init_registers_powerpc_e500l): ... this new prototype. (init_registers_ppc64): Remove, replace by ... (init_registers_powerpc_64l): ... this new prototype. (init_registers_powerpc_64): Remove, replace by ... (init_registers_powerpc_altivec64l): ... this new prototype. (ppc_num_regs): Set to 73. (PT_ORIG_R3, PT_TRAP): Define if necessary. (ppc_regmap, ppc_regmap_e500): Add values for orig_r3 and trap. (ppc_cannot_store_register): Handle orig_r3 and trap. (ppc_arch_setup): Update init_registers_... calls. (ppc_fill_gregset): Handle orig_r3 and trap. * inferiors.c (clear_inferiors): Reset current_inferior.
2008-05-04 01:16:44 +08:00
if (regno == PPC_ORIG_R3_REGNUM)
u_addr = PT_ORIG_R3 * wordsize;
if (regno == PPC_TRAP_REGNUM)
u_addr = PT_TRAP * wordsize;
* ppc-tdep.h (struct gdbarch_tdep): Change definition of ppc_fp0_regnum and ppc_fpscr_regnum: if they are -1, then this processor variant lacks those registers. (ppc_floating_point_unit_p): Change description to make it clear that this returns info about the ISA, not the ABI. * rs6000-tdep.c (ppc_floating_point_unit_p): Decide whether to return true or false by checking tdep->ppc_fp0_regnum and tdep->ppc_fpscr_regnum. The original code replicated the BFD arch/mach switching done in rs6000_gdbarch_init; it's better to keep that logic there, and just check the results here. (rs6000_gdbarch_init): On the E500, set tdep->ppc_fp0_regnum and tdep->ppc_fpscr_regnum to -1 to indicate that we have no floating-point registers. (ppc_supply_fpregset, ppc_collect_fpregset) (rs6000_push_dummy_call, rs6000_extract_return_value) (rs6000_store_return_value): Assert that we have floating-point registers. (rs6000_dwarf2_stab_reg_to_regnum): Add FIXME. (rs6000_frame_cache): Don't note the locations at which floating-point registers were saved if we have no fprs. * aix-thread.c (supply_fprs, fill_fprs): Assert that we have FP registers. (fetch_regs_user_thread, fetch_regs_kernel_thread) (store_regs_user_thread, store_regs_kernel_thread): Only call supply_fprs / fill_fprs if we actually have floating-point registers. (special_register_p): Check ppc_fpscr_regnum before matching against it. (supply_sprs64, supply_sprs32, fill_sprs64, fill_sprs32): Don't supply / collect fpscr if we don't have it. * ppc-bdm.c: #include "gdb_assert.h". (bdm_ppc_fetch_registers, bdm_ppc_store_registers): Assert that we have floating-point registers, since I can't test this code on FP-free systems to adapt it. * ppc-linux-nat.c (ppc_register_u_addr): Don't match against the fpscr and floating point register numbers if they don't exist. (fetch_register): Assert that we have floating-point registers before we reach the code that handles them. (store_register): Same. And use tdep instead of calling gdbarch_tdep again. (fill_fpregset): Don't try to collect FP registers and fpscr if we don't have them. (ppc_linux_sigtramp_cache): Don't record the saved locations of fprs and fpscr if we don't have them. (ppc_linux_supply_fpregset): Don't supply fp regs and fpscr if we don't have them. * ppcnbsd-nat.c: #include "gdb_assert.h". (getfpregs_supplies): Assert that we have floating-point registers. * ppcnbsd-tdep.c (ppcnbsd_supply_fpreg, ppcnbsd_fill_fpreg): Same. * ppcobsd-tdep.c: #include "gdb_assert.h". (ppcobsd_supply_gregset, ppcobsd_collect_gregset): Assert that we have floating-point registers. * rs6000-nat.c (regmap): Don't match against the fpscr and floating point register numbers if they don't exist. (fetch_inferior_registers, store_inferior_registers, fetch_core_registers): Only fetch / store / supply the floating-point registers and the fpscr if we have them. * Makefile.in (ppc-bdm.o, ppc-linux-nat.o, ppcnbsd-nat.o) (ppcobsd-tdep.o): Update dependencies.
2004-05-11 12:55:32 +08:00
if (tdep->ppc_fpscr_regnum >= 0
&& regno == tdep->ppc_fpscr_regnum)
{
/* NOTE: cagney/2005-02-08: On some 64-bit GNU/Linux systems the
kernel headers incorrectly contained the 32-bit definition of
PT_FPSCR. For the 32-bit definition, floating-point
registers occupy two 32-bit "slots", and the FPSCR lives in
gdb/ * ppc-linux-nat.c (ppc_register_u_addr): Add special case to return offset for full 64-bit slot of FPSCR when in 32-bits. (ppc_linux_read_description): Return target description with 64-bit FPSCR when inferior is running on an ISA 2.05 or later processor. * ppc-linux-tdep.c (_initialize_ppc_linux_tdep): Call initialize_tdec_powerpc_isa205_32l, initialize_tdec_powerpc_isa205_altivec32l, initialize_tdec_powerpc_isa205_vsx32l, initialize_tdec_powerpc_isa205_64l, initialize_tdec_powerpc_isa205_altivec64l and initialize_tdec_powerpc_isa205_vsx64l. * ppc-linux-tdep.h: Add external declaration for tdesc_powerpc_isa205_32l, tdesc_powerpc_isa205_altivec32l, tdesc_powerpc_isa205_vsx32l, tdesc_powerpc_isa205_64l, tdesc_powerpc_isa205_altivec64l and tdesc_powerpc_isa205_vsx64l. * features/rs600/powerpc-fpu-isa205.xml: New file. * features/rs600/powerpc-isa205-32l.xml: New file. * features/rs600/powerpc-isa205-64l.xml: New file. * features/rs600/powerpc-isa205-altivec32l.xml: New file. * features/rs600/powerpc-isa205-altivec64l.xml: New file. * features/rs600/powerpc-isa205-vsx32l.xml: New file. * features/rs600/powerpc-isa205-vsx64l.xml: New file. * features/rs600/powerpc-isa205-32l.c: Generate. * features/rs600/powerpc-isa205-64l.c: Generate. * features/rs600/powerpc-isa205-altivec32l.c: Generate. * features/rs600/powerpc-isa205-altivec64l.c: Generate. * features/rs600/powerpc-isa205-vsx32l.c: Generate. * features/rs600/powerpc-isa205-vsx64l.c: Generate. gdb/testsuite/ * gdb.arch/ppc-dfp.exp: New file. * gdb.arch/ppc-dfp.c: New file.
2008-11-19 05:39:47 +08:00
the second half of such a slot-pair (hence +1). For 64-bit,
the FPSCR instead occupies the full 64-bit 2-word-slot and
hence no adjustment is necessary. Hack around this. */
if (wordsize == 8 && PT_FPSCR == (48 + 32 + 1))
u_addr = (48 + 32) * wordsize;
gdb/ * ppc-linux-nat.c (ppc_register_u_addr): Add special case to return offset for full 64-bit slot of FPSCR when in 32-bits. (ppc_linux_read_description): Return target description with 64-bit FPSCR when inferior is running on an ISA 2.05 or later processor. * ppc-linux-tdep.c (_initialize_ppc_linux_tdep): Call initialize_tdec_powerpc_isa205_32l, initialize_tdec_powerpc_isa205_altivec32l, initialize_tdec_powerpc_isa205_vsx32l, initialize_tdec_powerpc_isa205_64l, initialize_tdec_powerpc_isa205_altivec64l and initialize_tdec_powerpc_isa205_vsx64l. * ppc-linux-tdep.h: Add external declaration for tdesc_powerpc_isa205_32l, tdesc_powerpc_isa205_altivec32l, tdesc_powerpc_isa205_vsx32l, tdesc_powerpc_isa205_64l, tdesc_powerpc_isa205_altivec64l and tdesc_powerpc_isa205_vsx64l. * features/rs600/powerpc-fpu-isa205.xml: New file. * features/rs600/powerpc-isa205-32l.xml: New file. * features/rs600/powerpc-isa205-64l.xml: New file. * features/rs600/powerpc-isa205-altivec32l.xml: New file. * features/rs600/powerpc-isa205-altivec64l.xml: New file. * features/rs600/powerpc-isa205-vsx32l.xml: New file. * features/rs600/powerpc-isa205-vsx64l.xml: New file. * features/rs600/powerpc-isa205-32l.c: Generate. * features/rs600/powerpc-isa205-64l.c: Generate. * features/rs600/powerpc-isa205-altivec32l.c: Generate. * features/rs600/powerpc-isa205-altivec64l.c: Generate. * features/rs600/powerpc-isa205-vsx32l.c: Generate. * features/rs600/powerpc-isa205-vsx64l.c: Generate. gdb/testsuite/ * gdb.arch/ppc-dfp.exp: New file. * gdb.arch/ppc-dfp.c: New file.
2008-11-19 05:39:47 +08:00
/* If the FPSCR is 64-bit wide, we need to fetch the whole 64-bit
slot and not just its second word. The PT_FPSCR supplied when
GDB is compiled as a 32-bit app doesn't reflect this. */
else if (wordsize == 4 && register_size (gdbarch, regno) == 8
&& PT_FPSCR == (48 + 2*32 + 1))
u_addr = (48 + 2*32) * wordsize;
else
u_addr = PT_FPSCR * wordsize;
}
return u_addr;
}
* rs6000-tdep: Include "features/rs6000/powerpc-vsx32.c". Include "features/rs6000/powerpc-vsx64.c". (ppc_supply_vsxregset): New function. (ppc_collect_vsxregset): New function. (IS_VSX_PSEUDOREG): New macro. (IS_EFP_PSEUDOREG): New macro. (vsx_register_p): New function. (ppc_vsx_support_p): New function. (rs6000_builtin_type_vec128): New function. (rs6000_register_name): Hide upper halves of vs0~vs31. Return correct names for VSX registers and EFPR registers. (rs6000_pseudo_register_type): Return correct types for VSX and EFPR registers. (rs6000_pseudo_register_reggroup_p): Return correct group for VSX and EFPR registers. (ppc_pseudo_register_read): Rename to dfp_pseudo_register_read. (ppc_pseudo_register_write): Rename to dfp_pseudo_register_write. (vsx_pseudo_register_read): New function. (vsx_pseudo_register_write): New function. (efpr_pseudo_register_read): New function. (efpr_pseudo_register_write): New function. (rs6000_pseudo_register_read): Call new VSX and EFPR read functions. (rs6000_pseudo_register_write): Call new VSX and EFPR write functions. (rs6000_gdbarch_init): Declare have_vsx. Initialize new upper half VSX registers. Initialize VSX-related and EFPR-related pseudo-registers variables. Adjust the number of pseudo registers accordingly. * ppc-linux-nat.c: Define PTRACE_GETVSXREGS, PTRACE_SETVSXREGS and SIZEOF_VSRREGS. (gdb_vsxregset_t): New type. (have_ptrace_getsetvsxregs): New variable. (fetch_vsx_register): New function. (fetch_register): Handle VSX registers. (fetch_vsx_registers): New function. (fetch_ppc_registers): Handle VSX registers. (store_ppc_registers): Handle VSX registers. (store_vsx_register): New function. (store_register): Handle VSX registers. (store_vsx_registers): New function. (ppc_linux_read_description): Handle VSX-enabled inferiors. (gdb_vsxregset_t): New type. (supply_vsxregset): New function. (fill_vsxregset): New function. * ppc-tdep.h (vsx_register_p): New prototype. (vsx_support_p): New prototype. (ppc_vsr0_regnum): New variable. (ppc_vsr0_upper_regnum): Likewise. (ppc_efpr0_regnum): Likewise. (ppc_builtin_type_vec128): New type. (ppc_num_vsrs): New constant. (ppc_num_vshrs): New constant. (ppc_num_efprs): Likewise. Define POWERPC_VEC_VSX PPC_VSR0_UPPER_REGNUM and PPC_VSR31_UPPER_REGNUM. (ppc_supply_vsxregset): New prototype. (ppc_collect_vsxregset): New prototype. * ppc-linux-tdep.c: Include "features/rs6000/powerpc-vsx32l.c" Include "features/rs6000/powerpc-vsx64l.c". (_initialize_ppc_linux_tdep): Initialize VSX-enabled targets. (ppc_linux_regset_sections): Add new ".reg-ppc-vsx" field. (ppc32_linux_vsxregset): New 32-bit VSX-enabled regset. (ppc_linux_regset_from_core_section): Handle VSX core section. (ppc_linux_core_read_description): Support VSX-enabled core files. * ppc-linux-tdep.h: Declare *tdesc_powerpc_vsx32l Declare tdesc_powerpc_vsx64l * corelow.c (get_core_register_section): Support VSX-enabled core files. * features/rs6000/power-vsx.xml: New VSX descriptions. * features/rs6000/powerpc-vsx32.xml: New file. * features/rs6000/powerpc-vsx32l.xml: New file. * features/rs6000/powerpc-vsx64.xml: New file. * features/rs6000/powerpc-vsx64l.xml: New file. * features/rs6000/powerpc-vsx32.c: New file (generated). * features/rs6000/powerpc-vsx32l.c: New file (generated). * features/rs6000/powerpc-vsx64.c: New file (generated). * features/rs6000/powerpc-vsx64l.c: New file (generated). * features/Makefile: Updated with new descriptions. * regformats/rs6000/powerpc-vsx32l.dat: New file (generated). * regformats/rs6000/powerpc-vsx64l.dat: New file (generated). * testsuite/gdb.arch/vsx-regs.c: New source file. * testsuite/gdb.arch/vsx-regs.exp: New testcase. * testsuite/lib/gdb.exp (skip_vsx_tests): New function.
2008-08-15 23:18:34 +08:00
/* The Linux kernel ptrace interface for POWER7 VSX registers uses the
registers set mechanism, as opposed to the interface for all the
other registers, that stores/fetches each register individually. */
static void
[PowerPC] Fix VSX registers in linux core files The functions used by the VSX regset to collect and supply registers from core files where incorrect. This patch changes the regset to use the standard regset collect/supply functions to fix this. The native target is also changed to use the same regset. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-linux-tdep.c (ppc_linux_vsxregset): New function. (ppc32_linux_vsxregmap): New global. (ppc32_linux_vsxregset): Initialize with ppc32_linux_vsxregmap, regcache_supply_regset, and regcache_collect_regset. * ppc-linux-tdep.h (ppc_linux_vsxregset): Declare. * ppc-linux-nat.c (supply_vsxregset, fill_vsxregset): Remove. (fetch_vsx_register, store_vsx_register): Remove. (fetch_vsx_registers): Add regno parameter. Get regset using ppc_linux_vsxregset. Use regset to supply registers. (store_vsx_registers): Add regno parameter. Get regset using ppc_linux_vsxregset. Use regset to collect registers. (fetch_register): Call fetch_vsx_registers instead of fetch_vsx_register. (store_register): Call store_vsx_registers instead of store_vsx_register. (fetch_ppc_registers): Call fetch_vsx_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_vsx_registers with -1 for the new regno parameter. * rs6000-tdep.c (ppc_vsx_support_p, ppc_supply_vsxreget) (ppc_collect_vsxregset): Remove. gdb/testsuite/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * gdb.arch/powerpc-vsx-gcore.exp: New file.
2018-05-22 22:09:05 +08:00
fetch_vsx_registers (struct regcache *regcache, int tid, int regno)
* rs6000-tdep: Include "features/rs6000/powerpc-vsx32.c". Include "features/rs6000/powerpc-vsx64.c". (ppc_supply_vsxregset): New function. (ppc_collect_vsxregset): New function. (IS_VSX_PSEUDOREG): New macro. (IS_EFP_PSEUDOREG): New macro. (vsx_register_p): New function. (ppc_vsx_support_p): New function. (rs6000_builtin_type_vec128): New function. (rs6000_register_name): Hide upper halves of vs0~vs31. Return correct names for VSX registers and EFPR registers. (rs6000_pseudo_register_type): Return correct types for VSX and EFPR registers. (rs6000_pseudo_register_reggroup_p): Return correct group for VSX and EFPR registers. (ppc_pseudo_register_read): Rename to dfp_pseudo_register_read. (ppc_pseudo_register_write): Rename to dfp_pseudo_register_write. (vsx_pseudo_register_read): New function. (vsx_pseudo_register_write): New function. (efpr_pseudo_register_read): New function. (efpr_pseudo_register_write): New function. (rs6000_pseudo_register_read): Call new VSX and EFPR read functions. (rs6000_pseudo_register_write): Call new VSX and EFPR write functions. (rs6000_gdbarch_init): Declare have_vsx. Initialize new upper half VSX registers. Initialize VSX-related and EFPR-related pseudo-registers variables. Adjust the number of pseudo registers accordingly. * ppc-linux-nat.c: Define PTRACE_GETVSXREGS, PTRACE_SETVSXREGS and SIZEOF_VSRREGS. (gdb_vsxregset_t): New type. (have_ptrace_getsetvsxregs): New variable. (fetch_vsx_register): New function. (fetch_register): Handle VSX registers. (fetch_vsx_registers): New function. (fetch_ppc_registers): Handle VSX registers. (store_ppc_registers): Handle VSX registers. (store_vsx_register): New function. (store_register): Handle VSX registers. (store_vsx_registers): New function. (ppc_linux_read_description): Handle VSX-enabled inferiors. (gdb_vsxregset_t): New type. (supply_vsxregset): New function. (fill_vsxregset): New function. * ppc-tdep.h (vsx_register_p): New prototype. (vsx_support_p): New prototype. (ppc_vsr0_regnum): New variable. (ppc_vsr0_upper_regnum): Likewise. (ppc_efpr0_regnum): Likewise. (ppc_builtin_type_vec128): New type. (ppc_num_vsrs): New constant. (ppc_num_vshrs): New constant. (ppc_num_efprs): Likewise. Define POWERPC_VEC_VSX PPC_VSR0_UPPER_REGNUM and PPC_VSR31_UPPER_REGNUM. (ppc_supply_vsxregset): New prototype. (ppc_collect_vsxregset): New prototype. * ppc-linux-tdep.c: Include "features/rs6000/powerpc-vsx32l.c" Include "features/rs6000/powerpc-vsx64l.c". (_initialize_ppc_linux_tdep): Initialize VSX-enabled targets. (ppc_linux_regset_sections): Add new ".reg-ppc-vsx" field. (ppc32_linux_vsxregset): New 32-bit VSX-enabled regset. (ppc_linux_regset_from_core_section): Handle VSX core section. (ppc_linux_core_read_description): Support VSX-enabled core files. * ppc-linux-tdep.h: Declare *tdesc_powerpc_vsx32l Declare tdesc_powerpc_vsx64l * corelow.c (get_core_register_section): Support VSX-enabled core files. * features/rs6000/power-vsx.xml: New VSX descriptions. * features/rs6000/powerpc-vsx32.xml: New file. * features/rs6000/powerpc-vsx32l.xml: New file. * features/rs6000/powerpc-vsx64.xml: New file. * features/rs6000/powerpc-vsx64l.xml: New file. * features/rs6000/powerpc-vsx32.c: New file (generated). * features/rs6000/powerpc-vsx32l.c: New file (generated). * features/rs6000/powerpc-vsx64.c: New file (generated). * features/rs6000/powerpc-vsx64l.c: New file (generated). * features/Makefile: Updated with new descriptions. * regformats/rs6000/powerpc-vsx32l.dat: New file (generated). * regformats/rs6000/powerpc-vsx64l.dat: New file (generated). * testsuite/gdb.arch/vsx-regs.c: New source file. * testsuite/gdb.arch/vsx-regs.exp: New testcase. * testsuite/lib/gdb.exp (skip_vsx_tests): New function.
2008-08-15 23:18:34 +08:00
{
int ret;
gdb_vsxregset_t regs;
[PowerPC] Fix VSX registers in linux core files The functions used by the VSX regset to collect and supply registers from core files where incorrect. This patch changes the regset to use the standard regset collect/supply functions to fix this. The native target is also changed to use the same regset. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-linux-tdep.c (ppc_linux_vsxregset): New function. (ppc32_linux_vsxregmap): New global. (ppc32_linux_vsxregset): Initialize with ppc32_linux_vsxregmap, regcache_supply_regset, and regcache_collect_regset. * ppc-linux-tdep.h (ppc_linux_vsxregset): Declare. * ppc-linux-nat.c (supply_vsxregset, fill_vsxregset): Remove. (fetch_vsx_register, store_vsx_register): Remove. (fetch_vsx_registers): Add regno parameter. Get regset using ppc_linux_vsxregset. Use regset to supply registers. (store_vsx_registers): Add regno parameter. Get regset using ppc_linux_vsxregset. Use regset to collect registers. (fetch_register): Call fetch_vsx_registers instead of fetch_vsx_register. (store_register): Call store_vsx_registers instead of store_vsx_register. (fetch_ppc_registers): Call fetch_vsx_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_vsx_registers with -1 for the new regno parameter. * rs6000-tdep.c (ppc_vsx_support_p, ppc_supply_vsxreget) (ppc_collect_vsxregset): Remove. gdb/testsuite/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * gdb.arch/powerpc-vsx-gcore.exp: New file.
2018-05-22 22:09:05 +08:00
const struct regset *vsxregset = ppc_linux_vsxregset ();
* rs6000-tdep: Include "features/rs6000/powerpc-vsx32.c". Include "features/rs6000/powerpc-vsx64.c". (ppc_supply_vsxregset): New function. (ppc_collect_vsxregset): New function. (IS_VSX_PSEUDOREG): New macro. (IS_EFP_PSEUDOREG): New macro. (vsx_register_p): New function. (ppc_vsx_support_p): New function. (rs6000_builtin_type_vec128): New function. (rs6000_register_name): Hide upper halves of vs0~vs31. Return correct names for VSX registers and EFPR registers. (rs6000_pseudo_register_type): Return correct types for VSX and EFPR registers. (rs6000_pseudo_register_reggroup_p): Return correct group for VSX and EFPR registers. (ppc_pseudo_register_read): Rename to dfp_pseudo_register_read. (ppc_pseudo_register_write): Rename to dfp_pseudo_register_write. (vsx_pseudo_register_read): New function. (vsx_pseudo_register_write): New function. (efpr_pseudo_register_read): New function. (efpr_pseudo_register_write): New function. (rs6000_pseudo_register_read): Call new VSX and EFPR read functions. (rs6000_pseudo_register_write): Call new VSX and EFPR write functions. (rs6000_gdbarch_init): Declare have_vsx. Initialize new upper half VSX registers. Initialize VSX-related and EFPR-related pseudo-registers variables. Adjust the number of pseudo registers accordingly. * ppc-linux-nat.c: Define PTRACE_GETVSXREGS, PTRACE_SETVSXREGS and SIZEOF_VSRREGS. (gdb_vsxregset_t): New type. (have_ptrace_getsetvsxregs): New variable. (fetch_vsx_register): New function. (fetch_register): Handle VSX registers. (fetch_vsx_registers): New function. (fetch_ppc_registers): Handle VSX registers. (store_ppc_registers): Handle VSX registers. (store_vsx_register): New function. (store_register): Handle VSX registers. (store_vsx_registers): New function. (ppc_linux_read_description): Handle VSX-enabled inferiors. (gdb_vsxregset_t): New type. (supply_vsxregset): New function. (fill_vsxregset): New function. * ppc-tdep.h (vsx_register_p): New prototype. (vsx_support_p): New prototype. (ppc_vsr0_regnum): New variable. (ppc_vsr0_upper_regnum): Likewise. (ppc_efpr0_regnum): Likewise. (ppc_builtin_type_vec128): New type. (ppc_num_vsrs): New constant. (ppc_num_vshrs): New constant. (ppc_num_efprs): Likewise. Define POWERPC_VEC_VSX PPC_VSR0_UPPER_REGNUM and PPC_VSR31_UPPER_REGNUM. (ppc_supply_vsxregset): New prototype. (ppc_collect_vsxregset): New prototype. * ppc-linux-tdep.c: Include "features/rs6000/powerpc-vsx32l.c" Include "features/rs6000/powerpc-vsx64l.c". (_initialize_ppc_linux_tdep): Initialize VSX-enabled targets. (ppc_linux_regset_sections): Add new ".reg-ppc-vsx" field. (ppc32_linux_vsxregset): New 32-bit VSX-enabled regset. (ppc_linux_regset_from_core_section): Handle VSX core section. (ppc_linux_core_read_description): Support VSX-enabled core files. * ppc-linux-tdep.h: Declare *tdesc_powerpc_vsx32l Declare tdesc_powerpc_vsx64l * corelow.c (get_core_register_section): Support VSX-enabled core files. * features/rs6000/power-vsx.xml: New VSX descriptions. * features/rs6000/powerpc-vsx32.xml: New file. * features/rs6000/powerpc-vsx32l.xml: New file. * features/rs6000/powerpc-vsx64.xml: New file. * features/rs6000/powerpc-vsx64l.xml: New file. * features/rs6000/powerpc-vsx32.c: New file (generated). * features/rs6000/powerpc-vsx32l.c: New file (generated). * features/rs6000/powerpc-vsx64.c: New file (generated). * features/rs6000/powerpc-vsx64l.c: New file (generated). * features/Makefile: Updated with new descriptions. * regformats/rs6000/powerpc-vsx32l.dat: New file (generated). * regformats/rs6000/powerpc-vsx64l.dat: New file (generated). * testsuite/gdb.arch/vsx-regs.c: New source file. * testsuite/gdb.arch/vsx-regs.exp: New testcase. * testsuite/lib/gdb.exp (skip_vsx_tests): New function.
2008-08-15 23:18:34 +08:00
ret = ptrace (PTRACE_GETVSXREGS, tid, 0, &regs);
if (ret < 0)
{
if (errno == EIO)
{
have_ptrace_getsetvsxregs = 0;
return;
}
[PowerPC] Fix VSX registers in linux core files The functions used by the VSX regset to collect and supply registers from core files where incorrect. This patch changes the regset to use the standard regset collect/supply functions to fix this. The native target is also changed to use the same regset. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-linux-tdep.c (ppc_linux_vsxregset): New function. (ppc32_linux_vsxregmap): New global. (ppc32_linux_vsxregset): Initialize with ppc32_linux_vsxregmap, regcache_supply_regset, and regcache_collect_regset. * ppc-linux-tdep.h (ppc_linux_vsxregset): Declare. * ppc-linux-nat.c (supply_vsxregset, fill_vsxregset): Remove. (fetch_vsx_register, store_vsx_register): Remove. (fetch_vsx_registers): Add regno parameter. Get regset using ppc_linux_vsxregset. Use regset to supply registers. (store_vsx_registers): Add regno parameter. Get regset using ppc_linux_vsxregset. Use regset to collect registers. (fetch_register): Call fetch_vsx_registers instead of fetch_vsx_register. (store_register): Call store_vsx_registers instead of store_vsx_register. (fetch_ppc_registers): Call fetch_vsx_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_vsx_registers with -1 for the new regno parameter. * rs6000-tdep.c (ppc_vsx_support_p, ppc_supply_vsxreget) (ppc_collect_vsxregset): Remove. gdb/testsuite/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * gdb.arch/powerpc-vsx-gcore.exp: New file.
2018-05-22 22:09:05 +08:00
perror_with_name (_("Unable to fetch VSX registers"));
* rs6000-tdep: Include "features/rs6000/powerpc-vsx32.c". Include "features/rs6000/powerpc-vsx64.c". (ppc_supply_vsxregset): New function. (ppc_collect_vsxregset): New function. (IS_VSX_PSEUDOREG): New macro. (IS_EFP_PSEUDOREG): New macro. (vsx_register_p): New function. (ppc_vsx_support_p): New function. (rs6000_builtin_type_vec128): New function. (rs6000_register_name): Hide upper halves of vs0~vs31. Return correct names for VSX registers and EFPR registers. (rs6000_pseudo_register_type): Return correct types for VSX and EFPR registers. (rs6000_pseudo_register_reggroup_p): Return correct group for VSX and EFPR registers. (ppc_pseudo_register_read): Rename to dfp_pseudo_register_read. (ppc_pseudo_register_write): Rename to dfp_pseudo_register_write. (vsx_pseudo_register_read): New function. (vsx_pseudo_register_write): New function. (efpr_pseudo_register_read): New function. (efpr_pseudo_register_write): New function. (rs6000_pseudo_register_read): Call new VSX and EFPR read functions. (rs6000_pseudo_register_write): Call new VSX and EFPR write functions. (rs6000_gdbarch_init): Declare have_vsx. Initialize new upper half VSX registers. Initialize VSX-related and EFPR-related pseudo-registers variables. Adjust the number of pseudo registers accordingly. * ppc-linux-nat.c: Define PTRACE_GETVSXREGS, PTRACE_SETVSXREGS and SIZEOF_VSRREGS. (gdb_vsxregset_t): New type. (have_ptrace_getsetvsxregs): New variable. (fetch_vsx_register): New function. (fetch_register): Handle VSX registers. (fetch_vsx_registers): New function. (fetch_ppc_registers): Handle VSX registers. (store_ppc_registers): Handle VSX registers. (store_vsx_register): New function. (store_register): Handle VSX registers. (store_vsx_registers): New function. (ppc_linux_read_description): Handle VSX-enabled inferiors. (gdb_vsxregset_t): New type. (supply_vsxregset): New function. (fill_vsxregset): New function. * ppc-tdep.h (vsx_register_p): New prototype. (vsx_support_p): New prototype. (ppc_vsr0_regnum): New variable. (ppc_vsr0_upper_regnum): Likewise. (ppc_efpr0_regnum): Likewise. (ppc_builtin_type_vec128): New type. (ppc_num_vsrs): New constant. (ppc_num_vshrs): New constant. (ppc_num_efprs): Likewise. Define POWERPC_VEC_VSX PPC_VSR0_UPPER_REGNUM and PPC_VSR31_UPPER_REGNUM. (ppc_supply_vsxregset): New prototype. (ppc_collect_vsxregset): New prototype. * ppc-linux-tdep.c: Include "features/rs6000/powerpc-vsx32l.c" Include "features/rs6000/powerpc-vsx64l.c". (_initialize_ppc_linux_tdep): Initialize VSX-enabled targets. (ppc_linux_regset_sections): Add new ".reg-ppc-vsx" field. (ppc32_linux_vsxregset): New 32-bit VSX-enabled regset. (ppc_linux_regset_from_core_section): Handle VSX core section. (ppc_linux_core_read_description): Support VSX-enabled core files. * ppc-linux-tdep.h: Declare *tdesc_powerpc_vsx32l Declare tdesc_powerpc_vsx64l * corelow.c (get_core_register_section): Support VSX-enabled core files. * features/rs6000/power-vsx.xml: New VSX descriptions. * features/rs6000/powerpc-vsx32.xml: New file. * features/rs6000/powerpc-vsx32l.xml: New file. * features/rs6000/powerpc-vsx64.xml: New file. * features/rs6000/powerpc-vsx64l.xml: New file. * features/rs6000/powerpc-vsx32.c: New file (generated). * features/rs6000/powerpc-vsx32l.c: New file (generated). * features/rs6000/powerpc-vsx64.c: New file (generated). * features/rs6000/powerpc-vsx64l.c: New file (generated). * features/Makefile: Updated with new descriptions. * regformats/rs6000/powerpc-vsx32l.dat: New file (generated). * regformats/rs6000/powerpc-vsx64l.dat: New file (generated). * testsuite/gdb.arch/vsx-regs.c: New source file. * testsuite/gdb.arch/vsx-regs.exp: New testcase. * testsuite/lib/gdb.exp (skip_vsx_tests): New function.
2008-08-15 23:18:34 +08:00
}
[PowerPC] Fix VSX registers in linux core files The functions used by the VSX regset to collect and supply registers from core files where incorrect. This patch changes the regset to use the standard regset collect/supply functions to fix this. The native target is also changed to use the same regset. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-linux-tdep.c (ppc_linux_vsxregset): New function. (ppc32_linux_vsxregmap): New global. (ppc32_linux_vsxregset): Initialize with ppc32_linux_vsxregmap, regcache_supply_regset, and regcache_collect_regset. * ppc-linux-tdep.h (ppc_linux_vsxregset): Declare. * ppc-linux-nat.c (supply_vsxregset, fill_vsxregset): Remove. (fetch_vsx_register, store_vsx_register): Remove. (fetch_vsx_registers): Add regno parameter. Get regset using ppc_linux_vsxregset. Use regset to supply registers. (store_vsx_registers): Add regno parameter. Get regset using ppc_linux_vsxregset. Use regset to collect registers. (fetch_register): Call fetch_vsx_registers instead of fetch_vsx_register. (store_register): Call store_vsx_registers instead of store_vsx_register. (fetch_ppc_registers): Call fetch_vsx_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_vsx_registers with -1 for the new regno parameter. * rs6000-tdep.c (ppc_vsx_support_p, ppc_supply_vsxreget) (ppc_collect_vsxregset): Remove. gdb/testsuite/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * gdb.arch/powerpc-vsx-gcore.exp: New file.
2018-05-22 22:09:05 +08:00
vsxregset->supply_regset (vsxregset, regcache, regno, &regs,
PPC_LINUX_SIZEOF_VSXREGSET);
* rs6000-tdep: Include "features/rs6000/powerpc-vsx32.c". Include "features/rs6000/powerpc-vsx64.c". (ppc_supply_vsxregset): New function. (ppc_collect_vsxregset): New function. (IS_VSX_PSEUDOREG): New macro. (IS_EFP_PSEUDOREG): New macro. (vsx_register_p): New function. (ppc_vsx_support_p): New function. (rs6000_builtin_type_vec128): New function. (rs6000_register_name): Hide upper halves of vs0~vs31. Return correct names for VSX registers and EFPR registers. (rs6000_pseudo_register_type): Return correct types for VSX and EFPR registers. (rs6000_pseudo_register_reggroup_p): Return correct group for VSX and EFPR registers. (ppc_pseudo_register_read): Rename to dfp_pseudo_register_read. (ppc_pseudo_register_write): Rename to dfp_pseudo_register_write. (vsx_pseudo_register_read): New function. (vsx_pseudo_register_write): New function. (efpr_pseudo_register_read): New function. (efpr_pseudo_register_write): New function. (rs6000_pseudo_register_read): Call new VSX and EFPR read functions. (rs6000_pseudo_register_write): Call new VSX and EFPR write functions. (rs6000_gdbarch_init): Declare have_vsx. Initialize new upper half VSX registers. Initialize VSX-related and EFPR-related pseudo-registers variables. Adjust the number of pseudo registers accordingly. * ppc-linux-nat.c: Define PTRACE_GETVSXREGS, PTRACE_SETVSXREGS and SIZEOF_VSRREGS. (gdb_vsxregset_t): New type. (have_ptrace_getsetvsxregs): New variable. (fetch_vsx_register): New function. (fetch_register): Handle VSX registers. (fetch_vsx_registers): New function. (fetch_ppc_registers): Handle VSX registers. (store_ppc_registers): Handle VSX registers. (store_vsx_register): New function. (store_register): Handle VSX registers. (store_vsx_registers): New function. (ppc_linux_read_description): Handle VSX-enabled inferiors. (gdb_vsxregset_t): New type. (supply_vsxregset): New function. (fill_vsxregset): New function. * ppc-tdep.h (vsx_register_p): New prototype. (vsx_support_p): New prototype. (ppc_vsr0_regnum): New variable. (ppc_vsr0_upper_regnum): Likewise. (ppc_efpr0_regnum): Likewise. (ppc_builtin_type_vec128): New type. (ppc_num_vsrs): New constant. (ppc_num_vshrs): New constant. (ppc_num_efprs): Likewise. Define POWERPC_VEC_VSX PPC_VSR0_UPPER_REGNUM and PPC_VSR31_UPPER_REGNUM. (ppc_supply_vsxregset): New prototype. (ppc_collect_vsxregset): New prototype. * ppc-linux-tdep.c: Include "features/rs6000/powerpc-vsx32l.c" Include "features/rs6000/powerpc-vsx64l.c". (_initialize_ppc_linux_tdep): Initialize VSX-enabled targets. (ppc_linux_regset_sections): Add new ".reg-ppc-vsx" field. (ppc32_linux_vsxregset): New 32-bit VSX-enabled regset. (ppc_linux_regset_from_core_section): Handle VSX core section. (ppc_linux_core_read_description): Support VSX-enabled core files. * ppc-linux-tdep.h: Declare *tdesc_powerpc_vsx32l Declare tdesc_powerpc_vsx64l * corelow.c (get_core_register_section): Support VSX-enabled core files. * features/rs6000/power-vsx.xml: New VSX descriptions. * features/rs6000/powerpc-vsx32.xml: New file. * features/rs6000/powerpc-vsx32l.xml: New file. * features/rs6000/powerpc-vsx64.xml: New file. * features/rs6000/powerpc-vsx64l.xml: New file. * features/rs6000/powerpc-vsx32.c: New file (generated). * features/rs6000/powerpc-vsx32l.c: New file (generated). * features/rs6000/powerpc-vsx64.c: New file (generated). * features/rs6000/powerpc-vsx64l.c: New file (generated). * features/Makefile: Updated with new descriptions. * regformats/rs6000/powerpc-vsx32l.dat: New file (generated). * regformats/rs6000/powerpc-vsx64l.dat: New file (generated). * testsuite/gdb.arch/vsx-regs.c: New source file. * testsuite/gdb.arch/vsx-regs.exp: New testcase. * testsuite/lib/gdb.exp (skip_vsx_tests): New function.
2008-08-15 23:18:34 +08:00
}
/* The Linux kernel ptrace interface for AltiVec registers uses the
registers set mechanism, as opposed to the interface for all the
other registers, that stores/fetches each register individually. */
static void
[PowerPC] Fix access to VSCR in linux targets The 4-byte VSCR register is found inside a 16-byte field in the regset returned by ptrace and in core files. The position of VSCR depends on the endianess of the target, which was previously assumed to be big-endian for the purpose of getting VSCR. This patch removes this assumption to fix access to VSCR in little-endian mode. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-tdep.h (struct ppc_reg_offsets): Remove vector register offset fields. * ppc-fbsd-tdep.c (ppc32_fbsd_reg_offsets): Remove initializers for vector register offset fields. (ppc64_fbsd_reg_offsets): Likewise. * ppc-nbsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-nat.c (_initialize_ppcobsd_nat): Remove assignment to vector register offset fields. * rs6000-aix-tdep.c (rs6000_aix32_reg_offsets): Remove initializers for vector register offset fields. (rs6000_aix64_reg_offsets): Likewise. * rs6000-tdep.c (ppc_vrreg_offset): Remove. (ppc_supply_vrregset): Remove. (ppc_collect_vrregset): Remove. * ppc-linux-tdep.c (ppc_linux_collect_vrregset): New function. (ppc_linux_vrregset) : New function. (ppc32_le_linux_vrregmap, ppc32_be_linux_vrregmap) (ppc32_le_linux_vrregset, ppc32_be_linux_vrregset): New globals. (ppc32_linux_vrregset): Remove. (ppc_linux_iterate_over_regset_sections): Call ppc_linux_vrregset and use result instead of ppc32_linux_vrregset. (ppc32_linux_reg_offsets): Remove initializers for vector register offset fields. (ppc64_linux_reg_offsets): Likewise. * ppc-linux-tdep.h (ppc_linux_vrregset): New declaration. * ppc-linux-nat.c: Include regset.h. (gdb_vrregset_t): Adjust comment to account for little-endian mode. (supply_vrregset, fill_vrregset): Remove. (fetch_altivec_register, store_altivec_register): Remove. (fetch_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to supply registers. (store_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to collect registers. (fetch_register): Call fetch_altivec_registers instead of fetch_altivec_register. (store_register): Call store_altivec_registers instead of store_altivec_register. (fetch_ppc_registers): Call fetch_altivec_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_altivec_registers with -1 for the new regno parameter. gdb/gdbserver/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * linux-ppc-low.c (ppc_fill_vrregset): Add vscr_offset variable. Set vscr_offset to 0 in little-endian mode and 12 in big-endian mode. Call collect_register_by_name with vscr using vscr_offset. Zero-pad vscr and vrsave fields in collector buffer. (ppc_store_vrregset): Add and set vscr_offset variable as in ppc_fill_vrregset. Call supply_register_by_name with vscr using vscr_offset.
2018-05-22 22:09:05 +08:00
fetch_altivec_registers (struct regcache *regcache, int tid,
int regno)
{
int ret;
gdb_vrregset_t regs;
s/get_regcache_arch (regcache)/regcache->arch ()/g This patches removes get_regcache_arch, and use regache->arch () instead. The motivation of this change is that I am going to move some basic stuff into a base class of regcache. I don't need to update "client" code regcache->arch (). On the other hand, this patch shortens the code a little bit. gdb: 2017-10-25 Yao Qi <yao.qi@linaro.org> * aarch32-linux-nat.c (aarch32_gp_regcache_supply): Use regcache->arch () instead get_regcache_arch. * aarch64-fbsd-nat.c (aarch64_fbsd_fetch_inferior_registers): Likewise. (aarch64_fbsd_store_inferior_registers): Likewise. * aarch64-linux-nat.c (fetch_gregs_from_thread): Likewise. (store_gregs_to_thread): Likewise. (fetch_fpregs_from_thread): Likewise. (store_fpregs_to_thread): Likewise. * aarch64-tdep.c (aarch64_extract_return_value): Likewise. (aarch64_store_return_value): Likewise. (aarch64_software_single_step): Likewise. * aix-thread.c (aix_thread_wait): Likewise. (supply_reg32): Likewise. (supply_sprs64): Likewise. (supply_sprs32): Likewise. (fill_gprs64): Likewise. (fill_gprs32): Likewise. (fill_sprs64): Likewise. (fill_sprs32): Likewise. (store_regs_user_thread): Likewise. (store_regs_kernel_thread): Likewise. * alpha-bsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * alpha-tdep.c (alpha_extract_return_value): Likewise. (alpha_store_return_value): Likewise. (alpha_deal_with_atomic_sequence): Likewise. (alpha_next_pc): Likewise. (alpha_software_single_step): Likewise. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * amd64-nat.c (amd64_supply_native_gregset): Likewise. (amd64_collect_native_gregset): Likewise. * amd64-obsd-tdep.c (amd64obsd_supply_uthread): Likewise. (amd64obsd_collect_uthread): Likewise. * amd64-tdep.c (amd64_supply_fpregset): Likewise. (amd64_collect_fpregset): Likewise. (amd64_supply_fxsave): Likewise. (amd64_supply_xsave): Likewise. (amd64_collect_fxsave): Likewise. (amd64_collect_xsave): Likewise. * arc-tdep.c (arc_write_pc): Likewise. * arch-utils.c (default_skip_permanent_breakpoint): Likewise. * arm-fbsd-nat.c (arm_fbsd_fetch_inferior_registers): Likewise. (arm_fbsd_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_vfp_regs): Likewise. (store_vfp_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * arm-linux-tdep.c (arm_linux_supply_gregset): Likewise. (arm_linux_sigreturn_next_pc): Likewise. (arm_linux_get_next_pcs_syscall_next_pc): Likewise. * arm-nbsd-nat.c (arm_supply_gregset): Likewise. (fetch_register): Likewise. (store_register): Likewise. * arm-tdep.c (arm_is_thumb): Likewise. (displaced_in_arm_mode): Likewise. (bx_write_pc): Likewise. (arm_get_next_pcs_addr_bits_remove): Likewise. (arm_software_single_step): Likewise. (arm_extract_return_value): Likewise. (arm_store_return_value): Likewise. (arm_write_pc): Likewise. * bfin-tdep.c (bfin_extract_return_value): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * core-regset.c (fetch_core_registers): Likewise. * corelow.c (get_core_registers): Likewise. * cris-tdep.c (cris_store_return_value): Likewise. (cris_extract_return_value): Likewise. (find_step_target): Likewise. (find_step_target): Likewise. (cris_software_single_step): Likewise. * ctf.c (ctf_fetch_registers): Likewise. * darwin-nat.c (cancel_breakpoint): Likewise. * fbsd-tdep.c (fbsd_collect_thread_registers): Likewise. * frv-tdep.c (frv_extract_return_value): Likewise. * ft32-tdep.c (ft32_store_return_value): Likewise. (ft32_extract_return_value): Likewise. * go32-nat.c (fetch_register): Likewise. (go32_fetch_registers): Likewise. (go32_store_registers): Likewise. (store_register): Likewise. * h8300-tdep.c (h8300_extract_return_value): Likewise. (h8300_store_return_value): Likewise. * hppa-linux-nat.c (fetch_register): Likewise. (store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * i386-darwin-nat.c (i386_darwin_fetch_inferior_registers): Likewise. (i386_darwin_store_inferior_registers): Likewise. * i386-gnu-nat.c (gnu_fetch_registers): Likewise. (gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register): Likewise. (store_register): Likewise. (supply_gregset): Likewise. (fill_gregset): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. (i386_linux_resume): Likewise. * i386-linux-tdep.c (i386_linux_get_syscall_number_from_regcache): Likewise. * i386-nto-tdep.c (i386nto_supply_gregset): Likewise. * i386-obsd-nat.c (i386obsd_supply_pcb): Likewise. * i386-obsd-tdep.c (i386obsd_supply_uthread): Likewise. (i386obsd_collect_uthread): Likewise. * i386-tdep.c (i386_mmx_regnum_to_fp_regnum): Likewise. (i386_supply_gregset): Likewise. (i386_collect_gregset): Likewise. (i386_supply_fpregset): Likewise. (i386_collect_fpregset): Likewise. (i386_mpx_bd_base): Likewise. * i386-v4-nat.c (supply_fpregset): Likewise. (fill_fpregset): Likewise. * i387-tdep.c (i387_supply_fsave): Likewise. (i387_collect_fsave): Likewise. (i387_supply_fxsave): Likewise. (i387_collect_fxsave): Likewise. (i387_supply_xsave): Likewise. (i387_collect_xsave): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_registers): Likewise. * ia64-tdep.c (ia64_access_rse_reg): Likewise. (ia64_extract_return_value): Likewise. (ia64_store_return_value): Likewise. (find_func_descr): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_registers): Likewise. * infrun.c (use_displaced_stepping): Likewise. (displaced_step_prepare_throw): Likewise. (resume): Likewise. (proceed): Likewise. (do_target_wait): Likewise. (adjust_pc_after_break): Likewise. (handle_inferior_event_1): Likewise. (handle_signal_stop): Likewise. (save_infcall_suspend_state): Likewise. (restore_infcall_suspend_state): Likewise. * iq2000-tdep.c (iq2000_extract_return_value): Likewise. * jit.c (jit_frame_prev_register): Likewise. * linux-nat.c (save_stop_reason): Likewise. (linux_nat_wait_1): Likewise. (resume_stopped_resumed_lwps): Likewise. * linux-record.c (record_linux_sockaddr): Likewise. (record_linux_msghdr): Likewise. (record_linux_system_call): Likewise. * linux-tdep.c (linux_collect_thread_registers): Likewise. * lm32-tdep.c (lm32_extract_return_value): Likewise. (lm32_store_return_value): Likewise. * m32c-tdep.c (m32c_read_flg): Likewise. (m32c_pseudo_register_read): Likewise. (m32c_pseudo_register_write): Likewise. * m32r-linux-tdep.c (m32r_linux_supply_gregset): Likewise. (m32r_linux_collect_gregset): Likewise. * m32r-tdep.c (m32r_store_return_value): Likewise. (m32r_extract_return_value): Likewise. * m68k-bsd-nat.c (m68kbsd_supply_fpregset): Likewise. (m68kbsd_collect_fpregset): Likewise. * m68k-bsd-tdep.c (m68kbsd_supply_fpregset): Likewise. * m68k-linux-nat.c (fetch_register): Likewise. (old_fetch_inferior_registers): Likewise. (old_store_inferior_registers): Likewise. (store_regs): Likewise. * m68k-tdep.c (m68k_svr4_extract_return_value): Likewise. (m68k_svr4_store_return_value): Likewise. * m88k-tdep.c (m88k_store_arguments): Likewise. * mi/mi-main.c (mi_cmd_data_list_changed_registers): Likewise. (mi_cmd_data_write_register_values): Likewise. * mips-fbsd-nat.c (mips_fbsd_fetch_inferior_registers): Likewise. (mips_fbsd_store_inferior_registers): Likewise. * mips-fbsd-tdep.c (mips_fbsd_supply_fpregs): Likewise. (mips_fbsd_supply_gregs): Likewise. (mips_fbsd_collect_fpregs): Likewise. (mips_fbsd_collect_gregs): Likewise. (mips_fbsd_supply_fpregset): Likewise. (mips_fbsd_collect_fpregset): Likewise. (mips_fbsd_supply_gregset): Likewise. (mips_fbsd_collect_gregset): Likewise. * mips-linux-nat.c (supply_gregset): Likewise. (fill_gregset): Likewise. (supply_fpregset): Likewise. (fill_fpregset): Likewise. * mips-linux-tdep.c (mips_supply_gregset): Likewise. (mips_fill_gregset): Likewise. (mips_supply_fpregset): Likewise. (mips_fill_fpregset): Likewise. (mips64_supply_gregset): Likewise. (micromips_linux_sigframe_validate): Likewise. * mips-nbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * mips-nbsd-tdep.c (mipsnbsd_supply_fpregset): Likewise. (mipsnbsd_supply_gregset): Likewise. (mipsnbsd_iterate_over_regset_sections): Likewise. (mipsnbsd_supply_reg): Likewise. (mipsnbsd_supply_fpreg): Likewise. * mips-tdep.c (mips_in_frame_stub): Likewise. (mips_dummy_id): Likewise. (is_octeon_bbit_op): Likewise. (micromips_bc1_pc): Likewise. (extended_mips16_next_pc): Likewise. (mips16_next_pc): Likewise. (deal_with_atomic_sequence): Likewise. * moxie-tdep.c (moxie_process_readu): Likewise. * nios2-tdep.c (nios2_get_next_pc): Likewise. * nto-procfs.c (procfs_store_registers): Likewise. * ppc-fbsd-nat.c (ppcfbsd_fetch_inferior_registers): Likewise. (ppcfbsd_store_inferior_registers): Likewise. * ppc-linux-nat.c (fetch_vsx_register): Likewise. (fetch_altivec_register): Likewise. (get_spe_registers): Likewise. (fetch_spe_register): Likewise. (fetch_altivec_registers): Likewise. (fetch_all_gp_regs): Likewise. (fetch_all_fp_regs): Likewise. (store_vsx_register): Likewise. (store_altivec_register): Likewise. (set_spe_registers): Likewise. (store_spe_register): Likewise. (store_altivec_registers): Likewise. (store_all_gp_regs): Likewise. (store_all_fp_regs): Likewise. * ppc-linux-tdep.c (ppc_linux_supply_gregset): Likewise. (ppc_linux_collect_gregset): Likewise. (ppc_canonicalize_syscall): Likewise. (ppc_linux_record_signal): Likewise. (ppu2spu_prev_register): Likewise. * ppc-nbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-obsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * ppc-ravenscar-thread.c (ppc_ravenscar_generic_fetch_registers): Likewise. (ppc_ravenscar_generic_store_registers): Likewise. * procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ravenscar-thread.c (ravenscar_fetch_registers): Likewise. (ravenscar_store_registers): Likewise. (ravenscar_prepare_to_store): Likewise. * record-btrace.c (record_btrace_fetch_registers): Likewise. * record-full.c (record_full_wait_1): Likewise. (record_full_registers_change): Likewise. (record_full_store_registers): Likewise. (record_full_core_fetch_registers): Likewise. (record_full_save): Likewise. (record_full_goto_insn): Likewise. * regcache.c (regcache_register_size): Likewise. (get_regcache_arch): Remove. (regcache_read_pc): Likewise. * regcache.h (get_regcache_arch): Remove. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * remote.c (fetch_register_using_p): Likewise. (send_g_packet): Likewise. (remote_prepare_to_store): Likewise. (store_registers_using_G): Likewise. * reverse.c (save_bookmark_command): Likewise. (goto_bookmark_command): Likewise. * rs6000-aix-tdep.c (branch_dest): Likewise. * rs6000-nat.c (rs6000_ptrace64): Likewise. (fetch_register): Likewise. * rs6000-tdep.c (ppc_supply_reg): Likewise. (ppc_collect_reg): Likewise. (ppc_collect_gregset): Likewise. (ppc_collect_fpregset): Likewise. (ppc_collect_vsxregset): Likewise. (ppc_collect_vrregset): Likewise. (ppc_displaced_step_hw_singlestep): Likewise. (rs6000_pseudo_register_read): Likewise. (rs6000_pseudo_register_write): Likewise. * s390-linux-nat.c (supply_gregset): Likewise. (fill_gregset): Likewise. (s390_linux_fetch_inferior_registers): Likewise. * s390-linux-tdep.c (s390_write_pc): Likewise. (s390_software_single_step): Likewise. (s390_all_but_pc_registers_record): Likewise. (s390_linux_syscall_record): Likewise. * sentinel-frame.c (sentinel_frame_prev_arch): Likewise. * sh-nbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sh-tdep.c (sh_extract_return_value_nofpu): Likewise. (sh_extract_return_value_fpu): Likewise. (sh_store_return_value_nofpu): Likewise. (sh_corefile_supply_regset): Likewise. (sh_corefile_collect_regset): Likewise. * sh64-tdep.c (sh64_extract_return_value): Likewise. (sh64_store_return_value): Likewise. * sparc-linux-tdep.c (sparc32_linux_collect_core_fpregset): Likewise. * sparc-nat.c (sparc_fetch_inferior_registers): Likewise. (sparc_store_inferior_registers): Likewise. * sparc-ravenscar-thread.c (register_in_thread_descriptor_p): Likewise. (sparc_ravenscar_prepare_to_store): Likewise. * sparc-tdep.c (sparc32_store_arguments): Likewise. (sparc_analyze_control_transfer): Likewise. (sparc_step_trap): Likewise. (sparc_software_single_step): Likewise. (sparc32_gdbarch_init): Likewise. (sparc_supply_rwindow): Likewise. (sparc_collect_rwindow): Likewise. * sparc64-linux-tdep.c (sparc64_linux_collect_core_fpregset): Likewise. * sparc64-nbsd-nat.c (sparc64nbsd_supply_gregset): Likewise. (sparc64nbsd_collect_gregset): Likewise. (sparc64nbsd_supply_fpregset): Likewise. (sparc64nbsd_collect_fpregset): Likewise. * sparc64-tdep.c (sparc64_store_arguments): Likewise. (sparc64_supply_gregset): Likewise. (sparc64_collect_gregset): Likewise. (sparc64_supply_fpregset): Likewise. (sparc64_collect_fpregset): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. * spu-tdep.c (spu_unwind_sp): Likewise. (spu2ppu_prev_register): Likewise. (spu_memory_remove_breakpoint): Likewise. * stack.c (return_command): Likewise. * tic6x-tdep.c (tic6x_extract_signed_field): Likewise. * tracefile-tfile.c (tfile_fetch_registers): Likewise. * tracefile.c (trace_save_ctf): Likewise. * windows-nat.c (do_windows_fetch_inferior_registers): Likewise. (do_windows_store_inferior_registers): Likewise. (windows_resume): Likewise. * xtensa-linux-nat.c (fill_gregset): Likewise. (supply_gregset_reg): Likewise. * xtensa-tdep.c (xtensa_register_write_masked): Likewise. (xtensa_register_read_masked): Likewise. (xtensa_supply_gregset): Likewise. (xtensa_extract_return_value): Likewise. (xtensa_store_return_value): Likewise.
2017-10-25 23:37:03 +08:00
struct gdbarch *gdbarch = regcache->arch ();
[PowerPC] Fix access to VSCR in linux targets The 4-byte VSCR register is found inside a 16-byte field in the regset returned by ptrace and in core files. The position of VSCR depends on the endianess of the target, which was previously assumed to be big-endian for the purpose of getting VSCR. This patch removes this assumption to fix access to VSCR in little-endian mode. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-tdep.h (struct ppc_reg_offsets): Remove vector register offset fields. * ppc-fbsd-tdep.c (ppc32_fbsd_reg_offsets): Remove initializers for vector register offset fields. (ppc64_fbsd_reg_offsets): Likewise. * ppc-nbsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-nat.c (_initialize_ppcobsd_nat): Remove assignment to vector register offset fields. * rs6000-aix-tdep.c (rs6000_aix32_reg_offsets): Remove initializers for vector register offset fields. (rs6000_aix64_reg_offsets): Likewise. * rs6000-tdep.c (ppc_vrreg_offset): Remove. (ppc_supply_vrregset): Remove. (ppc_collect_vrregset): Remove. * ppc-linux-tdep.c (ppc_linux_collect_vrregset): New function. (ppc_linux_vrregset) : New function. (ppc32_le_linux_vrregmap, ppc32_be_linux_vrregmap) (ppc32_le_linux_vrregset, ppc32_be_linux_vrregset): New globals. (ppc32_linux_vrregset): Remove. (ppc_linux_iterate_over_regset_sections): Call ppc_linux_vrregset and use result instead of ppc32_linux_vrregset. (ppc32_linux_reg_offsets): Remove initializers for vector register offset fields. (ppc64_linux_reg_offsets): Likewise. * ppc-linux-tdep.h (ppc_linux_vrregset): New declaration. * ppc-linux-nat.c: Include regset.h. (gdb_vrregset_t): Adjust comment to account for little-endian mode. (supply_vrregset, fill_vrregset): Remove. (fetch_altivec_register, store_altivec_register): Remove. (fetch_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to supply registers. (store_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to collect registers. (fetch_register): Call fetch_altivec_registers instead of fetch_altivec_register. (store_register): Call store_altivec_registers instead of store_altivec_register. (fetch_ppc_registers): Call fetch_altivec_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_altivec_registers with -1 for the new regno parameter. gdb/gdbserver/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * linux-ppc-low.c (ppc_fill_vrregset): Add vscr_offset variable. Set vscr_offset to 0 in little-endian mode and 12 in big-endian mode. Call collect_register_by_name with vscr using vscr_offset. Zero-pad vscr and vrsave fields in collector buffer. (ppc_store_vrregset): Add and set vscr_offset variable as in ppc_fill_vrregset. Call supply_register_by_name with vscr using vscr_offset.
2018-05-22 22:09:05 +08:00
const struct regset *vrregset = ppc_linux_vrregset (gdbarch);
ret = ptrace (PTRACE_GETVRREGS, tid, 0, &regs);
if (ret < 0)
{
if (errno == EIO)
{
have_ptrace_getvrregs = 0;
return;
}
[PowerPC] Fix access to VSCR in linux targets The 4-byte VSCR register is found inside a 16-byte field in the regset returned by ptrace and in core files. The position of VSCR depends on the endianess of the target, which was previously assumed to be big-endian for the purpose of getting VSCR. This patch removes this assumption to fix access to VSCR in little-endian mode. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-tdep.h (struct ppc_reg_offsets): Remove vector register offset fields. * ppc-fbsd-tdep.c (ppc32_fbsd_reg_offsets): Remove initializers for vector register offset fields. (ppc64_fbsd_reg_offsets): Likewise. * ppc-nbsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-nat.c (_initialize_ppcobsd_nat): Remove assignment to vector register offset fields. * rs6000-aix-tdep.c (rs6000_aix32_reg_offsets): Remove initializers for vector register offset fields. (rs6000_aix64_reg_offsets): Likewise. * rs6000-tdep.c (ppc_vrreg_offset): Remove. (ppc_supply_vrregset): Remove. (ppc_collect_vrregset): Remove. * ppc-linux-tdep.c (ppc_linux_collect_vrregset): New function. (ppc_linux_vrregset) : New function. (ppc32_le_linux_vrregmap, ppc32_be_linux_vrregmap) (ppc32_le_linux_vrregset, ppc32_be_linux_vrregset): New globals. (ppc32_linux_vrregset): Remove. (ppc_linux_iterate_over_regset_sections): Call ppc_linux_vrregset and use result instead of ppc32_linux_vrregset. (ppc32_linux_reg_offsets): Remove initializers for vector register offset fields. (ppc64_linux_reg_offsets): Likewise. * ppc-linux-tdep.h (ppc_linux_vrregset): New declaration. * ppc-linux-nat.c: Include regset.h. (gdb_vrregset_t): Adjust comment to account for little-endian mode. (supply_vrregset, fill_vrregset): Remove. (fetch_altivec_register, store_altivec_register): Remove. (fetch_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to supply registers. (store_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to collect registers. (fetch_register): Call fetch_altivec_registers instead of fetch_altivec_register. (store_register): Call store_altivec_registers instead of store_altivec_register. (fetch_ppc_registers): Call fetch_altivec_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_altivec_registers with -1 for the new regno parameter. gdb/gdbserver/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * linux-ppc-low.c (ppc_fill_vrregset): Add vscr_offset variable. Set vscr_offset to 0 in little-endian mode and 12 in big-endian mode. Call collect_register_by_name with vscr using vscr_offset. Zero-pad vscr and vrsave fields in collector buffer. (ppc_store_vrregset): Add and set vscr_offset variable as in ppc_fill_vrregset. Call supply_register_by_name with vscr using vscr_offset.
2018-05-22 22:09:05 +08:00
perror_with_name (_("Unable to fetch AltiVec registers"));
}
[PowerPC] Fix access to VSCR in linux targets The 4-byte VSCR register is found inside a 16-byte field in the regset returned by ptrace and in core files. The position of VSCR depends on the endianess of the target, which was previously assumed to be big-endian for the purpose of getting VSCR. This patch removes this assumption to fix access to VSCR in little-endian mode. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-tdep.h (struct ppc_reg_offsets): Remove vector register offset fields. * ppc-fbsd-tdep.c (ppc32_fbsd_reg_offsets): Remove initializers for vector register offset fields. (ppc64_fbsd_reg_offsets): Likewise. * ppc-nbsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-nat.c (_initialize_ppcobsd_nat): Remove assignment to vector register offset fields. * rs6000-aix-tdep.c (rs6000_aix32_reg_offsets): Remove initializers for vector register offset fields. (rs6000_aix64_reg_offsets): Likewise. * rs6000-tdep.c (ppc_vrreg_offset): Remove. (ppc_supply_vrregset): Remove. (ppc_collect_vrregset): Remove. * ppc-linux-tdep.c (ppc_linux_collect_vrregset): New function. (ppc_linux_vrregset) : New function. (ppc32_le_linux_vrregmap, ppc32_be_linux_vrregmap) (ppc32_le_linux_vrregset, ppc32_be_linux_vrregset): New globals. (ppc32_linux_vrregset): Remove. (ppc_linux_iterate_over_regset_sections): Call ppc_linux_vrregset and use result instead of ppc32_linux_vrregset. (ppc32_linux_reg_offsets): Remove initializers for vector register offset fields. (ppc64_linux_reg_offsets): Likewise. * ppc-linux-tdep.h (ppc_linux_vrregset): New declaration. * ppc-linux-nat.c: Include regset.h. (gdb_vrregset_t): Adjust comment to account for little-endian mode. (supply_vrregset, fill_vrregset): Remove. (fetch_altivec_register, store_altivec_register): Remove. (fetch_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to supply registers. (store_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to collect registers. (fetch_register): Call fetch_altivec_registers instead of fetch_altivec_register. (store_register): Call store_altivec_registers instead of store_altivec_register. (fetch_ppc_registers): Call fetch_altivec_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_altivec_registers with -1 for the new regno parameter. gdb/gdbserver/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * linux-ppc-low.c (ppc_fill_vrregset): Add vscr_offset variable. Set vscr_offset to 0 in little-endian mode and 12 in big-endian mode. Call collect_register_by_name with vscr using vscr_offset. Zero-pad vscr and vrsave fields in collector buffer. (ppc_store_vrregset): Add and set vscr_offset variable as in ppc_fill_vrregset. Call supply_register_by_name with vscr using vscr_offset.
2018-05-22 22:09:05 +08:00
vrregset->supply_regset (vrregset, regcache, regno, &regs,
PPC_LINUX_SIZEOF_VRREGSET);
}
/* Fetch the top 32 bits of TID's general-purpose registers and the
SPE-specific registers, and place the results in EVRREGSET. If we
don't support PTRACE_GETEVRREGS, then just fill EVRREGSET with
zeros.
All the logic to deal with whether or not the PTRACE_GETEVRREGS and
PTRACE_SETEVRREGS requests are supported is isolated here, and in
set_spe_registers. */
static void
get_spe_registers (int tid, struct gdb_evrregset_t *evrregset)
{
if (have_ptrace_getsetevrregs)
{
if (ptrace (PTRACE_GETEVRREGS, tid, 0, evrregset) >= 0)
return;
else
{
/* EIO means that the PTRACE_GETEVRREGS request isn't supported;
we just return zeros. */
if (errno == EIO)
have_ptrace_getsetevrregs = 0;
else
/* Anything else needs to be reported. */
2005-02-11 Andrew Cagney <cagney@gnu.org> Mark up error_no_arg, query, perror_with_name, complaint, and internal_error. * breakpoint.c, cp-abi.c, cp-namespace.c, cp-support.c: Update. * cris-tdep.c, dbxread.c, dictionary.c, dsrec.c: Update. * dummy-frame.c, dve3900-rom.c, dwarf2-frame.c, dwarf2expr.c: Update. * dwarf2read.c, dwarfread.c, elfread.c, event-loop.c: Update. * exceptions.c, exec.c, f-lang.c, findvar.c, fork-child.c: Update. * frame-unwind.c, frame.c, frv-linux-tdep.c, frv-tdep.c: Update. * gdb_assert.h, gdbarch.c, gdbtypes.c, gnu-nat.c: Update. * go32-nat.c, hppa-tdep.c, hppabsd-nat.c, hpread.c: Update. * i386-linux-nat.c, i386-nat.c, i386-tdep.c, i386bsd-nat.c: Update. * i386fbsd-nat.c, inf-ptrace.c, inf-ttrace.c, infcall.c: Update. * infcmd.c, inflow.c, infptrace.c, infrun.c, inftarg.c: Update. * interps.c, language.c, linespec.c, linux-nat.c: Update. * m32r-linux-nat.c, m68k-tdep.c, m68kbsd-nat.c: Update. * m68klinux-nat.c, m88kbsd-nat.c, macroexp.c, macroscope.c: Update. * macrotab.c, maint.c, mdebugread.c, memattr.c: Update. * mips-linux-tdep.c, mips-tdep.c, mips64obsd-nat.c: Update. * mipsnbsd-nat.c, mn10300-tdep.c, monitor.c, nto-procfs.c: Update. * objc-lang.c, objfiles.c, objfiles.h, ocd.c, osabi.c: Update. * parse.c, ppc-bdm.c, ppc-linux-nat.c, ppc-sysv-tdep.c: Update. * ppcnbsd-nat.c, ppcobsd-nat.c, printcmd.c, procfs.c: Update. * regcache.c, reggroups.c, remote-e7000.c, remote-mips.c: Update. * remote-rdp.c, remote-sds.c, remote-sim.c, remote-st.c: Update. * remote-utils.c, remote.c, rs6000-nat.c, rs6000-tdep.c: Update. * s390-nat.c, s390-tdep.c, sentinel-frame.c, serial.c: Update. * sh-tdep.c, sh3-rom.c, sh64-tdep.c, shnbsd-nat.c: Update. * solib-aix5.c, solib-svr4.c, solib.c, source.c: Update. * sparc-nat.c, stabsread.c, stack.c, symfile.c, symtab.c: Update. * symtab.h, target.c, tracepoint.c, ui-file.c, ui-out.c: Update. * utils.c, valops.c, valprint.c, vax-nat.c, vaxbsd-nat.c: Update. * win32-nat.c, xcoffread.c, xstormy16-tdep.c: Update. * cli/cli-cmds.c, cli/cli-logging.c, cli/cli-script.c: Update. * cli/cli-setshow.c, mi/mi-cmd-break.c, mi/mi-cmds.c: Update. * mi/mi-console.c, mi/mi-getopt.c, mi/mi-out.c: Update. * tui/tui-file.c, tui/tui-interp.c: Update.
2005-02-12 02:13:55 +08:00
perror_with_name (_("Unable to fetch SPE registers"));
}
}
memset (evrregset, 0, sizeof (*evrregset));
}
Change the layout of the PowerPC E500 raw register cache to allow the lower 32-bit halves of the GPRS to be their own raw registers, not pseudoregisters. * ppc-tdep.h (struct gdbarch_tdep): Remove ppc_gprs_pseudo_p flag; add ppc_ev0_upper_regnum flag. * rs6000-tdep.c: #include "reggroups.h". (spe_register_p): Recognize the ev upper half registers as SPE registers. (init_sim_regno_table): Build gdb->sim mappings for the upper-half registers. (e500_move_ev_register): New function. (e500_pseudo_register_read, e500_pseudo_register_write): The 'ev' vector registers are the pseudo-registers now, formed by splicing together the gprs and the upper-half registers. (e500_register_reggroup_p): New function. (P): Macro deleted. (P8, A4): New macro. (PPC_EV_REGS, PPC_GPRS_PSEUDO_REGS): Macros deleted. (PPC_SPE_GP_REGS, PPC_SPE_UPPER_GP_REGS, PPC_EV_PSEUDO_REGS): New macros. (registers_e500): Rearrange register set so that the raw register set contains 32-bit GPRs and upper-half registers, and the SPE vector registers become pseudo-registers. (rs6000_gdbarch_init): Don't initialize tdep->ppc_gprs_pseudo_p; it has been deleted. Initialize ppc_ev0_upper_regnum. Many other register numbers are now the same for the E500 as they are for other PowerPC variants. Register e500_register_reggroup_p as the register group function for the E500. * Makefile.in (rs6000-tdep.o): Update dependencies. Adapt PPC E500 native support to the new raw regcache layout. * ppc-linux-nat.c (struct gdb_evrregset_t): Doc fixes. (read_spliced_spe_reg, write_spliced_spe_reg): Deleted. (fetch_spe_register, store_spe_register): Handle fetching/storing all the SPE registers at once, if regno == -1. These now take over the job of fetch_spe_registers and store_spe_registers. (fetch_spe_registers, store_spe_registers): Deleted. (fetch_ppc_registers, store_ppc_registers): Fetch/store gprs unconditionally; they're always raw. Fetch/store SPE upper half registers, if present, instead of ev registers. (fetch_register, store_register): Remove sanity checks: gprs are never pseudo-registers now, so we never need to even mention any registers that are ever pseudoregisters.
2004-08-05 01:17:55 +08:00
/* Supply values from TID for SPE-specific raw registers: the upper
halves of the GPRs, the accumulator, and the spefscr. REGNO must
be the number of an upper half register, acc, spefscr, or -1 to
supply the values of all registers. */
static void
* target.h (struct regcache): Add forward declaration. (struct target_ops): Add REGCACHE parameter to to_fetch_registers and to_store_registers target operations. (target_fetch_registers, target_store_registers): Update. * regcache.c (regcache_raw_read): Replace register_cached by regcache_valid_p. Pass regcache to target_fetch_registers. (regcache_raw_write): Pass regcache to target_store_registers. * arm-linux-nat.c (store_fpregister, store_fpregs, store_register, store_regs, store_wmmx_regs): Replace register_cached by regcache_valid_p. * bsd-kvm.c (bsd_kvm_open, bsd_kvm_proc_cmd): Pass current_regcache to target_fetch_registers calls. * corelow.c (core_open): Likewise. * linux-nat.c (linux_nat_corefile_thread_callback): Likewise. * proc-service.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * sol-thread.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * win32-nat.c (win32_resume): Likewise. * ia64-tdep.c (ia64_store_return_value): Pass current_regcache to target_store_registers call. * rs6000-tdep.c (rs6000_push_dummy_call): Likewise. * inferior.h (store_inferior_registers): Update prototype. (fetch_inferior_registers): Likewise. * gnu-nat.c (gnu_store_registers, gnu_fetch_registers): Likewise. * mips-linux-nat.c (super_fetch_registers, super_store_registers): Update function pointer signatures. * aix-thread.c (aix_thread_fetch_registers): Add REGCACHE parameter, use it instead of current_regcache, update calls. (aix_thread_store_registers): Likewise. * alphabsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * amd64bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_fpregister, fetch_fpregs, store_fpregister, store_fpregs, fetch_register, fetch_regs, store_register, store_regs, fetch_wmmx_regs, store_wmmx_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * armnbsd-nat.c (fetch_register, fetch_regs, fetch_fp_register, fetch_fp_regs, armnbsd_fetch_registers): Likewise. (store_register, store_regs, store_fp_register, store_fp_regs, armnbsd_store_registers): Likewise. * bsd-kvm.c (bsd_kvm_fetch_pcb, bsd_kvm_fetch_registers): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * corelow.c (get_core_registers): Likewise. * go32-nat.c (fetch_register, go32_fetch_registers, store_register, go32_store_registers): Likewise. * hppabsd-nat.c (hppabsd_fetch_registers): Likewise. (hppabsd_store_registers): Likewise. * hppa-hpux-nat.c (hppa_hpux_fetch_register): Likewise. (hppa_hpux_fetch_inferior_registers): Likewise. (hppa_hpux_store_register): Likewise. (hppa_hpux_store_inferior_registers): Likewise. * hppa-linux-nat.c (fetch_register, store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * hpux-thread.c (hpux_thread_fetch_registers): Likewise. (hpux_thread_store_registers): Likewise. * i386bsd-nat.c (i386bsd_fetch_inferior_registers): Likewise. (i386bsd_store_inferior_registers): Likewise. * i386gnu-nat.c (fetch_fpregs, gnu_fetch_registers, store_fpregs, gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register, store_register, fetch_regs, store_regs, fetch_fpregs, store_fpregs, fetch_fpxregs, store_fpxregs): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_register): Likewise. (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_register): Likewise. (ia64_linux_store_registers): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. (inf_child_store_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register): Likewise. (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_register): Likewise. (inf_ptrace_store_registers): Likewise. * infptrace.c (fetch_register, store_register): Likewise. (fetch_inferior_registers, store_inferior_registers): Likewise. * m32r-linux-nat.c (fetch_regs, store_regs): Likewise. (m32r_linux_fetch_inferior_registers): Likewise. (m32r_linux_store_inferior_registers): Likewise. * m68kbsd-nat.c (m68kbsd_fetch_inferior_registers): Likewise. (m68kbsd_store_inferior_registers): Likewise. * m68klinux-nat.c (fetch_register, old_fetch_inferior_registers, store_register, old_store_inferior_registers, fetch_regs, store_regs, fetch_fpregs, store_fpregs): Likewise. (m68k_linux_fetch_inferior_registers): Likewise. (m68k_linux_store_inferior_registers): Likewise. * m88kbsd-nat.c (m88kbsd_fetch_inferior_registers): Likewise. (m88kbsd_store_inferior_registers): Likewise. * mips64obsd-nat.c (mips64obsd_fetch_inferior_registers): Likewise. (mips64obsd_store_inferior_registers): Likewise. * mips-linux-nat.c (mips64_linux_regsets_fetch_registers): Likewise. (mips64_linux_regsets_store_registers): Likewise. (mips64_linux_fetch_registers): Likewise. (mips64_linux_store_registers): Likewise. * mipsnbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * monitor.c (monitor_fetch_register, monitor_store_register): Likewise. (monitor_fetch_registers, monitor_store_registers): Likewise. * nto-procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register, fetch_register, supply_vrregset, fetch_altivec_registers, fetch_ppc_registers, ppc_linux_fetch_inferior_registers): Likewise. (store_altivec_register, store_spe_register, store_register, fill_vrregset, store_altivec_registers, store_ppc_registers, ppc_linux_store_inferior_registers): Likewise. * ppcnbsd-nat.c (ppcnbsd_fetch_inferior_registers): Likewise. (ppcnbsd_store_inferior_registers): Likewise. * ppcobsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote.c (fetch_register_using_p, process_g_packet, fetch_registers_using_g, remote_fetch_registers): Likewise. (store_register_using_P, store_registers_using_G, remote_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers, m32r_fetch_register, m32r_store_register, m32r_store_register): Likewise. * remote-mips.c (mips_fetch_registers, mips_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * rs6000-nat.c (fetch_register, store_register): Likewise. (rs6000_fetch_inferior_registers): Likewise. (rs6000_store_inferior_registers): Likewise. * s390-nat.c (fetch_regs, store_regs): Likewise. (fetch_fpregs, store_fpregs): Likewise. (s390_linux_fetch_inferior_registers): Likewise. (s390_linux_store_inferior_registers): Likewise. * shnbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sol-thread.c (sol_thread_fetch_registers): Likewise. (sol_thread_store_registers): Likewise. * sparc-nat.c (fetch_inferior_registers): Likewise. (store_inferior_registers): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. (spu_store_inferior_registers): Likewise. * target.c (debug_print_register): Likewise. (debug_to_fetch_registers, debug_to_store_registers): Likewise. * vaxbsd-nat.c (vaxbsd_fetch_inferior_registers): Likewise. (vaxbsd_store_inferior_registers): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers): Likewise. (win32_fetch_inferior_registers): Likewise. (win32_store_inferior_registers): Likewise.
2007-05-06 22:34:38 +08:00
fetch_spe_register (struct regcache *regcache, int tid, int regno)
{
s/get_regcache_arch (regcache)/regcache->arch ()/g This patches removes get_regcache_arch, and use regache->arch () instead. The motivation of this change is that I am going to move some basic stuff into a base class of regcache. I don't need to update "client" code regcache->arch (). On the other hand, this patch shortens the code a little bit. gdb: 2017-10-25 Yao Qi <yao.qi@linaro.org> * aarch32-linux-nat.c (aarch32_gp_regcache_supply): Use regcache->arch () instead get_regcache_arch. * aarch64-fbsd-nat.c (aarch64_fbsd_fetch_inferior_registers): Likewise. (aarch64_fbsd_store_inferior_registers): Likewise. * aarch64-linux-nat.c (fetch_gregs_from_thread): Likewise. (store_gregs_to_thread): Likewise. (fetch_fpregs_from_thread): Likewise. (store_fpregs_to_thread): Likewise. * aarch64-tdep.c (aarch64_extract_return_value): Likewise. (aarch64_store_return_value): Likewise. (aarch64_software_single_step): Likewise. * aix-thread.c (aix_thread_wait): Likewise. (supply_reg32): Likewise. (supply_sprs64): Likewise. (supply_sprs32): Likewise. (fill_gprs64): Likewise. (fill_gprs32): Likewise. (fill_sprs64): Likewise. (fill_sprs32): Likewise. (store_regs_user_thread): Likewise. (store_regs_kernel_thread): Likewise. * alpha-bsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * alpha-tdep.c (alpha_extract_return_value): Likewise. (alpha_store_return_value): Likewise. (alpha_deal_with_atomic_sequence): Likewise. (alpha_next_pc): Likewise. (alpha_software_single_step): Likewise. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * amd64-nat.c (amd64_supply_native_gregset): Likewise. (amd64_collect_native_gregset): Likewise. * amd64-obsd-tdep.c (amd64obsd_supply_uthread): Likewise. (amd64obsd_collect_uthread): Likewise. * amd64-tdep.c (amd64_supply_fpregset): Likewise. (amd64_collect_fpregset): Likewise. (amd64_supply_fxsave): Likewise. (amd64_supply_xsave): Likewise. (amd64_collect_fxsave): Likewise. (amd64_collect_xsave): Likewise. * arc-tdep.c (arc_write_pc): Likewise. * arch-utils.c (default_skip_permanent_breakpoint): Likewise. * arm-fbsd-nat.c (arm_fbsd_fetch_inferior_registers): Likewise. (arm_fbsd_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_vfp_regs): Likewise. (store_vfp_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * arm-linux-tdep.c (arm_linux_supply_gregset): Likewise. (arm_linux_sigreturn_next_pc): Likewise. (arm_linux_get_next_pcs_syscall_next_pc): Likewise. * arm-nbsd-nat.c (arm_supply_gregset): Likewise. (fetch_register): Likewise. (store_register): Likewise. * arm-tdep.c (arm_is_thumb): Likewise. (displaced_in_arm_mode): Likewise. (bx_write_pc): Likewise. (arm_get_next_pcs_addr_bits_remove): Likewise. (arm_software_single_step): Likewise. (arm_extract_return_value): Likewise. (arm_store_return_value): Likewise. (arm_write_pc): Likewise. * bfin-tdep.c (bfin_extract_return_value): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * core-regset.c (fetch_core_registers): Likewise. * corelow.c (get_core_registers): Likewise. * cris-tdep.c (cris_store_return_value): Likewise. (cris_extract_return_value): Likewise. (find_step_target): Likewise. (find_step_target): Likewise. (cris_software_single_step): Likewise. * ctf.c (ctf_fetch_registers): Likewise. * darwin-nat.c (cancel_breakpoint): Likewise. * fbsd-tdep.c (fbsd_collect_thread_registers): Likewise. * frv-tdep.c (frv_extract_return_value): Likewise. * ft32-tdep.c (ft32_store_return_value): Likewise. (ft32_extract_return_value): Likewise. * go32-nat.c (fetch_register): Likewise. (go32_fetch_registers): Likewise. (go32_store_registers): Likewise. (store_register): Likewise. * h8300-tdep.c (h8300_extract_return_value): Likewise. (h8300_store_return_value): Likewise. * hppa-linux-nat.c (fetch_register): Likewise. (store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * i386-darwin-nat.c (i386_darwin_fetch_inferior_registers): Likewise. (i386_darwin_store_inferior_registers): Likewise. * i386-gnu-nat.c (gnu_fetch_registers): Likewise. (gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register): Likewise. (store_register): Likewise. (supply_gregset): Likewise. (fill_gregset): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. (i386_linux_resume): Likewise. * i386-linux-tdep.c (i386_linux_get_syscall_number_from_regcache): Likewise. * i386-nto-tdep.c (i386nto_supply_gregset): Likewise. * i386-obsd-nat.c (i386obsd_supply_pcb): Likewise. * i386-obsd-tdep.c (i386obsd_supply_uthread): Likewise. (i386obsd_collect_uthread): Likewise. * i386-tdep.c (i386_mmx_regnum_to_fp_regnum): Likewise. (i386_supply_gregset): Likewise. (i386_collect_gregset): Likewise. (i386_supply_fpregset): Likewise. (i386_collect_fpregset): Likewise. (i386_mpx_bd_base): Likewise. * i386-v4-nat.c (supply_fpregset): Likewise. (fill_fpregset): Likewise. * i387-tdep.c (i387_supply_fsave): Likewise. (i387_collect_fsave): Likewise. (i387_supply_fxsave): Likewise. (i387_collect_fxsave): Likewise. (i387_supply_xsave): Likewise. (i387_collect_xsave): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_registers): Likewise. * ia64-tdep.c (ia64_access_rse_reg): Likewise. (ia64_extract_return_value): Likewise. (ia64_store_return_value): Likewise. (find_func_descr): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_registers): Likewise. * infrun.c (use_displaced_stepping): Likewise. (displaced_step_prepare_throw): Likewise. (resume): Likewise. (proceed): Likewise. (do_target_wait): Likewise. (adjust_pc_after_break): Likewise. (handle_inferior_event_1): Likewise. (handle_signal_stop): Likewise. (save_infcall_suspend_state): Likewise. (restore_infcall_suspend_state): Likewise. * iq2000-tdep.c (iq2000_extract_return_value): Likewise. * jit.c (jit_frame_prev_register): Likewise. * linux-nat.c (save_stop_reason): Likewise. (linux_nat_wait_1): Likewise. (resume_stopped_resumed_lwps): Likewise. * linux-record.c (record_linux_sockaddr): Likewise. (record_linux_msghdr): Likewise. (record_linux_system_call): Likewise. * linux-tdep.c (linux_collect_thread_registers): Likewise. * lm32-tdep.c (lm32_extract_return_value): Likewise. (lm32_store_return_value): Likewise. * m32c-tdep.c (m32c_read_flg): Likewise. (m32c_pseudo_register_read): Likewise. (m32c_pseudo_register_write): Likewise. * m32r-linux-tdep.c (m32r_linux_supply_gregset): Likewise. (m32r_linux_collect_gregset): Likewise. * m32r-tdep.c (m32r_store_return_value): Likewise. (m32r_extract_return_value): Likewise. * m68k-bsd-nat.c (m68kbsd_supply_fpregset): Likewise. (m68kbsd_collect_fpregset): Likewise. * m68k-bsd-tdep.c (m68kbsd_supply_fpregset): Likewise. * m68k-linux-nat.c (fetch_register): Likewise. (old_fetch_inferior_registers): Likewise. (old_store_inferior_registers): Likewise. (store_regs): Likewise. * m68k-tdep.c (m68k_svr4_extract_return_value): Likewise. (m68k_svr4_store_return_value): Likewise. * m88k-tdep.c (m88k_store_arguments): Likewise. * mi/mi-main.c (mi_cmd_data_list_changed_registers): Likewise. (mi_cmd_data_write_register_values): Likewise. * mips-fbsd-nat.c (mips_fbsd_fetch_inferior_registers): Likewise. (mips_fbsd_store_inferior_registers): Likewise. * mips-fbsd-tdep.c (mips_fbsd_supply_fpregs): Likewise. (mips_fbsd_supply_gregs): Likewise. (mips_fbsd_collect_fpregs): Likewise. (mips_fbsd_collect_gregs): Likewise. (mips_fbsd_supply_fpregset): Likewise. (mips_fbsd_collect_fpregset): Likewise. (mips_fbsd_supply_gregset): Likewise. (mips_fbsd_collect_gregset): Likewise. * mips-linux-nat.c (supply_gregset): Likewise. (fill_gregset): Likewise. (supply_fpregset): Likewise. (fill_fpregset): Likewise. * mips-linux-tdep.c (mips_supply_gregset): Likewise. (mips_fill_gregset): Likewise. (mips_supply_fpregset): Likewise. (mips_fill_fpregset): Likewise. (mips64_supply_gregset): Likewise. (micromips_linux_sigframe_validate): Likewise. * mips-nbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * mips-nbsd-tdep.c (mipsnbsd_supply_fpregset): Likewise. (mipsnbsd_supply_gregset): Likewise. (mipsnbsd_iterate_over_regset_sections): Likewise. (mipsnbsd_supply_reg): Likewise. (mipsnbsd_supply_fpreg): Likewise. * mips-tdep.c (mips_in_frame_stub): Likewise. (mips_dummy_id): Likewise. (is_octeon_bbit_op): Likewise. (micromips_bc1_pc): Likewise. (extended_mips16_next_pc): Likewise. (mips16_next_pc): Likewise. (deal_with_atomic_sequence): Likewise. * moxie-tdep.c (moxie_process_readu): Likewise. * nios2-tdep.c (nios2_get_next_pc): Likewise. * nto-procfs.c (procfs_store_registers): Likewise. * ppc-fbsd-nat.c (ppcfbsd_fetch_inferior_registers): Likewise. (ppcfbsd_store_inferior_registers): Likewise. * ppc-linux-nat.c (fetch_vsx_register): Likewise. (fetch_altivec_register): Likewise. (get_spe_registers): Likewise. (fetch_spe_register): Likewise. (fetch_altivec_registers): Likewise. (fetch_all_gp_regs): Likewise. (fetch_all_fp_regs): Likewise. (store_vsx_register): Likewise. (store_altivec_register): Likewise. (set_spe_registers): Likewise. (store_spe_register): Likewise. (store_altivec_registers): Likewise. (store_all_gp_regs): Likewise. (store_all_fp_regs): Likewise. * ppc-linux-tdep.c (ppc_linux_supply_gregset): Likewise. (ppc_linux_collect_gregset): Likewise. (ppc_canonicalize_syscall): Likewise. (ppc_linux_record_signal): Likewise. (ppu2spu_prev_register): Likewise. * ppc-nbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-obsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * ppc-ravenscar-thread.c (ppc_ravenscar_generic_fetch_registers): Likewise. (ppc_ravenscar_generic_store_registers): Likewise. * procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ravenscar-thread.c (ravenscar_fetch_registers): Likewise. (ravenscar_store_registers): Likewise. (ravenscar_prepare_to_store): Likewise. * record-btrace.c (record_btrace_fetch_registers): Likewise. * record-full.c (record_full_wait_1): Likewise. (record_full_registers_change): Likewise. (record_full_store_registers): Likewise. (record_full_core_fetch_registers): Likewise. (record_full_save): Likewise. (record_full_goto_insn): Likewise. * regcache.c (regcache_register_size): Likewise. (get_regcache_arch): Remove. (regcache_read_pc): Likewise. * regcache.h (get_regcache_arch): Remove. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * remote.c (fetch_register_using_p): Likewise. (send_g_packet): Likewise. (remote_prepare_to_store): Likewise. (store_registers_using_G): Likewise. * reverse.c (save_bookmark_command): Likewise. (goto_bookmark_command): Likewise. * rs6000-aix-tdep.c (branch_dest): Likewise. * rs6000-nat.c (rs6000_ptrace64): Likewise. (fetch_register): Likewise. * rs6000-tdep.c (ppc_supply_reg): Likewise. (ppc_collect_reg): Likewise. (ppc_collect_gregset): Likewise. (ppc_collect_fpregset): Likewise. (ppc_collect_vsxregset): Likewise. (ppc_collect_vrregset): Likewise. (ppc_displaced_step_hw_singlestep): Likewise. (rs6000_pseudo_register_read): Likewise. (rs6000_pseudo_register_write): Likewise. * s390-linux-nat.c (supply_gregset): Likewise. (fill_gregset): Likewise. (s390_linux_fetch_inferior_registers): Likewise. * s390-linux-tdep.c (s390_write_pc): Likewise. (s390_software_single_step): Likewise. (s390_all_but_pc_registers_record): Likewise. (s390_linux_syscall_record): Likewise. * sentinel-frame.c (sentinel_frame_prev_arch): Likewise. * sh-nbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sh-tdep.c (sh_extract_return_value_nofpu): Likewise. (sh_extract_return_value_fpu): Likewise. (sh_store_return_value_nofpu): Likewise. (sh_corefile_supply_regset): Likewise. (sh_corefile_collect_regset): Likewise. * sh64-tdep.c (sh64_extract_return_value): Likewise. (sh64_store_return_value): Likewise. * sparc-linux-tdep.c (sparc32_linux_collect_core_fpregset): Likewise. * sparc-nat.c (sparc_fetch_inferior_registers): Likewise. (sparc_store_inferior_registers): Likewise. * sparc-ravenscar-thread.c (register_in_thread_descriptor_p): Likewise. (sparc_ravenscar_prepare_to_store): Likewise. * sparc-tdep.c (sparc32_store_arguments): Likewise. (sparc_analyze_control_transfer): Likewise. (sparc_step_trap): Likewise. (sparc_software_single_step): Likewise. (sparc32_gdbarch_init): Likewise. (sparc_supply_rwindow): Likewise. (sparc_collect_rwindow): Likewise. * sparc64-linux-tdep.c (sparc64_linux_collect_core_fpregset): Likewise. * sparc64-nbsd-nat.c (sparc64nbsd_supply_gregset): Likewise. (sparc64nbsd_collect_gregset): Likewise. (sparc64nbsd_supply_fpregset): Likewise. (sparc64nbsd_collect_fpregset): Likewise. * sparc64-tdep.c (sparc64_store_arguments): Likewise. (sparc64_supply_gregset): Likewise. (sparc64_collect_gregset): Likewise. (sparc64_supply_fpregset): Likewise. (sparc64_collect_fpregset): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. * spu-tdep.c (spu_unwind_sp): Likewise. (spu2ppu_prev_register): Likewise. (spu_memory_remove_breakpoint): Likewise. * stack.c (return_command): Likewise. * tic6x-tdep.c (tic6x_extract_signed_field): Likewise. * tracefile-tfile.c (tfile_fetch_registers): Likewise. * tracefile.c (trace_save_ctf): Likewise. * windows-nat.c (do_windows_fetch_inferior_registers): Likewise. (do_windows_store_inferior_registers): Likewise. (windows_resume): Likewise. * xtensa-linux-nat.c (fill_gregset): Likewise. (supply_gregset_reg): Likewise. * xtensa-tdep.c (xtensa_register_write_masked): Likewise. (xtensa_register_read_masked): Likewise. (xtensa_supply_gregset): Likewise. (xtensa_extract_return_value): Likewise. (xtensa_store_return_value): Likewise.
2017-10-25 23:37:03 +08:00
struct gdbarch *gdbarch = regcache->arch ();
2007-11-16 Markus Deuling <deuling@de.ibm.com> * m32r-rom.c (m32r_supply_register): Use get_regcache_arch to get at the current architecture by regcache. * ppcnbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register) (fetch_register, supply_vrregset, fetch_ppc_registers) (store_altivec_register, store_spe_register, store_register) (fill_vrregset, store_ppc_registers): Likewise. * ppcobsd-nat.c (ppcobsd_supply_pcb): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers) (do_win32_store_inferior_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers) (m32r_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register, gdbsim_store_register): Likewise. * trad-frame.c (trad_frame_alloc_saved_regs): Replace current_gdbarch by gdbarch. * user-regs.c (user_reg_map_name_to_regnum): Likewise. * ppc-sysv-tdep.c (ppc_sysv_abi_push_dummy_call) (do_ppc_sysv_return_value, ppc64_sysv_abi_push_dummy_call) (ppc64_sysv_abi_return_value): Likewise. * m32c-tdep.c (m32c_register_reggroup_p): Likewise. * m2-lang.c (build_m2_types): Likewise. * ppc-linux-tdep.c (ppc_linux_sigtramp_cache * ppcnbsd-tdep.c (ppcnbsd_sigtramp_cache_init): Likewise. * ppcobsd-tdep.c (ppcobsd_sigtramp_frame_cache): Likewise. * rs6000-tdep.c (ppc_dwarf2_frame_init_reg): Likewise. * m68hc11-tdep.c (m68hc11_frame_unwind_cache): Use get_frame_arch to get at the current architecture by frame_info. * gcore.c (derive_stack_segment): Likewise. * shnbsd-nat.c (GETREGS_SUPPLIES): Add gdbarch parameter. (shnbsd_fetch_inferior_registers, shnbsd_store_inferior_registers): Add gdbarch to GETREGS_SUPPLIES call.
2007-11-16 12:53:46 +08:00
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
struct gdb_evrregset_t evrregs;
Change the layout of the PowerPC E500 raw register cache to allow the lower 32-bit halves of the GPRS to be their own raw registers, not pseudoregisters. * ppc-tdep.h (struct gdbarch_tdep): Remove ppc_gprs_pseudo_p flag; add ppc_ev0_upper_regnum flag. * rs6000-tdep.c: #include "reggroups.h". (spe_register_p): Recognize the ev upper half registers as SPE registers. (init_sim_regno_table): Build gdb->sim mappings for the upper-half registers. (e500_move_ev_register): New function. (e500_pseudo_register_read, e500_pseudo_register_write): The 'ev' vector registers are the pseudo-registers now, formed by splicing together the gprs and the upper-half registers. (e500_register_reggroup_p): New function. (P): Macro deleted. (P8, A4): New macro. (PPC_EV_REGS, PPC_GPRS_PSEUDO_REGS): Macros deleted. (PPC_SPE_GP_REGS, PPC_SPE_UPPER_GP_REGS, PPC_EV_PSEUDO_REGS): New macros. (registers_e500): Rearrange register set so that the raw register set contains 32-bit GPRs and upper-half registers, and the SPE vector registers become pseudo-registers. (rs6000_gdbarch_init): Don't initialize tdep->ppc_gprs_pseudo_p; it has been deleted. Initialize ppc_ev0_upper_regnum. Many other register numbers are now the same for the E500 as they are for other PowerPC variants. Register e500_register_reggroup_p as the register group function for the E500. * Makefile.in (rs6000-tdep.o): Update dependencies. Adapt PPC E500 native support to the new raw regcache layout. * ppc-linux-nat.c (struct gdb_evrregset_t): Doc fixes. (read_spliced_spe_reg, write_spliced_spe_reg): Deleted. (fetch_spe_register, store_spe_register): Handle fetching/storing all the SPE registers at once, if regno == -1. These now take over the job of fetch_spe_registers and store_spe_registers. (fetch_spe_registers, store_spe_registers): Deleted. (fetch_ppc_registers, store_ppc_registers): Fetch/store gprs unconditionally; they're always raw. Fetch/store SPE upper half registers, if present, instead of ev registers. (fetch_register, store_register): Remove sanity checks: gprs are never pseudo-registers now, so we never need to even mention any registers that are ever pseudoregisters.
2004-08-05 01:17:55 +08:00
gdb_assert (sizeof (evrregs.evr[0])
2007-11-16 Markus Deuling <deuling@de.ibm.com> * m32r-rom.c (m32r_supply_register): Use get_regcache_arch to get at the current architecture by regcache. * ppcnbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register) (fetch_register, supply_vrregset, fetch_ppc_registers) (store_altivec_register, store_spe_register, store_register) (fill_vrregset, store_ppc_registers): Likewise. * ppcobsd-nat.c (ppcobsd_supply_pcb): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers) (do_win32_store_inferior_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers) (m32r_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register, gdbsim_store_register): Likewise. * trad-frame.c (trad_frame_alloc_saved_regs): Replace current_gdbarch by gdbarch. * user-regs.c (user_reg_map_name_to_regnum): Likewise. * ppc-sysv-tdep.c (ppc_sysv_abi_push_dummy_call) (do_ppc_sysv_return_value, ppc64_sysv_abi_push_dummy_call) (ppc64_sysv_abi_return_value): Likewise. * m32c-tdep.c (m32c_register_reggroup_p): Likewise. * m2-lang.c (build_m2_types): Likewise. * ppc-linux-tdep.c (ppc_linux_sigtramp_cache * ppcnbsd-tdep.c (ppcnbsd_sigtramp_cache_init): Likewise. * ppcobsd-tdep.c (ppcobsd_sigtramp_frame_cache): Likewise. * rs6000-tdep.c (ppc_dwarf2_frame_init_reg): Likewise. * m68hc11-tdep.c (m68hc11_frame_unwind_cache): Use get_frame_arch to get at the current architecture by frame_info. * gcore.c (derive_stack_segment): Likewise. * shnbsd-nat.c (GETREGS_SUPPLIES): Add gdbarch parameter. (shnbsd_fetch_inferior_registers, shnbsd_store_inferior_registers): Add gdbarch to GETREGS_SUPPLIES call.
2007-11-16 12:53:46 +08:00
== register_size (gdbarch, tdep->ppc_ev0_upper_regnum));
Change the layout of the PowerPC E500 raw register cache to allow the lower 32-bit halves of the GPRS to be their own raw registers, not pseudoregisters. * ppc-tdep.h (struct gdbarch_tdep): Remove ppc_gprs_pseudo_p flag; add ppc_ev0_upper_regnum flag. * rs6000-tdep.c: #include "reggroups.h". (spe_register_p): Recognize the ev upper half registers as SPE registers. (init_sim_regno_table): Build gdb->sim mappings for the upper-half registers. (e500_move_ev_register): New function. (e500_pseudo_register_read, e500_pseudo_register_write): The 'ev' vector registers are the pseudo-registers now, formed by splicing together the gprs and the upper-half registers. (e500_register_reggroup_p): New function. (P): Macro deleted. (P8, A4): New macro. (PPC_EV_REGS, PPC_GPRS_PSEUDO_REGS): Macros deleted. (PPC_SPE_GP_REGS, PPC_SPE_UPPER_GP_REGS, PPC_EV_PSEUDO_REGS): New macros. (registers_e500): Rearrange register set so that the raw register set contains 32-bit GPRs and upper-half registers, and the SPE vector registers become pseudo-registers. (rs6000_gdbarch_init): Don't initialize tdep->ppc_gprs_pseudo_p; it has been deleted. Initialize ppc_ev0_upper_regnum. Many other register numbers are now the same for the E500 as they are for other PowerPC variants. Register e500_register_reggroup_p as the register group function for the E500. * Makefile.in (rs6000-tdep.o): Update dependencies. Adapt PPC E500 native support to the new raw regcache layout. * ppc-linux-nat.c (struct gdb_evrregset_t): Doc fixes. (read_spliced_spe_reg, write_spliced_spe_reg): Deleted. (fetch_spe_register, store_spe_register): Handle fetching/storing all the SPE registers at once, if regno == -1. These now take over the job of fetch_spe_registers and store_spe_registers. (fetch_spe_registers, store_spe_registers): Deleted. (fetch_ppc_registers, store_ppc_registers): Fetch/store gprs unconditionally; they're always raw. Fetch/store SPE upper half registers, if present, instead of ev registers. (fetch_register, store_register): Remove sanity checks: gprs are never pseudo-registers now, so we never need to even mention any registers that are ever pseudoregisters.
2004-08-05 01:17:55 +08:00
gdb_assert (sizeof (evrregs.acc)
2007-11-16 Markus Deuling <deuling@de.ibm.com> * m32r-rom.c (m32r_supply_register): Use get_regcache_arch to get at the current architecture by regcache. * ppcnbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register) (fetch_register, supply_vrregset, fetch_ppc_registers) (store_altivec_register, store_spe_register, store_register) (fill_vrregset, store_ppc_registers): Likewise. * ppcobsd-nat.c (ppcobsd_supply_pcb): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers) (do_win32_store_inferior_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers) (m32r_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register, gdbsim_store_register): Likewise. * trad-frame.c (trad_frame_alloc_saved_regs): Replace current_gdbarch by gdbarch. * user-regs.c (user_reg_map_name_to_regnum): Likewise. * ppc-sysv-tdep.c (ppc_sysv_abi_push_dummy_call) (do_ppc_sysv_return_value, ppc64_sysv_abi_push_dummy_call) (ppc64_sysv_abi_return_value): Likewise. * m32c-tdep.c (m32c_register_reggroup_p): Likewise. * m2-lang.c (build_m2_types): Likewise. * ppc-linux-tdep.c (ppc_linux_sigtramp_cache * ppcnbsd-tdep.c (ppcnbsd_sigtramp_cache_init): Likewise. * ppcobsd-tdep.c (ppcobsd_sigtramp_frame_cache): Likewise. * rs6000-tdep.c (ppc_dwarf2_frame_init_reg): Likewise. * m68hc11-tdep.c (m68hc11_frame_unwind_cache): Use get_frame_arch to get at the current architecture by frame_info. * gcore.c (derive_stack_segment): Likewise. * shnbsd-nat.c (GETREGS_SUPPLIES): Add gdbarch parameter. (shnbsd_fetch_inferior_registers, shnbsd_store_inferior_registers): Add gdbarch to GETREGS_SUPPLIES call.
2007-11-16 12:53:46 +08:00
== register_size (gdbarch, tdep->ppc_acc_regnum));
Change the layout of the PowerPC E500 raw register cache to allow the lower 32-bit halves of the GPRS to be their own raw registers, not pseudoregisters. * ppc-tdep.h (struct gdbarch_tdep): Remove ppc_gprs_pseudo_p flag; add ppc_ev0_upper_regnum flag. * rs6000-tdep.c: #include "reggroups.h". (spe_register_p): Recognize the ev upper half registers as SPE registers. (init_sim_regno_table): Build gdb->sim mappings for the upper-half registers. (e500_move_ev_register): New function. (e500_pseudo_register_read, e500_pseudo_register_write): The 'ev' vector registers are the pseudo-registers now, formed by splicing together the gprs and the upper-half registers. (e500_register_reggroup_p): New function. (P): Macro deleted. (P8, A4): New macro. (PPC_EV_REGS, PPC_GPRS_PSEUDO_REGS): Macros deleted. (PPC_SPE_GP_REGS, PPC_SPE_UPPER_GP_REGS, PPC_EV_PSEUDO_REGS): New macros. (registers_e500): Rearrange register set so that the raw register set contains 32-bit GPRs and upper-half registers, and the SPE vector registers become pseudo-registers. (rs6000_gdbarch_init): Don't initialize tdep->ppc_gprs_pseudo_p; it has been deleted. Initialize ppc_ev0_upper_regnum. Many other register numbers are now the same for the E500 as they are for other PowerPC variants. Register e500_register_reggroup_p as the register group function for the E500. * Makefile.in (rs6000-tdep.o): Update dependencies. Adapt PPC E500 native support to the new raw regcache layout. * ppc-linux-nat.c (struct gdb_evrregset_t): Doc fixes. (read_spliced_spe_reg, write_spliced_spe_reg): Deleted. (fetch_spe_register, store_spe_register): Handle fetching/storing all the SPE registers at once, if regno == -1. These now take over the job of fetch_spe_registers and store_spe_registers. (fetch_spe_registers, store_spe_registers): Deleted. (fetch_ppc_registers, store_ppc_registers): Fetch/store gprs unconditionally; they're always raw. Fetch/store SPE upper half registers, if present, instead of ev registers. (fetch_register, store_register): Remove sanity checks: gprs are never pseudo-registers now, so we never need to even mention any registers that are ever pseudoregisters.
2004-08-05 01:17:55 +08:00
gdb_assert (sizeof (evrregs.spefscr)
2007-11-16 Markus Deuling <deuling@de.ibm.com> * m32r-rom.c (m32r_supply_register): Use get_regcache_arch to get at the current architecture by regcache. * ppcnbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register) (fetch_register, supply_vrregset, fetch_ppc_registers) (store_altivec_register, store_spe_register, store_register) (fill_vrregset, store_ppc_registers): Likewise. * ppcobsd-nat.c (ppcobsd_supply_pcb): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers) (do_win32_store_inferior_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers) (m32r_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register, gdbsim_store_register): Likewise. * trad-frame.c (trad_frame_alloc_saved_regs): Replace current_gdbarch by gdbarch. * user-regs.c (user_reg_map_name_to_regnum): Likewise. * ppc-sysv-tdep.c (ppc_sysv_abi_push_dummy_call) (do_ppc_sysv_return_value, ppc64_sysv_abi_push_dummy_call) (ppc64_sysv_abi_return_value): Likewise. * m32c-tdep.c (m32c_register_reggroup_p): Likewise. * m2-lang.c (build_m2_types): Likewise. * ppc-linux-tdep.c (ppc_linux_sigtramp_cache * ppcnbsd-tdep.c (ppcnbsd_sigtramp_cache_init): Likewise. * ppcobsd-tdep.c (ppcobsd_sigtramp_frame_cache): Likewise. * rs6000-tdep.c (ppc_dwarf2_frame_init_reg): Likewise. * m68hc11-tdep.c (m68hc11_frame_unwind_cache): Use get_frame_arch to get at the current architecture by frame_info. * gcore.c (derive_stack_segment): Likewise. * shnbsd-nat.c (GETREGS_SUPPLIES): Add gdbarch parameter. (shnbsd_fetch_inferior_registers, shnbsd_store_inferior_registers): Add gdbarch to GETREGS_SUPPLIES call.
2007-11-16 12:53:46 +08:00
== register_size (gdbarch, tdep->ppc_spefscr_regnum));
Change the layout of the PowerPC E500 raw register cache to allow the lower 32-bit halves of the GPRS to be their own raw registers, not pseudoregisters. * ppc-tdep.h (struct gdbarch_tdep): Remove ppc_gprs_pseudo_p flag; add ppc_ev0_upper_regnum flag. * rs6000-tdep.c: #include "reggroups.h". (spe_register_p): Recognize the ev upper half registers as SPE registers. (init_sim_regno_table): Build gdb->sim mappings for the upper-half registers. (e500_move_ev_register): New function. (e500_pseudo_register_read, e500_pseudo_register_write): The 'ev' vector registers are the pseudo-registers now, formed by splicing together the gprs and the upper-half registers. (e500_register_reggroup_p): New function. (P): Macro deleted. (P8, A4): New macro. (PPC_EV_REGS, PPC_GPRS_PSEUDO_REGS): Macros deleted. (PPC_SPE_GP_REGS, PPC_SPE_UPPER_GP_REGS, PPC_EV_PSEUDO_REGS): New macros. (registers_e500): Rearrange register set so that the raw register set contains 32-bit GPRs and upper-half registers, and the SPE vector registers become pseudo-registers. (rs6000_gdbarch_init): Don't initialize tdep->ppc_gprs_pseudo_p; it has been deleted. Initialize ppc_ev0_upper_regnum. Many other register numbers are now the same for the E500 as they are for other PowerPC variants. Register e500_register_reggroup_p as the register group function for the E500. * Makefile.in (rs6000-tdep.o): Update dependencies. Adapt PPC E500 native support to the new raw regcache layout. * ppc-linux-nat.c (struct gdb_evrregset_t): Doc fixes. (read_spliced_spe_reg, write_spliced_spe_reg): Deleted. (fetch_spe_register, store_spe_register): Handle fetching/storing all the SPE registers at once, if regno == -1. These now take over the job of fetch_spe_registers and store_spe_registers. (fetch_spe_registers, store_spe_registers): Deleted. (fetch_ppc_registers, store_ppc_registers): Fetch/store gprs unconditionally; they're always raw. Fetch/store SPE upper half registers, if present, instead of ev registers. (fetch_register, store_register): Remove sanity checks: gprs are never pseudo-registers now, so we never need to even mention any registers that are ever pseudoregisters.
2004-08-05 01:17:55 +08:00
get_spe_registers (tid, &evrregs);
Change the layout of the PowerPC E500 raw register cache to allow the lower 32-bit halves of the GPRS to be their own raw registers, not pseudoregisters. * ppc-tdep.h (struct gdbarch_tdep): Remove ppc_gprs_pseudo_p flag; add ppc_ev0_upper_regnum flag. * rs6000-tdep.c: #include "reggroups.h". (spe_register_p): Recognize the ev upper half registers as SPE registers. (init_sim_regno_table): Build gdb->sim mappings for the upper-half registers. (e500_move_ev_register): New function. (e500_pseudo_register_read, e500_pseudo_register_write): The 'ev' vector registers are the pseudo-registers now, formed by splicing together the gprs and the upper-half registers. (e500_register_reggroup_p): New function. (P): Macro deleted. (P8, A4): New macro. (PPC_EV_REGS, PPC_GPRS_PSEUDO_REGS): Macros deleted. (PPC_SPE_GP_REGS, PPC_SPE_UPPER_GP_REGS, PPC_EV_PSEUDO_REGS): New macros. (registers_e500): Rearrange register set so that the raw register set contains 32-bit GPRs and upper-half registers, and the SPE vector registers become pseudo-registers. (rs6000_gdbarch_init): Don't initialize tdep->ppc_gprs_pseudo_p; it has been deleted. Initialize ppc_ev0_upper_regnum. Many other register numbers are now the same for the E500 as they are for other PowerPC variants. Register e500_register_reggroup_p as the register group function for the E500. * Makefile.in (rs6000-tdep.o): Update dependencies. Adapt PPC E500 native support to the new raw regcache layout. * ppc-linux-nat.c (struct gdb_evrregset_t): Doc fixes. (read_spliced_spe_reg, write_spliced_spe_reg): Deleted. (fetch_spe_register, store_spe_register): Handle fetching/storing all the SPE registers at once, if regno == -1. These now take over the job of fetch_spe_registers and store_spe_registers. (fetch_spe_registers, store_spe_registers): Deleted. (fetch_ppc_registers, store_ppc_registers): Fetch/store gprs unconditionally; they're always raw. Fetch/store SPE upper half registers, if present, instead of ev registers. (fetch_register, store_register): Remove sanity checks: gprs are never pseudo-registers now, so we never need to even mention any registers that are ever pseudoregisters.
2004-08-05 01:17:55 +08:00
if (regno == -1)
{
Change the layout of the PowerPC E500 raw register cache to allow the lower 32-bit halves of the GPRS to be their own raw registers, not pseudoregisters. * ppc-tdep.h (struct gdbarch_tdep): Remove ppc_gprs_pseudo_p flag; add ppc_ev0_upper_regnum flag. * rs6000-tdep.c: #include "reggroups.h". (spe_register_p): Recognize the ev upper half registers as SPE registers. (init_sim_regno_table): Build gdb->sim mappings for the upper-half registers. (e500_move_ev_register): New function. (e500_pseudo_register_read, e500_pseudo_register_write): The 'ev' vector registers are the pseudo-registers now, formed by splicing together the gprs and the upper-half registers. (e500_register_reggroup_p): New function. (P): Macro deleted. (P8, A4): New macro. (PPC_EV_REGS, PPC_GPRS_PSEUDO_REGS): Macros deleted. (PPC_SPE_GP_REGS, PPC_SPE_UPPER_GP_REGS, PPC_EV_PSEUDO_REGS): New macros. (registers_e500): Rearrange register set so that the raw register set contains 32-bit GPRs and upper-half registers, and the SPE vector registers become pseudo-registers. (rs6000_gdbarch_init): Don't initialize tdep->ppc_gprs_pseudo_p; it has been deleted. Initialize ppc_ev0_upper_regnum. Many other register numbers are now the same for the E500 as they are for other PowerPC variants. Register e500_register_reggroup_p as the register group function for the E500. * Makefile.in (rs6000-tdep.o): Update dependencies. Adapt PPC E500 native support to the new raw regcache layout. * ppc-linux-nat.c (struct gdb_evrregset_t): Doc fixes. (read_spliced_spe_reg, write_spliced_spe_reg): Deleted. (fetch_spe_register, store_spe_register): Handle fetching/storing all the SPE registers at once, if regno == -1. These now take over the job of fetch_spe_registers and store_spe_registers. (fetch_spe_registers, store_spe_registers): Deleted. (fetch_ppc_registers, store_ppc_registers): Fetch/store gprs unconditionally; they're always raw. Fetch/store SPE upper half registers, if present, instead of ev registers. (fetch_register, store_register): Remove sanity checks: gprs are never pseudo-registers now, so we never need to even mention any registers that are ever pseudoregisters.
2004-08-05 01:17:55 +08:00
int i;
for (i = 0; i < ppc_num_gprs; i++)
regcache->raw_supply (tdep->ppc_ev0_upper_regnum + i, &evrregs.evr[i]);
}
Change the layout of the PowerPC E500 raw register cache to allow the lower 32-bit halves of the GPRS to be their own raw registers, not pseudoregisters. * ppc-tdep.h (struct gdbarch_tdep): Remove ppc_gprs_pseudo_p flag; add ppc_ev0_upper_regnum flag. * rs6000-tdep.c: #include "reggroups.h". (spe_register_p): Recognize the ev upper half registers as SPE registers. (init_sim_regno_table): Build gdb->sim mappings for the upper-half registers. (e500_move_ev_register): New function. (e500_pseudo_register_read, e500_pseudo_register_write): The 'ev' vector registers are the pseudo-registers now, formed by splicing together the gprs and the upper-half registers. (e500_register_reggroup_p): New function. (P): Macro deleted. (P8, A4): New macro. (PPC_EV_REGS, PPC_GPRS_PSEUDO_REGS): Macros deleted. (PPC_SPE_GP_REGS, PPC_SPE_UPPER_GP_REGS, PPC_EV_PSEUDO_REGS): New macros. (registers_e500): Rearrange register set so that the raw register set contains 32-bit GPRs and upper-half registers, and the SPE vector registers become pseudo-registers. (rs6000_gdbarch_init): Don't initialize tdep->ppc_gprs_pseudo_p; it has been deleted. Initialize ppc_ev0_upper_regnum. Many other register numbers are now the same for the E500 as they are for other PowerPC variants. Register e500_register_reggroup_p as the register group function for the E500. * Makefile.in (rs6000-tdep.o): Update dependencies. Adapt PPC E500 native support to the new raw regcache layout. * ppc-linux-nat.c (struct gdb_evrregset_t): Doc fixes. (read_spliced_spe_reg, write_spliced_spe_reg): Deleted. (fetch_spe_register, store_spe_register): Handle fetching/storing all the SPE registers at once, if regno == -1. These now take over the job of fetch_spe_registers and store_spe_registers. (fetch_spe_registers, store_spe_registers): Deleted. (fetch_ppc_registers, store_ppc_registers): Fetch/store gprs unconditionally; they're always raw. Fetch/store SPE upper half registers, if present, instead of ev registers. (fetch_register, store_register): Remove sanity checks: gprs are never pseudo-registers now, so we never need to even mention any registers that are ever pseudoregisters.
2004-08-05 01:17:55 +08:00
else if (tdep->ppc_ev0_upper_regnum <= regno
&& regno < tdep->ppc_ev0_upper_regnum + ppc_num_gprs)
regcache->raw_supply (regno,
&evrregs.evr[regno - tdep->ppc_ev0_upper_regnum]);
Change the layout of the PowerPC E500 raw register cache to allow the lower 32-bit halves of the GPRS to be their own raw registers, not pseudoregisters. * ppc-tdep.h (struct gdbarch_tdep): Remove ppc_gprs_pseudo_p flag; add ppc_ev0_upper_regnum flag. * rs6000-tdep.c: #include "reggroups.h". (spe_register_p): Recognize the ev upper half registers as SPE registers. (init_sim_regno_table): Build gdb->sim mappings for the upper-half registers. (e500_move_ev_register): New function. (e500_pseudo_register_read, e500_pseudo_register_write): The 'ev' vector registers are the pseudo-registers now, formed by splicing together the gprs and the upper-half registers. (e500_register_reggroup_p): New function. (P): Macro deleted. (P8, A4): New macro. (PPC_EV_REGS, PPC_GPRS_PSEUDO_REGS): Macros deleted. (PPC_SPE_GP_REGS, PPC_SPE_UPPER_GP_REGS, PPC_EV_PSEUDO_REGS): New macros. (registers_e500): Rearrange register set so that the raw register set contains 32-bit GPRs and upper-half registers, and the SPE vector registers become pseudo-registers. (rs6000_gdbarch_init): Don't initialize tdep->ppc_gprs_pseudo_p; it has been deleted. Initialize ppc_ev0_upper_regnum. Many other register numbers are now the same for the E500 as they are for other PowerPC variants. Register e500_register_reggroup_p as the register group function for the E500. * Makefile.in (rs6000-tdep.o): Update dependencies. Adapt PPC E500 native support to the new raw regcache layout. * ppc-linux-nat.c (struct gdb_evrregset_t): Doc fixes. (read_spliced_spe_reg, write_spliced_spe_reg): Deleted. (fetch_spe_register, store_spe_register): Handle fetching/storing all the SPE registers at once, if regno == -1. These now take over the job of fetch_spe_registers and store_spe_registers. (fetch_spe_registers, store_spe_registers): Deleted. (fetch_ppc_registers, store_ppc_registers): Fetch/store gprs unconditionally; they're always raw. Fetch/store SPE upper half registers, if present, instead of ev registers. (fetch_register, store_register): Remove sanity checks: gprs are never pseudo-registers now, so we never need to even mention any registers that are ever pseudoregisters.
2004-08-05 01:17:55 +08:00
if (regno == -1
|| regno == tdep->ppc_acc_regnum)
regcache->raw_supply (tdep->ppc_acc_regnum, &evrregs.acc);
Change the layout of the PowerPC E500 raw register cache to allow the lower 32-bit halves of the GPRS to be their own raw registers, not pseudoregisters. * ppc-tdep.h (struct gdbarch_tdep): Remove ppc_gprs_pseudo_p flag; add ppc_ev0_upper_regnum flag. * rs6000-tdep.c: #include "reggroups.h". (spe_register_p): Recognize the ev upper half registers as SPE registers. (init_sim_regno_table): Build gdb->sim mappings for the upper-half registers. (e500_move_ev_register): New function. (e500_pseudo_register_read, e500_pseudo_register_write): The 'ev' vector registers are the pseudo-registers now, formed by splicing together the gprs and the upper-half registers. (e500_register_reggroup_p): New function. (P): Macro deleted. (P8, A4): New macro. (PPC_EV_REGS, PPC_GPRS_PSEUDO_REGS): Macros deleted. (PPC_SPE_GP_REGS, PPC_SPE_UPPER_GP_REGS, PPC_EV_PSEUDO_REGS): New macros. (registers_e500): Rearrange register set so that the raw register set contains 32-bit GPRs and upper-half registers, and the SPE vector registers become pseudo-registers. (rs6000_gdbarch_init): Don't initialize tdep->ppc_gprs_pseudo_p; it has been deleted. Initialize ppc_ev0_upper_regnum. Many other register numbers are now the same for the E500 as they are for other PowerPC variants. Register e500_register_reggroup_p as the register group function for the E500. * Makefile.in (rs6000-tdep.o): Update dependencies. Adapt PPC E500 native support to the new raw regcache layout. * ppc-linux-nat.c (struct gdb_evrregset_t): Doc fixes. (read_spliced_spe_reg, write_spliced_spe_reg): Deleted. (fetch_spe_register, store_spe_register): Handle fetching/storing all the SPE registers at once, if regno == -1. These now take over the job of fetch_spe_registers and store_spe_registers. (fetch_spe_registers, store_spe_registers): Deleted. (fetch_ppc_registers, store_ppc_registers): Fetch/store gprs unconditionally; they're always raw. Fetch/store SPE upper half registers, if present, instead of ev registers. (fetch_register, store_register): Remove sanity checks: gprs are never pseudo-registers now, so we never need to even mention any registers that are ever pseudoregisters.
2004-08-05 01:17:55 +08:00
if (regno == -1
|| regno == tdep->ppc_spefscr_regnum)
regcache->raw_supply (tdep->ppc_spefscr_regnum, &evrregs.spefscr);
}
[PowerPC] Add support for PPR and DSCR This patch adds gdb support for the Program Priorty Register and the Data Stream Control Register, for the powerpc linux native and core file targets, and for the powerpc linux server stub. gdb/ChangeLog: 2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * arch/ppc-linux-tdesc.h (tdesc_powerpc_isa205_ppr_dscr_vsx32l) (tdesc_powerpc_isa205_ppr_dscr_vsx64l): Declare. * arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_PPRREGSET) (PPC_LINUX_SIZEOF_DSCRREGSET): Define. (struct ppc_linux_features) <ppr_dscr>: New field. (ppc_linux_no_features): Add initializer for ppr_dscr field. * arch/ppc-linux-common.c (ppc_linux_match_description): Return new tdescs. * nat/ppc-linux.h (PPC_FEATURE2_DSCR, NT_PPC_PPR, NT_PPC_DSCR): Define if not already defined. * features/Makefile (WHICH): Add rs6000/powerpc-isa205-ppr-dscr-vsx32l and rs6000/powerpc-isa205-ppr-dscr-vsx64l. (XMLTOC): Add rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml and rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml. * features/rs6000/power-dscr.xml: New file. * features/rs6000/power-ppr.xml: New file. * features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml: New file. * features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml: New file. * features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.c: Generate. * features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.c: Generate. * regformats/rs6000/powerpc-isa205-ppr-dscr-vsx32l.dat: Generate. * regformats/rs6000/powerpc-isa205-ppr-dscr-vsx64l.dat: Generate. * ppc-linux-nat.c: Include <sys/uio.h>. (fetch_regset, store_regset, check_regset): New functions. (fetch_register, fetch_ppc_registers): Call fetch_regset with DSCR and PPR regsets. (store_register, store_ppc_registers): Call store_regset with DSCR and PPR regsets. (ppc_linux_get_hwcap2): New function. (ppc_linux_nat_target::read_description): Call ppc_linux_get_hwcap2 and check_regset, set ppr_dscr field in the features struct if needed. * ppc-linux-tdep.c: Include features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.c and features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.c. (ppc32_regmap_ppr, ppc32_regmap_dscr, ppc32_linux_pprregset) (ppc32_linux_dscrregset): New globals. (ppc_linux_iterate_over_regset_sections): Call back with the ppr and dscr regsets. (ppc_linux_core_read_description): Check if the ppr and dscr sections are present and set ppr_dscr in the features struct. (_initialize_ppc_linux_tdep): Call initialize_tdesc_powerpc_isa205_ppr_dscr_vsx32l and initialize_tdesc_powerpc_isa205_ppr_dscr_vsx64l. * ppc-linux-tdep.h (ppc32_linux_pprregset) (ppc32_linux_dscrregset): Declare. * ppc-tdep.h (struct gdbarch_tdep) <ppc_ppr_regnum>: New field. <ppc_dscr_regnum>: New field. (enum) <PPC_PPR_REGNUM, PPC_DSCR_REGNUM>: New enum values. * rs6000-tdep.c (rs6000_gdbarch_init): Look for and validate ppr and dscr features. (ppc_process_record_op31): Record changes to PPR and DSCR. gdb/gdbserver/ChangeLog: 2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * configure.srv (ipa_ppc_linux_regobj): Add powerpc-isa205-ppr-dscr-vsx32l-ipa.o and powerpc-isa205-ppr-dscr-vsx64l-ipa.o. (powerpc*-*-linux*): Add powerpc-isa205-ppr-dscr-vsx32l.o and powerpc-isa205-ppr-dscr-vsx64l.o to srv_regobj, add rs6000/power-dscr.xml, rs6000/power-ppr.xml, rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml and rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml to srv_xmlfiles. * linux-ppc-tdesc-init.h (enum ppc_linux_tdesc) <PPC_TDESC_ISA205_PPR_DSCR_VSX>: New enum value. (init_registers_powerpc_isa205_ppr_dscr_vsx32l) (init_registers_powerpc_isa205_ppr_dscr_vsx64l): Declare. * linux-ppc-low.c: Include "elf/common.h" and <sys/uio.h>. (ppc_hwcap): Add comment. (ppc_hwcap2): New global. (ppc_check_regset, ppc_fill_pprregset, ppc_store_pprregset) (ppc_fill_dscrregset, ppc_store_dscrregset): New functions. (ppc_regsets): Add entries for the DSCR and PPR regsets. (ppc_arch_setup): Get AT_HWCAP2. Set ppr_dscr in features struct when needed. Set sizes for the the DSCR and PPR regsets. (ppc_get_ipa_tdesc_idx): Return PPC_TDESC_ISA205_PPR_DSCR_VSX. (initialize_low_arch): Call init_registers_powerpc_isa205_ppr_dscr_vsx32l and init_registers_powerpc_isa205_ppr_dscr_vsx64l. * linux-ppc-ipa.c (get_ipa_tdesc): Handle PPC_TDESC_ISA205_PPR_DSCR_VSX. (initialize_low_tracepoint): Call init_registers_powerpc_isa205_ppr_dscr_vsx32l and init_registers_powerpc_isa205_ppr_dscr_vsx64l. gdb/testsuite/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.arch/powerpc-ppr-dscr.c: New file. * gdb.arch/powerpc-ppr-dscr.exp: New file. gdb/doc/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.texinfo (PowerPC Features): Describe new features "org.gnu.gdb.power.ppr" and "org.gnu.gdb.power.dscr".
2018-10-26 20:37:54 +08:00
/* Use ptrace to fetch all registers from the register set with note
type REGSET_ID, size REGSIZE, and layout described by REGSET, from
process/thread TID and supply their values to REGCACHE. If ptrace
returns ENODATA to indicate the regset is unavailable, mark the
registers as unavailable in REGCACHE. */
static void
fetch_regset (struct regcache *regcache, int tid,
int regset_id, int regsetsize, const struct regset *regset)
{
void *buf = alloca (regsetsize);
struct iovec iov;
iov.iov_base = buf;
iov.iov_len = regsetsize;
if (ptrace (PTRACE_GETREGSET, tid, regset_id, &iov) < 0)
{
if (errno == ENODATA)
regset->supply_regset (regset, regcache, -1, NULL, regsetsize);
else
perror_with_name (_("Couldn't get register set"));
}
else
regset->supply_regset (regset, regcache, -1, buf, regsetsize);
}
/* Use ptrace to store register REGNUM of the regset with note type
REGSET_ID, size REGSETSIZE, and layout described by REGSET, from
REGCACHE back to process/thread TID. If REGNUM is -1 all registers
in the set are collected and stored. */
static void
store_regset (const struct regcache *regcache, int tid, int regnum,
int regset_id, int regsetsize, const struct regset *regset)
{
void *buf = alloca (regsetsize);
struct iovec iov;
iov.iov_base = buf;
iov.iov_len = regsetsize;
/* Make sure that the buffer that will be stored has up to date values
for the registers that won't be collected. */
if (ptrace (PTRACE_GETREGSET, tid, regset_id, &iov) < 0)
perror_with_name (_("Couldn't get register set"));
regset->collect_regset (regset, regcache, regnum, buf, regsetsize);
if (ptrace (PTRACE_SETREGSET, tid, regset_id, &iov) < 0)
perror_with_name (_("Couldn't set register set"));
}
/* Check whether the kernel provides a register set with number
REGSET_ID of size REGSETSIZE for process/thread TID. */
static bool
check_regset (int tid, int regset_id, int regsetsize)
{
void *buf = alloca (regsetsize);
struct iovec iov;
iov.iov_base = buf;
iov.iov_len = regsetsize;
if (ptrace (PTRACE_GETREGSET, tid, regset_id, &iov) >= 0
|| errno == ENODATA)
return true;
else
return false;
}
static void
* target.h (struct regcache): Add forward declaration. (struct target_ops): Add REGCACHE parameter to to_fetch_registers and to_store_registers target operations. (target_fetch_registers, target_store_registers): Update. * regcache.c (regcache_raw_read): Replace register_cached by regcache_valid_p. Pass regcache to target_fetch_registers. (regcache_raw_write): Pass regcache to target_store_registers. * arm-linux-nat.c (store_fpregister, store_fpregs, store_register, store_regs, store_wmmx_regs): Replace register_cached by regcache_valid_p. * bsd-kvm.c (bsd_kvm_open, bsd_kvm_proc_cmd): Pass current_regcache to target_fetch_registers calls. * corelow.c (core_open): Likewise. * linux-nat.c (linux_nat_corefile_thread_callback): Likewise. * proc-service.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * sol-thread.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * win32-nat.c (win32_resume): Likewise. * ia64-tdep.c (ia64_store_return_value): Pass current_regcache to target_store_registers call. * rs6000-tdep.c (rs6000_push_dummy_call): Likewise. * inferior.h (store_inferior_registers): Update prototype. (fetch_inferior_registers): Likewise. * gnu-nat.c (gnu_store_registers, gnu_fetch_registers): Likewise. * mips-linux-nat.c (super_fetch_registers, super_store_registers): Update function pointer signatures. * aix-thread.c (aix_thread_fetch_registers): Add REGCACHE parameter, use it instead of current_regcache, update calls. (aix_thread_store_registers): Likewise. * alphabsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * amd64bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_fpregister, fetch_fpregs, store_fpregister, store_fpregs, fetch_register, fetch_regs, store_register, store_regs, fetch_wmmx_regs, store_wmmx_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * armnbsd-nat.c (fetch_register, fetch_regs, fetch_fp_register, fetch_fp_regs, armnbsd_fetch_registers): Likewise. (store_register, store_regs, store_fp_register, store_fp_regs, armnbsd_store_registers): Likewise. * bsd-kvm.c (bsd_kvm_fetch_pcb, bsd_kvm_fetch_registers): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * corelow.c (get_core_registers): Likewise. * go32-nat.c (fetch_register, go32_fetch_registers, store_register, go32_store_registers): Likewise. * hppabsd-nat.c (hppabsd_fetch_registers): Likewise. (hppabsd_store_registers): Likewise. * hppa-hpux-nat.c (hppa_hpux_fetch_register): Likewise. (hppa_hpux_fetch_inferior_registers): Likewise. (hppa_hpux_store_register): Likewise. (hppa_hpux_store_inferior_registers): Likewise. * hppa-linux-nat.c (fetch_register, store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * hpux-thread.c (hpux_thread_fetch_registers): Likewise. (hpux_thread_store_registers): Likewise. * i386bsd-nat.c (i386bsd_fetch_inferior_registers): Likewise. (i386bsd_store_inferior_registers): Likewise. * i386gnu-nat.c (fetch_fpregs, gnu_fetch_registers, store_fpregs, gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register, store_register, fetch_regs, store_regs, fetch_fpregs, store_fpregs, fetch_fpxregs, store_fpxregs): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_register): Likewise. (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_register): Likewise. (ia64_linux_store_registers): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. (inf_child_store_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register): Likewise. (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_register): Likewise. (inf_ptrace_store_registers): Likewise. * infptrace.c (fetch_register, store_register): Likewise. (fetch_inferior_registers, store_inferior_registers): Likewise. * m32r-linux-nat.c (fetch_regs, store_regs): Likewise. (m32r_linux_fetch_inferior_registers): Likewise. (m32r_linux_store_inferior_registers): Likewise. * m68kbsd-nat.c (m68kbsd_fetch_inferior_registers): Likewise. (m68kbsd_store_inferior_registers): Likewise. * m68klinux-nat.c (fetch_register, old_fetch_inferior_registers, store_register, old_store_inferior_registers, fetch_regs, store_regs, fetch_fpregs, store_fpregs): Likewise. (m68k_linux_fetch_inferior_registers): Likewise. (m68k_linux_store_inferior_registers): Likewise. * m88kbsd-nat.c (m88kbsd_fetch_inferior_registers): Likewise. (m88kbsd_store_inferior_registers): Likewise. * mips64obsd-nat.c (mips64obsd_fetch_inferior_registers): Likewise. (mips64obsd_store_inferior_registers): Likewise. * mips-linux-nat.c (mips64_linux_regsets_fetch_registers): Likewise. (mips64_linux_regsets_store_registers): Likewise. (mips64_linux_fetch_registers): Likewise. (mips64_linux_store_registers): Likewise. * mipsnbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * monitor.c (monitor_fetch_register, monitor_store_register): Likewise. (monitor_fetch_registers, monitor_store_registers): Likewise. * nto-procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register, fetch_register, supply_vrregset, fetch_altivec_registers, fetch_ppc_registers, ppc_linux_fetch_inferior_registers): Likewise. (store_altivec_register, store_spe_register, store_register, fill_vrregset, store_altivec_registers, store_ppc_registers, ppc_linux_store_inferior_registers): Likewise. * ppcnbsd-nat.c (ppcnbsd_fetch_inferior_registers): Likewise. (ppcnbsd_store_inferior_registers): Likewise. * ppcobsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote.c (fetch_register_using_p, process_g_packet, fetch_registers_using_g, remote_fetch_registers): Likewise. (store_register_using_P, store_registers_using_G, remote_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers, m32r_fetch_register, m32r_store_register, m32r_store_register): Likewise. * remote-mips.c (mips_fetch_registers, mips_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * rs6000-nat.c (fetch_register, store_register): Likewise. (rs6000_fetch_inferior_registers): Likewise. (rs6000_store_inferior_registers): Likewise. * s390-nat.c (fetch_regs, store_regs): Likewise. (fetch_fpregs, store_fpregs): Likewise. (s390_linux_fetch_inferior_registers): Likewise. (s390_linux_store_inferior_registers): Likewise. * shnbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sol-thread.c (sol_thread_fetch_registers): Likewise. (sol_thread_store_registers): Likewise. * sparc-nat.c (fetch_inferior_registers): Likewise. (store_inferior_registers): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. (spu_store_inferior_registers): Likewise. * target.c (debug_print_register): Likewise. (debug_to_fetch_registers, debug_to_store_registers): Likewise. * vaxbsd-nat.c (vaxbsd_fetch_inferior_registers): Likewise. (vaxbsd_store_inferior_registers): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers): Likewise. (win32_fetch_inferior_registers): Likewise. (win32_store_inferior_registers): Likewise.
2007-05-06 22:34:38 +08:00
fetch_register (struct regcache *regcache, int tid, int regno)
{
s/get_regcache_arch (regcache)/regcache->arch ()/g This patches removes get_regcache_arch, and use regache->arch () instead. The motivation of this change is that I am going to move some basic stuff into a base class of regcache. I don't need to update "client" code regcache->arch (). On the other hand, this patch shortens the code a little bit. gdb: 2017-10-25 Yao Qi <yao.qi@linaro.org> * aarch32-linux-nat.c (aarch32_gp_regcache_supply): Use regcache->arch () instead get_regcache_arch. * aarch64-fbsd-nat.c (aarch64_fbsd_fetch_inferior_registers): Likewise. (aarch64_fbsd_store_inferior_registers): Likewise. * aarch64-linux-nat.c (fetch_gregs_from_thread): Likewise. (store_gregs_to_thread): Likewise. (fetch_fpregs_from_thread): Likewise. (store_fpregs_to_thread): Likewise. * aarch64-tdep.c (aarch64_extract_return_value): Likewise. (aarch64_store_return_value): Likewise. (aarch64_software_single_step): Likewise. * aix-thread.c (aix_thread_wait): Likewise. (supply_reg32): Likewise. (supply_sprs64): Likewise. (supply_sprs32): Likewise. (fill_gprs64): Likewise. (fill_gprs32): Likewise. (fill_sprs64): Likewise. (fill_sprs32): Likewise. (store_regs_user_thread): Likewise. (store_regs_kernel_thread): Likewise. * alpha-bsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * alpha-tdep.c (alpha_extract_return_value): Likewise. (alpha_store_return_value): Likewise. (alpha_deal_with_atomic_sequence): Likewise. (alpha_next_pc): Likewise. (alpha_software_single_step): Likewise. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * amd64-nat.c (amd64_supply_native_gregset): Likewise. (amd64_collect_native_gregset): Likewise. * amd64-obsd-tdep.c (amd64obsd_supply_uthread): Likewise. (amd64obsd_collect_uthread): Likewise. * amd64-tdep.c (amd64_supply_fpregset): Likewise. (amd64_collect_fpregset): Likewise. (amd64_supply_fxsave): Likewise. (amd64_supply_xsave): Likewise. (amd64_collect_fxsave): Likewise. (amd64_collect_xsave): Likewise. * arc-tdep.c (arc_write_pc): Likewise. * arch-utils.c (default_skip_permanent_breakpoint): Likewise. * arm-fbsd-nat.c (arm_fbsd_fetch_inferior_registers): Likewise. (arm_fbsd_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_vfp_regs): Likewise. (store_vfp_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * arm-linux-tdep.c (arm_linux_supply_gregset): Likewise. (arm_linux_sigreturn_next_pc): Likewise. (arm_linux_get_next_pcs_syscall_next_pc): Likewise. * arm-nbsd-nat.c (arm_supply_gregset): Likewise. (fetch_register): Likewise. (store_register): Likewise. * arm-tdep.c (arm_is_thumb): Likewise. (displaced_in_arm_mode): Likewise. (bx_write_pc): Likewise. (arm_get_next_pcs_addr_bits_remove): Likewise. (arm_software_single_step): Likewise. (arm_extract_return_value): Likewise. (arm_store_return_value): Likewise. (arm_write_pc): Likewise. * bfin-tdep.c (bfin_extract_return_value): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * core-regset.c (fetch_core_registers): Likewise. * corelow.c (get_core_registers): Likewise. * cris-tdep.c (cris_store_return_value): Likewise. (cris_extract_return_value): Likewise. (find_step_target): Likewise. (find_step_target): Likewise. (cris_software_single_step): Likewise. * ctf.c (ctf_fetch_registers): Likewise. * darwin-nat.c (cancel_breakpoint): Likewise. * fbsd-tdep.c (fbsd_collect_thread_registers): Likewise. * frv-tdep.c (frv_extract_return_value): Likewise. * ft32-tdep.c (ft32_store_return_value): Likewise. (ft32_extract_return_value): Likewise. * go32-nat.c (fetch_register): Likewise. (go32_fetch_registers): Likewise. (go32_store_registers): Likewise. (store_register): Likewise. * h8300-tdep.c (h8300_extract_return_value): Likewise. (h8300_store_return_value): Likewise. * hppa-linux-nat.c (fetch_register): Likewise. (store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * i386-darwin-nat.c (i386_darwin_fetch_inferior_registers): Likewise. (i386_darwin_store_inferior_registers): Likewise. * i386-gnu-nat.c (gnu_fetch_registers): Likewise. (gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register): Likewise. (store_register): Likewise. (supply_gregset): Likewise. (fill_gregset): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. (i386_linux_resume): Likewise. * i386-linux-tdep.c (i386_linux_get_syscall_number_from_regcache): Likewise. * i386-nto-tdep.c (i386nto_supply_gregset): Likewise. * i386-obsd-nat.c (i386obsd_supply_pcb): Likewise. * i386-obsd-tdep.c (i386obsd_supply_uthread): Likewise. (i386obsd_collect_uthread): Likewise. * i386-tdep.c (i386_mmx_regnum_to_fp_regnum): Likewise. (i386_supply_gregset): Likewise. (i386_collect_gregset): Likewise. (i386_supply_fpregset): Likewise. (i386_collect_fpregset): Likewise. (i386_mpx_bd_base): Likewise. * i386-v4-nat.c (supply_fpregset): Likewise. (fill_fpregset): Likewise. * i387-tdep.c (i387_supply_fsave): Likewise. (i387_collect_fsave): Likewise. (i387_supply_fxsave): Likewise. (i387_collect_fxsave): Likewise. (i387_supply_xsave): Likewise. (i387_collect_xsave): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_registers): Likewise. * ia64-tdep.c (ia64_access_rse_reg): Likewise. (ia64_extract_return_value): Likewise. (ia64_store_return_value): Likewise. (find_func_descr): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_registers): Likewise. * infrun.c (use_displaced_stepping): Likewise. (displaced_step_prepare_throw): Likewise. (resume): Likewise. (proceed): Likewise. (do_target_wait): Likewise. (adjust_pc_after_break): Likewise. (handle_inferior_event_1): Likewise. (handle_signal_stop): Likewise. (save_infcall_suspend_state): Likewise. (restore_infcall_suspend_state): Likewise. * iq2000-tdep.c (iq2000_extract_return_value): Likewise. * jit.c (jit_frame_prev_register): Likewise. * linux-nat.c (save_stop_reason): Likewise. (linux_nat_wait_1): Likewise. (resume_stopped_resumed_lwps): Likewise. * linux-record.c (record_linux_sockaddr): Likewise. (record_linux_msghdr): Likewise. (record_linux_system_call): Likewise. * linux-tdep.c (linux_collect_thread_registers): Likewise. * lm32-tdep.c (lm32_extract_return_value): Likewise. (lm32_store_return_value): Likewise. * m32c-tdep.c (m32c_read_flg): Likewise. (m32c_pseudo_register_read): Likewise. (m32c_pseudo_register_write): Likewise. * m32r-linux-tdep.c (m32r_linux_supply_gregset): Likewise. (m32r_linux_collect_gregset): Likewise. * m32r-tdep.c (m32r_store_return_value): Likewise. (m32r_extract_return_value): Likewise. * m68k-bsd-nat.c (m68kbsd_supply_fpregset): Likewise. (m68kbsd_collect_fpregset): Likewise. * m68k-bsd-tdep.c (m68kbsd_supply_fpregset): Likewise. * m68k-linux-nat.c (fetch_register): Likewise. (old_fetch_inferior_registers): Likewise. (old_store_inferior_registers): Likewise. (store_regs): Likewise. * m68k-tdep.c (m68k_svr4_extract_return_value): Likewise. (m68k_svr4_store_return_value): Likewise. * m88k-tdep.c (m88k_store_arguments): Likewise. * mi/mi-main.c (mi_cmd_data_list_changed_registers): Likewise. (mi_cmd_data_write_register_values): Likewise. * mips-fbsd-nat.c (mips_fbsd_fetch_inferior_registers): Likewise. (mips_fbsd_store_inferior_registers): Likewise. * mips-fbsd-tdep.c (mips_fbsd_supply_fpregs): Likewise. (mips_fbsd_supply_gregs): Likewise. (mips_fbsd_collect_fpregs): Likewise. (mips_fbsd_collect_gregs): Likewise. (mips_fbsd_supply_fpregset): Likewise. (mips_fbsd_collect_fpregset): Likewise. (mips_fbsd_supply_gregset): Likewise. (mips_fbsd_collect_gregset): Likewise. * mips-linux-nat.c (supply_gregset): Likewise. (fill_gregset): Likewise. (supply_fpregset): Likewise. (fill_fpregset): Likewise. * mips-linux-tdep.c (mips_supply_gregset): Likewise. (mips_fill_gregset): Likewise. (mips_supply_fpregset): Likewise. (mips_fill_fpregset): Likewise. (mips64_supply_gregset): Likewise. (micromips_linux_sigframe_validate): Likewise. * mips-nbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * mips-nbsd-tdep.c (mipsnbsd_supply_fpregset): Likewise. (mipsnbsd_supply_gregset): Likewise. (mipsnbsd_iterate_over_regset_sections): Likewise. (mipsnbsd_supply_reg): Likewise. (mipsnbsd_supply_fpreg): Likewise. * mips-tdep.c (mips_in_frame_stub): Likewise. (mips_dummy_id): Likewise. (is_octeon_bbit_op): Likewise. (micromips_bc1_pc): Likewise. (extended_mips16_next_pc): Likewise. (mips16_next_pc): Likewise. (deal_with_atomic_sequence): Likewise. * moxie-tdep.c (moxie_process_readu): Likewise. * nios2-tdep.c (nios2_get_next_pc): Likewise. * nto-procfs.c (procfs_store_registers): Likewise. * ppc-fbsd-nat.c (ppcfbsd_fetch_inferior_registers): Likewise. (ppcfbsd_store_inferior_registers): Likewise. * ppc-linux-nat.c (fetch_vsx_register): Likewise. (fetch_altivec_register): Likewise. (get_spe_registers): Likewise. (fetch_spe_register): Likewise. (fetch_altivec_registers): Likewise. (fetch_all_gp_regs): Likewise. (fetch_all_fp_regs): Likewise. (store_vsx_register): Likewise. (store_altivec_register): Likewise. (set_spe_registers): Likewise. (store_spe_register): Likewise. (store_altivec_registers): Likewise. (store_all_gp_regs): Likewise. (store_all_fp_regs): Likewise. * ppc-linux-tdep.c (ppc_linux_supply_gregset): Likewise. (ppc_linux_collect_gregset): Likewise. (ppc_canonicalize_syscall): Likewise. (ppc_linux_record_signal): Likewise. (ppu2spu_prev_register): Likewise. * ppc-nbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-obsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * ppc-ravenscar-thread.c (ppc_ravenscar_generic_fetch_registers): Likewise. (ppc_ravenscar_generic_store_registers): Likewise. * procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ravenscar-thread.c (ravenscar_fetch_registers): Likewise. (ravenscar_store_registers): Likewise. (ravenscar_prepare_to_store): Likewise. * record-btrace.c (record_btrace_fetch_registers): Likewise. * record-full.c (record_full_wait_1): Likewise. (record_full_registers_change): Likewise. (record_full_store_registers): Likewise. (record_full_core_fetch_registers): Likewise. (record_full_save): Likewise. (record_full_goto_insn): Likewise. * regcache.c (regcache_register_size): Likewise. (get_regcache_arch): Remove. (regcache_read_pc): Likewise. * regcache.h (get_regcache_arch): Remove. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * remote.c (fetch_register_using_p): Likewise. (send_g_packet): Likewise. (remote_prepare_to_store): Likewise. (store_registers_using_G): Likewise. * reverse.c (save_bookmark_command): Likewise. (goto_bookmark_command): Likewise. * rs6000-aix-tdep.c (branch_dest): Likewise. * rs6000-nat.c (rs6000_ptrace64): Likewise. (fetch_register): Likewise. * rs6000-tdep.c (ppc_supply_reg): Likewise. (ppc_collect_reg): Likewise. (ppc_collect_gregset): Likewise. (ppc_collect_fpregset): Likewise. (ppc_collect_vsxregset): Likewise. (ppc_collect_vrregset): Likewise. (ppc_displaced_step_hw_singlestep): Likewise. (rs6000_pseudo_register_read): Likewise. (rs6000_pseudo_register_write): Likewise. * s390-linux-nat.c (supply_gregset): Likewise. (fill_gregset): Likewise. (s390_linux_fetch_inferior_registers): Likewise. * s390-linux-tdep.c (s390_write_pc): Likewise. (s390_software_single_step): Likewise. (s390_all_but_pc_registers_record): Likewise. (s390_linux_syscall_record): Likewise. * sentinel-frame.c (sentinel_frame_prev_arch): Likewise. * sh-nbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sh-tdep.c (sh_extract_return_value_nofpu): Likewise. (sh_extract_return_value_fpu): Likewise. (sh_store_return_value_nofpu): Likewise. (sh_corefile_supply_regset): Likewise. (sh_corefile_collect_regset): Likewise. * sh64-tdep.c (sh64_extract_return_value): Likewise. (sh64_store_return_value): Likewise. * sparc-linux-tdep.c (sparc32_linux_collect_core_fpregset): Likewise. * sparc-nat.c (sparc_fetch_inferior_registers): Likewise. (sparc_store_inferior_registers): Likewise. * sparc-ravenscar-thread.c (register_in_thread_descriptor_p): Likewise. (sparc_ravenscar_prepare_to_store): Likewise. * sparc-tdep.c (sparc32_store_arguments): Likewise. (sparc_analyze_control_transfer): Likewise. (sparc_step_trap): Likewise. (sparc_software_single_step): Likewise. (sparc32_gdbarch_init): Likewise. (sparc_supply_rwindow): Likewise. (sparc_collect_rwindow): Likewise. * sparc64-linux-tdep.c (sparc64_linux_collect_core_fpregset): Likewise. * sparc64-nbsd-nat.c (sparc64nbsd_supply_gregset): Likewise. (sparc64nbsd_collect_gregset): Likewise. (sparc64nbsd_supply_fpregset): Likewise. (sparc64nbsd_collect_fpregset): Likewise. * sparc64-tdep.c (sparc64_store_arguments): Likewise. (sparc64_supply_gregset): Likewise. (sparc64_collect_gregset): Likewise. (sparc64_supply_fpregset): Likewise. (sparc64_collect_fpregset): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. * spu-tdep.c (spu_unwind_sp): Likewise. (spu2ppu_prev_register): Likewise. (spu_memory_remove_breakpoint): Likewise. * stack.c (return_command): Likewise. * tic6x-tdep.c (tic6x_extract_signed_field): Likewise. * tracefile-tfile.c (tfile_fetch_registers): Likewise. * tracefile.c (trace_save_ctf): Likewise. * windows-nat.c (do_windows_fetch_inferior_registers): Likewise. (do_windows_store_inferior_registers): Likewise. (windows_resume): Likewise. * xtensa-linux-nat.c (fill_gregset): Likewise. (supply_gregset_reg): Likewise. * xtensa-tdep.c (xtensa_register_write_masked): Likewise. (xtensa_register_read_masked): Likewise. (xtensa_supply_gregset): Likewise. (xtensa_extract_return_value): Likewise. (xtensa_store_return_value): Likewise.
2017-10-25 23:37:03 +08:00
struct gdbarch *gdbarch = regcache->arch ();
[PowerPC] Add support for PPR and DSCR This patch adds gdb support for the Program Priorty Register and the Data Stream Control Register, for the powerpc linux native and core file targets, and for the powerpc linux server stub. gdb/ChangeLog: 2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * arch/ppc-linux-tdesc.h (tdesc_powerpc_isa205_ppr_dscr_vsx32l) (tdesc_powerpc_isa205_ppr_dscr_vsx64l): Declare. * arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_PPRREGSET) (PPC_LINUX_SIZEOF_DSCRREGSET): Define. (struct ppc_linux_features) <ppr_dscr>: New field. (ppc_linux_no_features): Add initializer for ppr_dscr field. * arch/ppc-linux-common.c (ppc_linux_match_description): Return new tdescs. * nat/ppc-linux.h (PPC_FEATURE2_DSCR, NT_PPC_PPR, NT_PPC_DSCR): Define if not already defined. * features/Makefile (WHICH): Add rs6000/powerpc-isa205-ppr-dscr-vsx32l and rs6000/powerpc-isa205-ppr-dscr-vsx64l. (XMLTOC): Add rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml and rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml. * features/rs6000/power-dscr.xml: New file. * features/rs6000/power-ppr.xml: New file. * features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml: New file. * features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml: New file. * features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.c: Generate. * features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.c: Generate. * regformats/rs6000/powerpc-isa205-ppr-dscr-vsx32l.dat: Generate. * regformats/rs6000/powerpc-isa205-ppr-dscr-vsx64l.dat: Generate. * ppc-linux-nat.c: Include <sys/uio.h>. (fetch_regset, store_regset, check_regset): New functions. (fetch_register, fetch_ppc_registers): Call fetch_regset with DSCR and PPR regsets. (store_register, store_ppc_registers): Call store_regset with DSCR and PPR regsets. (ppc_linux_get_hwcap2): New function. (ppc_linux_nat_target::read_description): Call ppc_linux_get_hwcap2 and check_regset, set ppr_dscr field in the features struct if needed. * ppc-linux-tdep.c: Include features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.c and features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.c. (ppc32_regmap_ppr, ppc32_regmap_dscr, ppc32_linux_pprregset) (ppc32_linux_dscrregset): New globals. (ppc_linux_iterate_over_regset_sections): Call back with the ppr and dscr regsets. (ppc_linux_core_read_description): Check if the ppr and dscr sections are present and set ppr_dscr in the features struct. (_initialize_ppc_linux_tdep): Call initialize_tdesc_powerpc_isa205_ppr_dscr_vsx32l and initialize_tdesc_powerpc_isa205_ppr_dscr_vsx64l. * ppc-linux-tdep.h (ppc32_linux_pprregset) (ppc32_linux_dscrregset): Declare. * ppc-tdep.h (struct gdbarch_tdep) <ppc_ppr_regnum>: New field. <ppc_dscr_regnum>: New field. (enum) <PPC_PPR_REGNUM, PPC_DSCR_REGNUM>: New enum values. * rs6000-tdep.c (rs6000_gdbarch_init): Look for and validate ppr and dscr features. (ppc_process_record_op31): Record changes to PPR and DSCR. gdb/gdbserver/ChangeLog: 2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * configure.srv (ipa_ppc_linux_regobj): Add powerpc-isa205-ppr-dscr-vsx32l-ipa.o and powerpc-isa205-ppr-dscr-vsx64l-ipa.o. (powerpc*-*-linux*): Add powerpc-isa205-ppr-dscr-vsx32l.o and powerpc-isa205-ppr-dscr-vsx64l.o to srv_regobj, add rs6000/power-dscr.xml, rs6000/power-ppr.xml, rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml and rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml to srv_xmlfiles. * linux-ppc-tdesc-init.h (enum ppc_linux_tdesc) <PPC_TDESC_ISA205_PPR_DSCR_VSX>: New enum value. (init_registers_powerpc_isa205_ppr_dscr_vsx32l) (init_registers_powerpc_isa205_ppr_dscr_vsx64l): Declare. * linux-ppc-low.c: Include "elf/common.h" and <sys/uio.h>. (ppc_hwcap): Add comment. (ppc_hwcap2): New global. (ppc_check_regset, ppc_fill_pprregset, ppc_store_pprregset) (ppc_fill_dscrregset, ppc_store_dscrregset): New functions. (ppc_regsets): Add entries for the DSCR and PPR regsets. (ppc_arch_setup): Get AT_HWCAP2. Set ppr_dscr in features struct when needed. Set sizes for the the DSCR and PPR regsets. (ppc_get_ipa_tdesc_idx): Return PPC_TDESC_ISA205_PPR_DSCR_VSX. (initialize_low_arch): Call init_registers_powerpc_isa205_ppr_dscr_vsx32l and init_registers_powerpc_isa205_ppr_dscr_vsx64l. * linux-ppc-ipa.c (get_ipa_tdesc): Handle PPC_TDESC_ISA205_PPR_DSCR_VSX. (initialize_low_tracepoint): Call init_registers_powerpc_isa205_ppr_dscr_vsx32l and init_registers_powerpc_isa205_ppr_dscr_vsx64l. gdb/testsuite/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.arch/powerpc-ppr-dscr.c: New file. * gdb.arch/powerpc-ppr-dscr.exp: New file. gdb/doc/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.texinfo (PowerPC Features): Describe new features "org.gnu.gdb.power.ppr" and "org.gnu.gdb.power.dscr".
2018-10-26 20:37:54 +08:00
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
/* This isn't really an address. But ptrace thinks of it as one. */
CORE_ADDR regaddr = ppc_register_u_addr (gdbarch, regno);
int bytes_transferred;
gdb_byte buf[PPC_MAX_REGISTER_SIZE];
* alpha-tdep.c (alpha_heuristic_proc_start) (alpha_sigtramp_register_address): Add gdbarch as parameter. Replace current_gdbarch by gdbarch. (alpha_heuristic_frame_unwind_cache): Use get_frame_arch to get at the current architecture by frame_info. Update alpha_heuristic_proc_start call. (alpha_sigtramp_frame_this_id, alpha_sigtramp_frame_prev_register): Use get_frame_arch to get at the current architecture by frame_info. Update alpha_sigtramp_register_address call. * arm-tdep.c (thumb_scan_prologue): Add gdbarch as parameter and replace current_gdbarch by gdbarch. Update caller. (convert_to_extended, convert_from_extended): Add endianess parameter for comparison. Update caller. (arm_extract_return_value, arm_store_return_value): Use get_regcache_arch to get at the current architecture. * cris-tdep.c (cris_register_size): Add gdbarch as parameter. Replace current_gdbarch by gdbarch. Update caller. (cris_gdb_func, move_to_preg_op, none_reg_mode_move_from_preg_op): Add gdbarch as parameter. Update caller. Replace current_gdbarch by gdbarch. * h8300-tdep.c (E_PSEUDO_CCR_REGNUM, E_PSEUDO_EXR_REGNUM, BINWORD): Add gdbarch as parameter. Update caller. (h8300_init_frame_cache): Add gdbarch as parameter. Replace current_gdbarch by gdbarch. Update caller. * hppa-tdep.c (skip_prologue_hard_way): Add gdbarch as parameter and update caller. Replace current_gdbarch by gdbarch. * m32c-tdep.c (m32c_skip_trampoline_code): Use get_frame_arch to get at the current architecture. Replace current_gdbarch by gdbarch. * m68hc11-tdep.c (m68hc11_frame_unwind_cache): Likewise. (STACK_CORRECTION, USE_PAGE_REGISTER): Replace M6811_TDEP by its expression. Add gdbarch as parameter and replace current_gdbarch with it. Update caller. (M6811_TDEP): Remove. (m68hc11_frame_prev_register): Use get_frame_arch to get at the current architecture. (m68hc11_scan_prologue): Add gdbarch as parameter. Replace current_gdbarch by gdbarch. Update caller. * m68k-tdep.c (m68k_analyze_prologue): Add gdbarch as parameter and update caller. (m68k_analyze_register_saves): Likewise. Also replace current_gdbarch by gdbarch. * rs6000-tdep.c (skip_prologue): Add gdbarch as parameter and update caller. Relace current_gdbarch by gdbarch. (altivec_register_p, spe_register_p): Likewise. * ppc-tdep.h (altivec_register_p, spe_register_p): Add gdbarch as parameter. * ppc-linux-nat.c (fetch_register, store_register): Update caller of altivec_register_p and spe_register_p. * score-tdep.c (score_fetch_inst): Add gdbarch as parameter. Update caller. Replace current_gdbarch by gdbarch. (score_analyze_prologue): use get_frame_arch to get at the current architecture. * sparc-tdep.h (sparc_analyze_prologue): Add gdbarch as parameter. * sparc-tdep.c (sparc_analyze_prologue): Likewise. Replace current_gdbarch by gdbarch. Update caller. (sparc_frame_cache): Use get_frame_arch to get at the current architecture. * sparce64-tdep.c (sparc64_skip_prologue): Update call of sparc_analyze_prologue. * mn10300-tdep.c (mn10300_dwarf2_reg_to_regnum): Add gdbarch as parameter.
2008-01-11 22:43:15 +08:00
if (altivec_register_p (gdbarch, regno))
{
/* If this is the first time through, or if it is not the first
[gdb] Fix more typos in comments (2) Fix typos in comments. NFC. Tested on x86_64-linux. gdb/ChangeLog: 2019-10-26 Tom de Vries <tdevries@suse.de> * aarch64-linux-tdep.c: Fix typos in comments. * aarch64-tdep.c: Same. * ada-lang.c: Same. * amd64-nat.c: Same. * arc-tdep.c: Same. * arch/aarch64-insn.c: Same. * block.c: Same. * breakpoint.h: Same. * btrace.h: Same. * c-varobj.c: Same. * cli/cli-decode.c: Same. * cli/cli-script.c: Same. * cli/cli-utils.h: Same. * coff-pe-read.c: Same. * coffread.c: Same. * compile/compile-cplus-symbols.c: Same. * compile/compile-object-run.c: Same. * completer.c: Same. * corelow.c: Same. * cp-support.c: Same. * demangle.c: Same. * dwarf-index-write.c: Same. * dwarf2-frame.c: Same. * dwarf2-frame.h: Same. * eval.c: Same. * frame-base.h: Same. * frame.h: Same. * gdbcmd.h: Same. * gdbtypes.h: Same. * gnu-nat.c: Same. * guile/scm-objfile.c: Same. * i386-tdep.c: Same. * i386-tdep.h: Same. * infcall.c: Same. * infcall.h: Same. * linux-nat.c: Same. * m68k-tdep.c: Same. * macroexp.c: Same. * memattr.c: Same. * mi/mi-cmd-disas.c: Same. * mi/mi-getopt.h: Same. * mi/mi-main.c: Same. * minsyms.c: Same. * nat/aarch64-sve-linux-sigcontext.h: Same. * objfiles.h: Same. * ppc-linux-nat.c: Same. * ppc-linux-tdep.c: Same. * ppc-tdep.h: Same. * progspace.h: Same. * prologue-value.h: Same. * python/py-evtregistry.c: Same. * python/py-instruction.h: Same. * record-btrace.c: Same. * record-full.c: Same. * remote.c: Same. * rs6000-tdep.c: Same. * ser-tcp.c: Same. * sol-thread.c: Same. * sparc-sol2-tdep.c: Same. * sparc64-tdep.c: Same. * stabsread.c: Same. * symfile.c: Same. * symtab.h: Same. * target.c: Same. * tracepoint.c: Same. * tui/tui-data.h: Same. * tui/tui-io.c: Same. * tui/tui-win.c: Same. * tui/tui.c: Same. * unittests/rsp-low-selftests.c: Same. * user-regs.h: Same. * utils.c: Same. * utils.h: Same. * valarith.c: Same. * valops.c: Same. * valprint.c: Same. * valprint.h: Same. * value.c: Same. * value.h: Same. * varobj.c: Same. * x86-nat.h: Same. * xtensa-tdep.c: Same. gdb/gdbserver/ChangeLog: 2019-10-26 Tom de Vries <tdevries@suse.de> * linux-aarch64-low.c: Fix typos in comments. * linux-arm-low.c: Same. * linux-low.c: Same. * linux-ppc-low.c: Same. * proc-service.c: Same. * regcache.h: Same. * server.c: Same. * tracepoint.c: Same. * win32-low.c: Same. gdb/stubs/ChangeLog: 2019-10-26 Tom de Vries <tdevries@suse.de> * ia64vms-stub.c: Fix typos in comments. * m32r-stub.c: Same. * m68k-stub.c: Same. * sh-stub.c: Same. gdb/testsuite/ChangeLog: 2019-10-26 Tom de Vries <tdevries@suse.de> * gdb.base/bigcore.c: Fix typos in comments. * gdb.base/ctf-ptype.c: Same. * gdb.base/long_long.c: Same. * gdb.dwarf2/dw2-op-out-param.S: Same. * gdb.python/py-evthreads.c: Same. * gdb.reverse/i387-stack-reverse.c: Same. * gdb.trace/tfile.c: Same. * lib/compiler.c: Same. * lib/compiler.cc: Same. Change-Id: I8573d84a577894270179ae30f46c48d806fc1beb
2019-10-26 15:55:32 +08:00
time through, and we have confirmed that there is kernel
support for such a ptrace request, then go and fetch the
register. */
if (have_ptrace_getvrregs)
{
[PowerPC] Fix access to VSCR in linux targets The 4-byte VSCR register is found inside a 16-byte field in the regset returned by ptrace and in core files. The position of VSCR depends on the endianess of the target, which was previously assumed to be big-endian for the purpose of getting VSCR. This patch removes this assumption to fix access to VSCR in little-endian mode. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-tdep.h (struct ppc_reg_offsets): Remove vector register offset fields. * ppc-fbsd-tdep.c (ppc32_fbsd_reg_offsets): Remove initializers for vector register offset fields. (ppc64_fbsd_reg_offsets): Likewise. * ppc-nbsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-nat.c (_initialize_ppcobsd_nat): Remove assignment to vector register offset fields. * rs6000-aix-tdep.c (rs6000_aix32_reg_offsets): Remove initializers for vector register offset fields. (rs6000_aix64_reg_offsets): Likewise. * rs6000-tdep.c (ppc_vrreg_offset): Remove. (ppc_supply_vrregset): Remove. (ppc_collect_vrregset): Remove. * ppc-linux-tdep.c (ppc_linux_collect_vrregset): New function. (ppc_linux_vrregset) : New function. (ppc32_le_linux_vrregmap, ppc32_be_linux_vrregmap) (ppc32_le_linux_vrregset, ppc32_be_linux_vrregset): New globals. (ppc32_linux_vrregset): Remove. (ppc_linux_iterate_over_regset_sections): Call ppc_linux_vrregset and use result instead of ppc32_linux_vrregset. (ppc32_linux_reg_offsets): Remove initializers for vector register offset fields. (ppc64_linux_reg_offsets): Likewise. * ppc-linux-tdep.h (ppc_linux_vrregset): New declaration. * ppc-linux-nat.c: Include regset.h. (gdb_vrregset_t): Adjust comment to account for little-endian mode. (supply_vrregset, fill_vrregset): Remove. (fetch_altivec_register, store_altivec_register): Remove. (fetch_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to supply registers. (store_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to collect registers. (fetch_register): Call fetch_altivec_registers instead of fetch_altivec_register. (store_register): Call store_altivec_registers instead of store_altivec_register. (fetch_ppc_registers): Call fetch_altivec_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_altivec_registers with -1 for the new regno parameter. gdb/gdbserver/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * linux-ppc-low.c (ppc_fill_vrregset): Add vscr_offset variable. Set vscr_offset to 0 in little-endian mode and 12 in big-endian mode. Call collect_register_by_name with vscr using vscr_offset. Zero-pad vscr and vrsave fields in collector buffer. (ppc_store_vrregset): Add and set vscr_offset variable as in ppc_fill_vrregset. Call supply_register_by_name with vscr using vscr_offset.
2018-05-22 22:09:05 +08:00
fetch_altivec_registers (regcache, tid, regno);
return;
}
/* If we have discovered that there is no ptrace support for
AltiVec registers, fall through and return zeroes, because
regaddr will be -1 in this case. */
}
else if (vsx_register_p (gdbarch, regno))
* rs6000-tdep: Include "features/rs6000/powerpc-vsx32.c". Include "features/rs6000/powerpc-vsx64.c". (ppc_supply_vsxregset): New function. (ppc_collect_vsxregset): New function. (IS_VSX_PSEUDOREG): New macro. (IS_EFP_PSEUDOREG): New macro. (vsx_register_p): New function. (ppc_vsx_support_p): New function. (rs6000_builtin_type_vec128): New function. (rs6000_register_name): Hide upper halves of vs0~vs31. Return correct names for VSX registers and EFPR registers. (rs6000_pseudo_register_type): Return correct types for VSX and EFPR registers. (rs6000_pseudo_register_reggroup_p): Return correct group for VSX and EFPR registers. (ppc_pseudo_register_read): Rename to dfp_pseudo_register_read. (ppc_pseudo_register_write): Rename to dfp_pseudo_register_write. (vsx_pseudo_register_read): New function. (vsx_pseudo_register_write): New function. (efpr_pseudo_register_read): New function. (efpr_pseudo_register_write): New function. (rs6000_pseudo_register_read): Call new VSX and EFPR read functions. (rs6000_pseudo_register_write): Call new VSX and EFPR write functions. (rs6000_gdbarch_init): Declare have_vsx. Initialize new upper half VSX registers. Initialize VSX-related and EFPR-related pseudo-registers variables. Adjust the number of pseudo registers accordingly. * ppc-linux-nat.c: Define PTRACE_GETVSXREGS, PTRACE_SETVSXREGS and SIZEOF_VSRREGS. (gdb_vsxregset_t): New type. (have_ptrace_getsetvsxregs): New variable. (fetch_vsx_register): New function. (fetch_register): Handle VSX registers. (fetch_vsx_registers): New function. (fetch_ppc_registers): Handle VSX registers. (store_ppc_registers): Handle VSX registers. (store_vsx_register): New function. (store_register): Handle VSX registers. (store_vsx_registers): New function. (ppc_linux_read_description): Handle VSX-enabled inferiors. (gdb_vsxregset_t): New type. (supply_vsxregset): New function. (fill_vsxregset): New function. * ppc-tdep.h (vsx_register_p): New prototype. (vsx_support_p): New prototype. (ppc_vsr0_regnum): New variable. (ppc_vsr0_upper_regnum): Likewise. (ppc_efpr0_regnum): Likewise. (ppc_builtin_type_vec128): New type. (ppc_num_vsrs): New constant. (ppc_num_vshrs): New constant. (ppc_num_efprs): Likewise. Define POWERPC_VEC_VSX PPC_VSR0_UPPER_REGNUM and PPC_VSR31_UPPER_REGNUM. (ppc_supply_vsxregset): New prototype. (ppc_collect_vsxregset): New prototype. * ppc-linux-tdep.c: Include "features/rs6000/powerpc-vsx32l.c" Include "features/rs6000/powerpc-vsx64l.c". (_initialize_ppc_linux_tdep): Initialize VSX-enabled targets. (ppc_linux_regset_sections): Add new ".reg-ppc-vsx" field. (ppc32_linux_vsxregset): New 32-bit VSX-enabled regset. (ppc_linux_regset_from_core_section): Handle VSX core section. (ppc_linux_core_read_description): Support VSX-enabled core files. * ppc-linux-tdep.h: Declare *tdesc_powerpc_vsx32l Declare tdesc_powerpc_vsx64l * corelow.c (get_core_register_section): Support VSX-enabled core files. * features/rs6000/power-vsx.xml: New VSX descriptions. * features/rs6000/powerpc-vsx32.xml: New file. * features/rs6000/powerpc-vsx32l.xml: New file. * features/rs6000/powerpc-vsx64.xml: New file. * features/rs6000/powerpc-vsx64l.xml: New file. * features/rs6000/powerpc-vsx32.c: New file (generated). * features/rs6000/powerpc-vsx32l.c: New file (generated). * features/rs6000/powerpc-vsx64.c: New file (generated). * features/rs6000/powerpc-vsx64l.c: New file (generated). * features/Makefile: Updated with new descriptions. * regformats/rs6000/powerpc-vsx32l.dat: New file (generated). * regformats/rs6000/powerpc-vsx64l.dat: New file (generated). * testsuite/gdb.arch/vsx-regs.c: New source file. * testsuite/gdb.arch/vsx-regs.exp: New testcase. * testsuite/lib/gdb.exp (skip_vsx_tests): New function.
2008-08-15 23:18:34 +08:00
{
if (have_ptrace_getsetvsxregs)
{
[PowerPC] Fix VSX registers in linux core files The functions used by the VSX regset to collect and supply registers from core files where incorrect. This patch changes the regset to use the standard regset collect/supply functions to fix this. The native target is also changed to use the same regset. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-linux-tdep.c (ppc_linux_vsxregset): New function. (ppc32_linux_vsxregmap): New global. (ppc32_linux_vsxregset): Initialize with ppc32_linux_vsxregmap, regcache_supply_regset, and regcache_collect_regset. * ppc-linux-tdep.h (ppc_linux_vsxregset): Declare. * ppc-linux-nat.c (supply_vsxregset, fill_vsxregset): Remove. (fetch_vsx_register, store_vsx_register): Remove. (fetch_vsx_registers): Add regno parameter. Get regset using ppc_linux_vsxregset. Use regset to supply registers. (store_vsx_registers): Add regno parameter. Get regset using ppc_linux_vsxregset. Use regset to collect registers. (fetch_register): Call fetch_vsx_registers instead of fetch_vsx_register. (store_register): Call store_vsx_registers instead of store_vsx_register. (fetch_ppc_registers): Call fetch_vsx_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_vsx_registers with -1 for the new regno parameter. * rs6000-tdep.c (ppc_vsx_support_p, ppc_supply_vsxreget) (ppc_collect_vsxregset): Remove. gdb/testsuite/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * gdb.arch/powerpc-vsx-gcore.exp: New file.
2018-05-22 22:09:05 +08:00
fetch_vsx_registers (regcache, tid, regno);
* rs6000-tdep: Include "features/rs6000/powerpc-vsx32.c". Include "features/rs6000/powerpc-vsx64.c". (ppc_supply_vsxregset): New function. (ppc_collect_vsxregset): New function. (IS_VSX_PSEUDOREG): New macro. (IS_EFP_PSEUDOREG): New macro. (vsx_register_p): New function. (ppc_vsx_support_p): New function. (rs6000_builtin_type_vec128): New function. (rs6000_register_name): Hide upper halves of vs0~vs31. Return correct names for VSX registers and EFPR registers. (rs6000_pseudo_register_type): Return correct types for VSX and EFPR registers. (rs6000_pseudo_register_reggroup_p): Return correct group for VSX and EFPR registers. (ppc_pseudo_register_read): Rename to dfp_pseudo_register_read. (ppc_pseudo_register_write): Rename to dfp_pseudo_register_write. (vsx_pseudo_register_read): New function. (vsx_pseudo_register_write): New function. (efpr_pseudo_register_read): New function. (efpr_pseudo_register_write): New function. (rs6000_pseudo_register_read): Call new VSX and EFPR read functions. (rs6000_pseudo_register_write): Call new VSX and EFPR write functions. (rs6000_gdbarch_init): Declare have_vsx. Initialize new upper half VSX registers. Initialize VSX-related and EFPR-related pseudo-registers variables. Adjust the number of pseudo registers accordingly. * ppc-linux-nat.c: Define PTRACE_GETVSXREGS, PTRACE_SETVSXREGS and SIZEOF_VSRREGS. (gdb_vsxregset_t): New type. (have_ptrace_getsetvsxregs): New variable. (fetch_vsx_register): New function. (fetch_register): Handle VSX registers. (fetch_vsx_registers): New function. (fetch_ppc_registers): Handle VSX registers. (store_ppc_registers): Handle VSX registers. (store_vsx_register): New function. (store_register): Handle VSX registers. (store_vsx_registers): New function. (ppc_linux_read_description): Handle VSX-enabled inferiors. (gdb_vsxregset_t): New type. (supply_vsxregset): New function. (fill_vsxregset): New function. * ppc-tdep.h (vsx_register_p): New prototype. (vsx_support_p): New prototype. (ppc_vsr0_regnum): New variable. (ppc_vsr0_upper_regnum): Likewise. (ppc_efpr0_regnum): Likewise. (ppc_builtin_type_vec128): New type. (ppc_num_vsrs): New constant. (ppc_num_vshrs): New constant. (ppc_num_efprs): Likewise. Define POWERPC_VEC_VSX PPC_VSR0_UPPER_REGNUM and PPC_VSR31_UPPER_REGNUM. (ppc_supply_vsxregset): New prototype. (ppc_collect_vsxregset): New prototype. * ppc-linux-tdep.c: Include "features/rs6000/powerpc-vsx32l.c" Include "features/rs6000/powerpc-vsx64l.c". (_initialize_ppc_linux_tdep): Initialize VSX-enabled targets. (ppc_linux_regset_sections): Add new ".reg-ppc-vsx" field. (ppc32_linux_vsxregset): New 32-bit VSX-enabled regset. (ppc_linux_regset_from_core_section): Handle VSX core section. (ppc_linux_core_read_description): Support VSX-enabled core files. * ppc-linux-tdep.h: Declare *tdesc_powerpc_vsx32l Declare tdesc_powerpc_vsx64l * corelow.c (get_core_register_section): Support VSX-enabled core files. * features/rs6000/power-vsx.xml: New VSX descriptions. * features/rs6000/powerpc-vsx32.xml: New file. * features/rs6000/powerpc-vsx32l.xml: New file. * features/rs6000/powerpc-vsx64.xml: New file. * features/rs6000/powerpc-vsx64l.xml: New file. * features/rs6000/powerpc-vsx32.c: New file (generated). * features/rs6000/powerpc-vsx32l.c: New file (generated). * features/rs6000/powerpc-vsx64.c: New file (generated). * features/rs6000/powerpc-vsx64l.c: New file (generated). * features/Makefile: Updated with new descriptions. * regformats/rs6000/powerpc-vsx32l.dat: New file (generated). * regformats/rs6000/powerpc-vsx64l.dat: New file (generated). * testsuite/gdb.arch/vsx-regs.c: New source file. * testsuite/gdb.arch/vsx-regs.exp: New testcase. * testsuite/lib/gdb.exp (skip_vsx_tests): New function.
2008-08-15 23:18:34 +08:00
return;
}
}
* alpha-tdep.c (alpha_heuristic_proc_start) (alpha_sigtramp_register_address): Add gdbarch as parameter. Replace current_gdbarch by gdbarch. (alpha_heuristic_frame_unwind_cache): Use get_frame_arch to get at the current architecture by frame_info. Update alpha_heuristic_proc_start call. (alpha_sigtramp_frame_this_id, alpha_sigtramp_frame_prev_register): Use get_frame_arch to get at the current architecture by frame_info. Update alpha_sigtramp_register_address call. * arm-tdep.c (thumb_scan_prologue): Add gdbarch as parameter and replace current_gdbarch by gdbarch. Update caller. (convert_to_extended, convert_from_extended): Add endianess parameter for comparison. Update caller. (arm_extract_return_value, arm_store_return_value): Use get_regcache_arch to get at the current architecture. * cris-tdep.c (cris_register_size): Add gdbarch as parameter. Replace current_gdbarch by gdbarch. Update caller. (cris_gdb_func, move_to_preg_op, none_reg_mode_move_from_preg_op): Add gdbarch as parameter. Update caller. Replace current_gdbarch by gdbarch. * h8300-tdep.c (E_PSEUDO_CCR_REGNUM, E_PSEUDO_EXR_REGNUM, BINWORD): Add gdbarch as parameter. Update caller. (h8300_init_frame_cache): Add gdbarch as parameter. Replace current_gdbarch by gdbarch. Update caller. * hppa-tdep.c (skip_prologue_hard_way): Add gdbarch as parameter and update caller. Replace current_gdbarch by gdbarch. * m32c-tdep.c (m32c_skip_trampoline_code): Use get_frame_arch to get at the current architecture. Replace current_gdbarch by gdbarch. * m68hc11-tdep.c (m68hc11_frame_unwind_cache): Likewise. (STACK_CORRECTION, USE_PAGE_REGISTER): Replace M6811_TDEP by its expression. Add gdbarch as parameter and replace current_gdbarch with it. Update caller. (M6811_TDEP): Remove. (m68hc11_frame_prev_register): Use get_frame_arch to get at the current architecture. (m68hc11_scan_prologue): Add gdbarch as parameter. Replace current_gdbarch by gdbarch. Update caller. * m68k-tdep.c (m68k_analyze_prologue): Add gdbarch as parameter and update caller. (m68k_analyze_register_saves): Likewise. Also replace current_gdbarch by gdbarch. * rs6000-tdep.c (skip_prologue): Add gdbarch as parameter and update caller. Relace current_gdbarch by gdbarch. (altivec_register_p, spe_register_p): Likewise. * ppc-tdep.h (altivec_register_p, spe_register_p): Add gdbarch as parameter. * ppc-linux-nat.c (fetch_register, store_register): Update caller of altivec_register_p and spe_register_p. * score-tdep.c (score_fetch_inst): Add gdbarch as parameter. Update caller. Replace current_gdbarch by gdbarch. (score_analyze_prologue): use get_frame_arch to get at the current architecture. * sparc-tdep.h (sparc_analyze_prologue): Add gdbarch as parameter. * sparc-tdep.c (sparc_analyze_prologue): Likewise. Replace current_gdbarch by gdbarch. Update caller. (sparc_frame_cache): Use get_frame_arch to get at the current architecture. * sparce64-tdep.c (sparc64_skip_prologue): Update call of sparc_analyze_prologue. * mn10300-tdep.c (mn10300_dwarf2_reg_to_regnum): Add gdbarch as parameter.
2008-01-11 22:43:15 +08:00
else if (spe_register_p (gdbarch, regno))
{
* target.h (struct regcache): Add forward declaration. (struct target_ops): Add REGCACHE parameter to to_fetch_registers and to_store_registers target operations. (target_fetch_registers, target_store_registers): Update. * regcache.c (regcache_raw_read): Replace register_cached by regcache_valid_p. Pass regcache to target_fetch_registers. (regcache_raw_write): Pass regcache to target_store_registers. * arm-linux-nat.c (store_fpregister, store_fpregs, store_register, store_regs, store_wmmx_regs): Replace register_cached by regcache_valid_p. * bsd-kvm.c (bsd_kvm_open, bsd_kvm_proc_cmd): Pass current_regcache to target_fetch_registers calls. * corelow.c (core_open): Likewise. * linux-nat.c (linux_nat_corefile_thread_callback): Likewise. * proc-service.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * sol-thread.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * win32-nat.c (win32_resume): Likewise. * ia64-tdep.c (ia64_store_return_value): Pass current_regcache to target_store_registers call. * rs6000-tdep.c (rs6000_push_dummy_call): Likewise. * inferior.h (store_inferior_registers): Update prototype. (fetch_inferior_registers): Likewise. * gnu-nat.c (gnu_store_registers, gnu_fetch_registers): Likewise. * mips-linux-nat.c (super_fetch_registers, super_store_registers): Update function pointer signatures. * aix-thread.c (aix_thread_fetch_registers): Add REGCACHE parameter, use it instead of current_regcache, update calls. (aix_thread_store_registers): Likewise. * alphabsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * amd64bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_fpregister, fetch_fpregs, store_fpregister, store_fpregs, fetch_register, fetch_regs, store_register, store_regs, fetch_wmmx_regs, store_wmmx_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * armnbsd-nat.c (fetch_register, fetch_regs, fetch_fp_register, fetch_fp_regs, armnbsd_fetch_registers): Likewise. (store_register, store_regs, store_fp_register, store_fp_regs, armnbsd_store_registers): Likewise. * bsd-kvm.c (bsd_kvm_fetch_pcb, bsd_kvm_fetch_registers): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * corelow.c (get_core_registers): Likewise. * go32-nat.c (fetch_register, go32_fetch_registers, store_register, go32_store_registers): Likewise. * hppabsd-nat.c (hppabsd_fetch_registers): Likewise. (hppabsd_store_registers): Likewise. * hppa-hpux-nat.c (hppa_hpux_fetch_register): Likewise. (hppa_hpux_fetch_inferior_registers): Likewise. (hppa_hpux_store_register): Likewise. (hppa_hpux_store_inferior_registers): Likewise. * hppa-linux-nat.c (fetch_register, store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * hpux-thread.c (hpux_thread_fetch_registers): Likewise. (hpux_thread_store_registers): Likewise. * i386bsd-nat.c (i386bsd_fetch_inferior_registers): Likewise. (i386bsd_store_inferior_registers): Likewise. * i386gnu-nat.c (fetch_fpregs, gnu_fetch_registers, store_fpregs, gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register, store_register, fetch_regs, store_regs, fetch_fpregs, store_fpregs, fetch_fpxregs, store_fpxregs): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_register): Likewise. (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_register): Likewise. (ia64_linux_store_registers): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. (inf_child_store_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register): Likewise. (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_register): Likewise. (inf_ptrace_store_registers): Likewise. * infptrace.c (fetch_register, store_register): Likewise. (fetch_inferior_registers, store_inferior_registers): Likewise. * m32r-linux-nat.c (fetch_regs, store_regs): Likewise. (m32r_linux_fetch_inferior_registers): Likewise. (m32r_linux_store_inferior_registers): Likewise. * m68kbsd-nat.c (m68kbsd_fetch_inferior_registers): Likewise. (m68kbsd_store_inferior_registers): Likewise. * m68klinux-nat.c (fetch_register, old_fetch_inferior_registers, store_register, old_store_inferior_registers, fetch_regs, store_regs, fetch_fpregs, store_fpregs): Likewise. (m68k_linux_fetch_inferior_registers): Likewise. (m68k_linux_store_inferior_registers): Likewise. * m88kbsd-nat.c (m88kbsd_fetch_inferior_registers): Likewise. (m88kbsd_store_inferior_registers): Likewise. * mips64obsd-nat.c (mips64obsd_fetch_inferior_registers): Likewise. (mips64obsd_store_inferior_registers): Likewise. * mips-linux-nat.c (mips64_linux_regsets_fetch_registers): Likewise. (mips64_linux_regsets_store_registers): Likewise. (mips64_linux_fetch_registers): Likewise. (mips64_linux_store_registers): Likewise. * mipsnbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * monitor.c (monitor_fetch_register, monitor_store_register): Likewise. (monitor_fetch_registers, monitor_store_registers): Likewise. * nto-procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register, fetch_register, supply_vrregset, fetch_altivec_registers, fetch_ppc_registers, ppc_linux_fetch_inferior_registers): Likewise. (store_altivec_register, store_spe_register, store_register, fill_vrregset, store_altivec_registers, store_ppc_registers, ppc_linux_store_inferior_registers): Likewise. * ppcnbsd-nat.c (ppcnbsd_fetch_inferior_registers): Likewise. (ppcnbsd_store_inferior_registers): Likewise. * ppcobsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote.c (fetch_register_using_p, process_g_packet, fetch_registers_using_g, remote_fetch_registers): Likewise. (store_register_using_P, store_registers_using_G, remote_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers, m32r_fetch_register, m32r_store_register, m32r_store_register): Likewise. * remote-mips.c (mips_fetch_registers, mips_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * rs6000-nat.c (fetch_register, store_register): Likewise. (rs6000_fetch_inferior_registers): Likewise. (rs6000_store_inferior_registers): Likewise. * s390-nat.c (fetch_regs, store_regs): Likewise. (fetch_fpregs, store_fpregs): Likewise. (s390_linux_fetch_inferior_registers): Likewise. (s390_linux_store_inferior_registers): Likewise. * shnbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sol-thread.c (sol_thread_fetch_registers): Likewise. (sol_thread_store_registers): Likewise. * sparc-nat.c (fetch_inferior_registers): Likewise. (store_inferior_registers): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. (spu_store_inferior_registers): Likewise. * target.c (debug_print_register): Likewise. (debug_to_fetch_registers, debug_to_store_registers): Likewise. * vaxbsd-nat.c (vaxbsd_fetch_inferior_registers): Likewise. (vaxbsd_store_inferior_registers): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers): Likewise. (win32_fetch_inferior_registers): Likewise. (win32_store_inferior_registers): Likewise.
2007-05-06 22:34:38 +08:00
fetch_spe_register (regcache, tid, regno);
return;
}
[PowerPC] Add support for PPR and DSCR This patch adds gdb support for the Program Priorty Register and the Data Stream Control Register, for the powerpc linux native and core file targets, and for the powerpc linux server stub. gdb/ChangeLog: 2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * arch/ppc-linux-tdesc.h (tdesc_powerpc_isa205_ppr_dscr_vsx32l) (tdesc_powerpc_isa205_ppr_dscr_vsx64l): Declare. * arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_PPRREGSET) (PPC_LINUX_SIZEOF_DSCRREGSET): Define. (struct ppc_linux_features) <ppr_dscr>: New field. (ppc_linux_no_features): Add initializer for ppr_dscr field. * arch/ppc-linux-common.c (ppc_linux_match_description): Return new tdescs. * nat/ppc-linux.h (PPC_FEATURE2_DSCR, NT_PPC_PPR, NT_PPC_DSCR): Define if not already defined. * features/Makefile (WHICH): Add rs6000/powerpc-isa205-ppr-dscr-vsx32l and rs6000/powerpc-isa205-ppr-dscr-vsx64l. (XMLTOC): Add rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml and rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml. * features/rs6000/power-dscr.xml: New file. * features/rs6000/power-ppr.xml: New file. * features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml: New file. * features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml: New file. * features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.c: Generate. * features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.c: Generate. * regformats/rs6000/powerpc-isa205-ppr-dscr-vsx32l.dat: Generate. * regformats/rs6000/powerpc-isa205-ppr-dscr-vsx64l.dat: Generate. * ppc-linux-nat.c: Include <sys/uio.h>. (fetch_regset, store_regset, check_regset): New functions. (fetch_register, fetch_ppc_registers): Call fetch_regset with DSCR and PPR regsets. (store_register, store_ppc_registers): Call store_regset with DSCR and PPR regsets. (ppc_linux_get_hwcap2): New function. (ppc_linux_nat_target::read_description): Call ppc_linux_get_hwcap2 and check_regset, set ppr_dscr field in the features struct if needed. * ppc-linux-tdep.c: Include features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.c and features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.c. (ppc32_regmap_ppr, ppc32_regmap_dscr, ppc32_linux_pprregset) (ppc32_linux_dscrregset): New globals. (ppc_linux_iterate_over_regset_sections): Call back with the ppr and dscr regsets. (ppc_linux_core_read_description): Check if the ppr and dscr sections are present and set ppr_dscr in the features struct. (_initialize_ppc_linux_tdep): Call initialize_tdesc_powerpc_isa205_ppr_dscr_vsx32l and initialize_tdesc_powerpc_isa205_ppr_dscr_vsx64l. * ppc-linux-tdep.h (ppc32_linux_pprregset) (ppc32_linux_dscrregset): Declare. * ppc-tdep.h (struct gdbarch_tdep) <ppc_ppr_regnum>: New field. <ppc_dscr_regnum>: New field. (enum) <PPC_PPR_REGNUM, PPC_DSCR_REGNUM>: New enum values. * rs6000-tdep.c (rs6000_gdbarch_init): Look for and validate ppr and dscr features. (ppc_process_record_op31): Record changes to PPR and DSCR. gdb/gdbserver/ChangeLog: 2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * configure.srv (ipa_ppc_linux_regobj): Add powerpc-isa205-ppr-dscr-vsx32l-ipa.o and powerpc-isa205-ppr-dscr-vsx64l-ipa.o. (powerpc*-*-linux*): Add powerpc-isa205-ppr-dscr-vsx32l.o and powerpc-isa205-ppr-dscr-vsx64l.o to srv_regobj, add rs6000/power-dscr.xml, rs6000/power-ppr.xml, rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml and rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml to srv_xmlfiles. * linux-ppc-tdesc-init.h (enum ppc_linux_tdesc) <PPC_TDESC_ISA205_PPR_DSCR_VSX>: New enum value. (init_registers_powerpc_isa205_ppr_dscr_vsx32l) (init_registers_powerpc_isa205_ppr_dscr_vsx64l): Declare. * linux-ppc-low.c: Include "elf/common.h" and <sys/uio.h>. (ppc_hwcap): Add comment. (ppc_hwcap2): New global. (ppc_check_regset, ppc_fill_pprregset, ppc_store_pprregset) (ppc_fill_dscrregset, ppc_store_dscrregset): New functions. (ppc_regsets): Add entries for the DSCR and PPR regsets. (ppc_arch_setup): Get AT_HWCAP2. Set ppr_dscr in features struct when needed. Set sizes for the the DSCR and PPR regsets. (ppc_get_ipa_tdesc_idx): Return PPC_TDESC_ISA205_PPR_DSCR_VSX. (initialize_low_arch): Call init_registers_powerpc_isa205_ppr_dscr_vsx32l and init_registers_powerpc_isa205_ppr_dscr_vsx64l. * linux-ppc-ipa.c (get_ipa_tdesc): Handle PPC_TDESC_ISA205_PPR_DSCR_VSX. (initialize_low_tracepoint): Call init_registers_powerpc_isa205_ppr_dscr_vsx32l and init_registers_powerpc_isa205_ppr_dscr_vsx64l. gdb/testsuite/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.arch/powerpc-ppr-dscr.c: New file. * gdb.arch/powerpc-ppr-dscr.exp: New file. gdb/doc/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.texinfo (PowerPC Features): Describe new features "org.gnu.gdb.power.ppr" and "org.gnu.gdb.power.dscr".
2018-10-26 20:37:54 +08:00
else if (regno == PPC_DSCR_REGNUM)
{
gdb_assert (tdep->ppc_dscr_regnum != -1);
fetch_regset (regcache, tid, NT_PPC_DSCR,
PPC_LINUX_SIZEOF_DSCRREGSET,
&ppc32_linux_dscrregset);
return;
}
else if (regno == PPC_PPR_REGNUM)
{
gdb_assert (tdep->ppc_ppr_regnum != -1);
fetch_regset (regcache, tid, NT_PPC_PPR,
PPC_LINUX_SIZEOF_PPRREGSET,
&ppc32_linux_pprregset);
return;
}
[PowerPC] Add support for TAR This patch adds support for the Target Address Register for powerpc linux native and core file targets, and in the powerpc linux server stub. gdb/ChangeLog: 2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * arch/ppc-linux-tdesc.h (tdesc_powerpc_isa207_vsx32l) (tdesc_powerpc_isa207_vsx64l): Declare. * arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_TARREGSET): Define. (struct ppc_linux_features) <isa207>: New field. (ppc_linux_no_features): Add initializer for isa207 field. * arch/ppc-linux-common.c (ppc_linux_match_description): Return new tdescs. * nat/ppc-linux.h (PPC_FEATURE2_ARCH_2_07, PPC_FEATURE2_TAR) (NT_PPC_TAR): Define if not already defined. * features/Makefile (WHICH): Add rs6000/powerpc-isa207-vsx32l and rs6000/powerpc-isa207-vsx64l. (XMLTOC): Add rs6000/powerpc-isa207-vsx32l.xml and rs6000/powerpc-isa207-vsx64l.xml. * features/rs6000/power-tar.xml: New file. * features/rs6000/powerpc-isa207-vsx32l.xml: New file. * features/rs6000/powerpc-isa207-vsx64l.xml: New file. * features/rs6000/powerpc-isa207-vsx32l.c: Generate. * features/rs6000/powerpc-isa207-vsx64l.c: Generate. * regformats/rs6000/powerpc-isa207-vsx32l.dat: Generate. * regformats/rs6000/powerpc-isa207-vsx64l.dat: Generate. * ppc-linux-nat.c (fetch_register, fetch_ppc_registers): Call fetch_regset with the TAR regset. (store_register, store_ppc_registers): Call store_regset with the TAR regset. (ppc_linux_nat_target::read_description): Set isa207 field in the features struct if needed. * ppc-linux-tdep.c: Include features/rs6000/powerpc-isa207-vsx32l.c and features/rs6000/powerpc-isa207-vsx64l.c. (ppc32_regmap_tar, ppc32_linux_tarregset): New globals. (ppc_linux_iterate_over_regset_sections): Call back with the tar regset. (ppc_linux_core_read_description): Check if the tar section is present and set isa207 in the features struct. (_initialize_ppc_linux_tdep): Call initialize_tdesc_powerpc_isa207_vsx32l and initialize_tdesc_powerpc_isa207_vsx64l. * ppc-linux-tdep.h (ppc32_linux_tarregset): Declare. * ppc-tdep.h (gdbarch_tdep) <ppc_tar_regnum>: New field. (enum) <PPC_TAR_REGNUM>: New enum value. * rs6000-tdep.c (rs6000_gdbarch_init): Look for and validate tar feature. (ppc_process_record_op31): Record changes to TAR. gdb/gdbserver/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * configure.srv (ipa_ppc_linux_regobj): Add powerpc-isa207-vsx64l-ipa.o and powerpc-isa207-vsx32l-ipa.o. (powerpc*-*-linux*): Add powerpc-isa207-vsx32l.o and powerpc-isa207-vsx64l.o to srv_regobj, add rs6000/power-tar.xml, rs6000/powerpc-isa207-vsx32l.xml, and rs6000/powerpc-isa207-vsx64l.xml to srv_xmlfiles. * linux-ppc-tdesc-init.h (enum ppc_linux_tdesc) <PPC_TDESC_ISA207_VSX>: New enum value. (init_registers_powerpc_isa207_vsx32l): Declare. (init_registers_powerpc_isa207_vsx64l): Declare. * linux-ppc-low.c (ppc_fill_tarregset): New function. (ppc_store_tarregset): New function. (ppc_regsets): Add entry for the TAR regset. (ppc_arch_setup): Set isa207 in features struct when needed. Set size for the TAR regsets. (ppc_get_ipa_tdesc_idx): Return PPC_TDESC_ISA207_VSX. (initialize_low_arch): Call init_registers_powerpc_isa207_vsx32l and init_registers_powerpc_isa207_vsx64l. * linux-ppc-ipa.c (get_ipa_tdesc): Handle PPC_TDESC_ISA207_VSX. (initialize_low_tracepoint): Call init_registers_powerpc_isa207_vsx32l and init_registers_powerpc_isa207_vsx64l. gdb/testsuite/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.arch/powerpc-tar.c: New file. * gdb.arch/powerpc-tar.exp: New file. gdb/doc/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.texinfo (PowerPC Features): Describe new feature "org.gnu.gdb.power.tar".
2018-10-26 20:37:54 +08:00
else if (regno == PPC_TAR_REGNUM)
{
gdb_assert (tdep->ppc_tar_regnum != -1);
fetch_regset (regcache, tid, NT_PPC_TAR,
PPC_LINUX_SIZEOF_TARREGSET,
&ppc32_linux_tarregset);
return;
}
[PowerPC] Add support for EBB and PMU registers This patch adds support for registers of the Event Based Branching and Performance Monitoring Units for the powerpc linux native and core file targets, and for the powerpc linux server stub. All three EBB registers are accessible. Only a subset of the PMU registers can be accessed through ptrace. Because of this, the PMU registers are enumerated individually in gdbarch_tdep, as opposed to having a single "have_pmu" flag. This is intended to make it easier to add additional PMU registers in the future, since checking a "have_pmu" flag elsewhere in the code would no longer be correct. The tdesc feature is named org.gnu.gdb.power.linux.pmu because of this. It's unclear if it makes sense to save and restore these registers across function calls, since some of them can be modified asynchronously. They are also not tracked in record-replay mode. The kernel can return ENODATA when ptrace is used to get the EBB registers, unless a linux performance event that uses EBB is open in the inferior. For this reason, the "fill" functions in the server stub for the ebb register sets is not implemented. Since gdbserver writes all registers in one go before resuming the inferior, this error would not be detected at the time the user tries to write to one of the registers on the client side, and gdbserver would print out warnings every time it resumes the inferior when no ebb performance event is opened, so there is currently no straightforward way to handle this case. This means the ebb registers in the client-side regcache can become dirty when the user tries to write to them, until the inferior is resumed and stopped again. A related issue is that 'G' packets used to write to unrelated registers will include bad data for the EBB registers if they are unavailable, since no register status information is included in the 'G' packet. This data won't be written to the inferior by the gdbserver stub because the "fill" functions are not implemented, and currently the gdbserver stub doesn't change the status of the registers in its own regcache in response to 'G' packets. Another limitation for the ebb registers is that traceframes don't record if registers are available or not, so if these registers are collected when a tracepoint is hit and the inferior has no ebb event opened, the user will see zero values for all of them, instead of the usual <unavailable>. Because these registers are often unavailable, trying to store them with target_store_registers with -1 for the regno argument (all registers) would almost always fail, so they are ignored in this case. gdb/ChangeLog: 2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_EBBREGSET) (PPC_LINUX_SIZEOF_PMUREGSET): Declare. * nat/ppc-linux.h (PPC_FEATURE2_EBB, NT_PPC_EBB, NT_PPC_PMU): Define if not already defined. * features/rs6000/power-ebb.xml: New file. * features/rs6000/power-linux-pmu.xml: New file. * features/rs6000/powerpc-isa207-vsx32l.xml: Include ebb and pmu features. * features/rs6000/powerpc-isa207-vsx64l.xml: Likewise. * features/rs6000/powerpc-isa207-vsx32l.c: Re-generate. * features/rs6000/powerpc-isa207-vsx64l.c: Re-generate. * regformats/rs6000/powerpc-isa207-vsx32l.dat: Re-generate. * regformats/rs6000/powerpc-isa207-vsx64l.dat: Re-generate. * ppc-linux-nat.c (fetch_register, fetch_ppc_registers): Call fetch_regset with ebb and pmu regsets. (store_register, store_ppc_registers): Call store_regset with ebb and pmu regsets. (ppc_linux_nat_target::read_description): Set isa207 field in the features struct if ebb and pmu are avaiable. * ppc-linux-tdep.c (ppc32_regmap_ebb, ppc32_regmap_pmu) (ppc32_linux_ebbregset, ppc32_linux_pmuregset): New globals. (ppc_linux_iterate_over_regset_sections): Call back with the ebb and pmu regsets. (ppc_linux_core_read_description): Check if the pmu section is present and set isa207 in the features struct. * ppc-linux-tdep.h (ppc32_linux_ebbregset) (ppc32_linux_pmuregset): Declare. * ppc-tdep.h (struct gdbarch_tdep) <ppc_mmcr0_regnum>: New field. <ppc_mmcr2_regnum, ppc_siar_regnum, ppc_sdar_regnum>: New fields. <ppc_sier_regnum>: New field. (enum): <PPC_BESCR_REGNUM, PPC_EBBHR_REGNUM, PPC_EBBRR_REGNUM>: New enum values. <PPC_MMCR0_REGNUM, PPC_MMCR2_REGNUM, PPC_SIAR_REGNUM>: New enum values. <PPC_SDAR_REGNUM, PPC_SIER_REGNUM>: New enum values. (PPC_IS_EBB_REGNUM, PPC_IS_PMU_REGNUM): Define. * rs6000-tdep.c (rs6000_gdbarch_init): Look for and validate the ebb and pmu features. gdb/gdbserver/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * configure.srv (powerpc*-*-linux*): Add rs6000/power-ebb.xml and rs6000/power-linux-pmu.xml to srv_xmlfiles. * linux-ppc-low.c (ppc_store_ebbregset, ppc_fill_pmuregset) (ppc_store_pmuregset): New functions. (ppc_regsets): Add entries for ebb and pmu regsets. (ppc_arch_setup): Set isa207 in features struct if the ebb and pmu regsets are available. Set sizes for these regsets. gdb/doc/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.texinfo (PowerPC Features): Describe new features "org.gnu.gdb.power.ebb" and "org.gnu.gdb.power.linux.pmu".
2018-10-26 20:37:54 +08:00
else if (PPC_IS_EBB_REGNUM (regno))
{
gdb_assert (tdep->have_ebb);
fetch_regset (regcache, tid, NT_PPC_EBB,
PPC_LINUX_SIZEOF_EBBREGSET,
&ppc32_linux_ebbregset);
return;
}
else if (PPC_IS_PMU_REGNUM (regno))
{
gdb_assert (tdep->ppc_mmcr0_regnum != -1);
fetch_regset (regcache, tid, NT_PPC_PMU,
PPC_LINUX_SIZEOF_PMUREGSET,
&ppc32_linux_pmuregset);
return;
}
[PowerPC] Add support for HTM registers This patch adds support for Hardware Transactional Memory registers for the powerpc linux native and core file targets, and for the pwoerpc linux server stub. These registers include both the HTM special-purpose registers (TFHAR, TEXASR and TFIAR) as well as the set of registers that are checkpointed (saved) when a transaction is initiated, which the processor restores in the event of a transaction failure. The set of checkpointed general-purpose registers is returned by the linux kernel in the same format as the regular general-purpose registers, defined in struct pt_regs. However, the architecture specifies that only some of the registers present in pt_regs are checkpointed (GPRs 0-31, CR, XER, LR and CTR). The kernel fills the slots for MSR and NIP with other info. The other fields usually don't have meaningful values. GDB doesn't define registers that are not checkpointed in the architecture, but when generating a core file, GDB fills the slot for the checkpointed MSR with the regular MSR. These are usually similar, although some bits might be different, and in some cases the checkpointed MSR will have a value of 0 in a kernel-generated core-file. The checkpointed NIP is filled with TFHAR by GDB in the core-file, which is what the kernel does. The other fields are set to 0 by GDB. Core files generated by the kernel have a note section for checkpointed GPRs with the same size for both 32-bit and 64-bit threads, and the values for the registers of a 32-bit thread are squeezed in the first half, with no useful data in the second half. GDB generates a smaller note section for 32-bit threads, but can read both sizes. The checkpointed XER is required to be 32-bit in the target description documentation, even though the more recent ISAs define it as 64-bit wide, since the high-order 32-bits are reserved, and because in Linux there is no way to get a 64-bit checkpointed XER for 32-bit threads. If this changes in the future, the target description feature requirement can be relaxed to allow for a 64-bit checkpointed XER. Access to the checkpointed CR (condition register) can be confusing. The architecture only specifies that CR fields 1 to 7 (the 24 least significant bits) are checkpointed, but the kernel provides all 8 fields (32 bits). The value of field 0 is not masked by ptrace, so it will sometimes show the result of some kernel operation, probably treclaim., which sets this field. The checkpointed registers are marked not to be saved and restored. Inferior function calls during an active transaction don't work well, and it's unclear what should be done in this case. TEXASR and TFIAR can be altered asynchronously, during transaction failure recording, so they are also not saved and restored. For consistency neither is TFHAR. Record and replay also doesn't work well when transactions are involved. This patch doesn't address this, so the values of the HTM SPRs will sometimes be innacurate when the record/relay target is enabled. For instance, executing a "tbegin." alters TFHAR and TEXASR, but these changes are not currently recorded. Because the checkpointed registers are only available when a transaction is active (or suspended), ptrace can return ENODATA when gdb tries to read these registers and the inferior is not in a transactional state. The registers are set to the unavailable state when this happens. When gbd tries to write to one of these registers, and it is unavailable, an error is raised. The "fill" functions for checkpointed register sets in the server stub are not implemented for the same reason as for the EBB register set, since ptrace can also return ENODATA for checkpointed regsets. The same issues with 'G' packets apply here. Just like for the EBB registers, tracepoints will not mark the checkpointed registers as unavailable if the inferior was not in a transaction, so their content will also show 0 instead of <unavailable> when inspecting trace data. The new tests record the values of the regular registers before stepping the inferior through a "tbegin." instruction to start a transaction, then the checkpointed registers are checked against the recorded pre-transactional values. New values are written to the checkpointed registers and recorded, the inferior continues until the transaction aborts (which is usually immediately when it is resumed), and the regular registers are checked against the recorded values, because the abort should have reverted the registers to these values. Like for the EBB registers, target_store_registers will ignore the checkpointed registers when called with -1 as the regno argument (store all registers in one go). gdb/ChangeLog: 2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * arch/ppc-linux-tdesc.h (tdesc_powerpc_isa207_htm_vsx32l) (tdesc_powerpc_isa207_htm_vsx64l): Declare. * arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_TM_SPRREGSET) (PPC32_LINUX_SIZEOF_CGPRREGSET, PPC64_LINUX_SIZEOF_CGPRREGSET) (PPC_LINUX_SIZEOF_CFPRREGSET, PPC_LINUX_SIZEOF_CVMXREGSET) (PPC_LINUX_SIZEOF_CVSXREGSET, PPC_LINUX_SIZEOF_CPPRREGSET) (PPC_LINUX_SIZEOF_CDSCRREGSET, PPC_LINUX_SIZEOF_CTARREGSET): Define. (struct ppc_linux_features) <htm>: New field. (ppc_linux_no_features): Add initializer for htm field. * arch/ppc-linux-common.c (ppc_linux_match_description): Return new tdescs. * nat/ppc-linux.h (PPC_FEATURE2_HTM, NT_PPC_TM_CGPR) (NT_PPC_TM_CFPR, NT_PPC_TM_CVMX, NT_PPC_TM_CVSX) (NT_PPC_TM_SPR, NT_PPC_TM_CTAR, NT_PPC_TM_CPPR, NT_PPC_TM_CDSCR): Define if not already defined. * features/Makefile (WHICH): Add rs6000/powerpc-isa207-htm-vsx32l and rs6000/powerpc-isa207-htm-vsx64l. (XMLTOC): Add rs6000/powerpc-isa207-htm-vsx32l.xml and rs6000/powerpc-isa207-htm-vsx64l.xml. * features/rs6000/power-htm-spr.xml: New file. * features/rs6000/power-htm-core.xml: New file. * features/rs6000/power64-htm-core.xml: New file. * features/rs6000/power-htm-fpu.xml: New file. * features/rs6000/power-htm-altivec.xml: New file. * features/rs6000/power-htm-vsx.xml: New file. * features/rs6000/power-htm-ppr.xml: New file. * features/rs6000/power-htm-dscr.xml: New file. * features/rs6000/power-htm-tar.xml: New file. * features/rs6000/powerpc-isa207-htm-vsx32l.xml: New file. * features/rs6000/powerpc-isa207-htm-vsx64l.xml: New file. * features/rs6000/powerpc-isa207-htm-vsx32l.c: Generate. * features/rs6000/powerpc-isa207-htm-vsx64l.c: Generate. * regformats/rs6000/powerpc-isa207-htm-vsx32l.dat: Generate. * regformats/rs6000/powerpc-isa207-htm-vsx64l.dat: Generate. * ppc-linux-nat.c (fetch_register, fetch_ppc_registers): Call fetch_regset with HTM regsets. (store_register, store_ppc_registers): Call store_regset with HTM regsets. (ppc_linux_nat_target::read_description): Set htm field in the features struct if needed. * ppc-linux-tdep.c: Include features/rs6000/powerpc-isa207-htm-vsx32l.c and features/rs6000/powerpc-isa207-htm-vsx64l.c. (ppc32_regmap_tm_spr, ppc32_regmap_cgpr, ppc64_le_regmap_cgpr) (ppc64_be_regmap_cgpr, ppc32_regmap_cfpr, ppc32_le_regmap_cvmx) (ppc32_be_regmap_cvmx, ppc32_regmap_cvsx, ppc32_regmap_cppr) (ppc32_regmap_cdscr, ppc32_regmap_ctar): New globals. (ppc32_linux_tm_sprregset, ppc32_linux_cgprregset) (ppc64_be_linux_cgprregset, ppc64_le_linux_cgprregset) (ppc32_linux_cfprregset, ppc32_le_linux_cvmxregset) (ppc32_be_linux_cvmxregset, ppc32_linux_cvsxregset) (ppc32_linux_cpprregset, ppc32_linux_cdscrregset) (ppc32_linux_ctarregset): New globals. (ppc_linux_cgprregset, ppc_linux_cvmxregset): New functions. (ppc_linux_collect_core_cpgrregset): New function. (ppc_linux_iterate_over_regset_sections): Call back with the htm regsets. (ppc_linux_core_read_description): Check if the tm spr section is present and set htm in the features struct. (_initialize_ppc_linux_tdep): Call initialize_tdesc_powerpc_isa207_htm_vsx32l and initialize_tdesc_powerpc_isa207_htm_vsx64l. * ppc-linux-tdep.h (ppc_linux_cgprregset, ppc_linux_cvmxregset): Declare. (ppc32_linux_tm_sprregset, ppc32_linux_cfprregset) (ppc32_linux_cvsxregset, ppc32_linux_cpprregset) (ppc32_linux_cdscrregset, ppc32_linux_ctarregset): Declare. * ppc-tdep.h (struct gdbarch_tdep) <have_htm_spr, have_htm_core>: New fields. <have_htm_fpu, have_htm_altivec, have_htm_vsx>: Likewise. <ppc_cppr_regnum, ppc_cdscr_regnum, ppc_ctar_regnum>: Likewise. <ppc_cdl0_regnum, ppc_cvsr0_regnum, ppc_cefpr0_regnum>: Likewise. (enum) <PPC_TFHAR_REGNUM, PPC_TEXASR_REGNUM, PPC_TFIAR_REGNUM>: New enum fields. <PPC_CR0_REGNUM, PPC_CCR_REGNUM, PPC_CXER_REGNUM>: Likewise. <PPC_CLR_REGNUM, PPC_CCTR_REGNUM, PPC_CF0_REGNUM>: Likewise. <PPC_CFPSCR_REGNUM, PPC_CVR0_REGNUM, PPC_CVSCR_REGNUM>: Likewise. <PPC_CVRSAVE_REGNUM, PPC_CVSR0_UPPER_REGNUM>: Likewise. <PPC_CPPR_REGNUM, PPC_CDSCR_REGNUM>: Likewise. <PPC_CTAR_REGNUM>: Likewise. (PPC_IS_TMSPR_REGNUM, PPC_IS_CKPTGP_REGNUM, PPC_IS_CKPTFP_REGNUM) (PPC_IS_CKPTVMX_REGNUM, PPC_IS_CKPTVSX_REGNUM): Define. * rs6000-tdep.c (IS_CDFP_PSEUDOREG, IS_CVSX_PSEUDOREG) (IS_CEFP_PSEUDOREG): Define. (rs6000_register_name): Hide the upper halves of checkpointed VSX registers. Return names for the checkpointed DFP, VSX, and EFP pseudo registers. (rs6000_pseudo_register_type): Remove initial assert and raise an internal error in the else clause instead. Return types for the checkpointed DFP, VSX, and EFP pseudo registers. (dfp_pseudo_register_read, dfp_pseudo_register_write): Handle checkpointed DFP pseudo registers. (vsx_pseudo_register_read, vsx_pseudo_register_write): Handle checkpointed VSX pseudo registers. (efp_pseudo_register_read, efp_pseudo_register_write): Rename from efpr_pseudo_register_read and efpr_pseudo_register_write. Handle checkpointed EFP pseudo registers. (rs6000_pseudo_register_read, rs6000_pseudo_register_write): Handle checkpointed DFP, VSX, and EFP registers. (dfp_ax_pseudo_register_collect, vsx_ax_pseudo_register_collect) (efp_ax_pseudo_register_collect): New functions. (rs6000_ax_pseudo_register_collect): Move DFP, VSX and EFP pseudo register logic to new functions. Handle checkpointed DFP, VSX, and EFP pseudo registers. (rs6000_gdbarch_init): Look for and validate the htm features. Include checkpointed DFP, VSX and EFP pseudo-registers. * NEWS: Mention access to PPR, DSCR, TAR, EBB/PMU registers and HTM registers. gdb/gdbserver/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * configure.srv (ipa_ppc_linux_regobj): Add powerpc-isa207-htm-vsx32l-ipa.o and powerpc-isa207-htm-vsx64l-ipa.o. (powerpc*-*-linux*): Add powerpc-isa207-htm-vsx32l.o and powerpc-isa207-htm-vsx64l.o to srv_regobj. Add rs6000/power-htm-spr.xml, rs6000/power-htm-core.xml, rs6000/power64-htm-core.xml, rs6000/power-htm-fpu.xml, rs6000/power-htm-altivec.xml, rs6000/power-htm-vsx.xml, rs6000/power-htm-ppr.xml, rs6000/power-htm-dscr.xml, rs6000/power-htm-tar.xml, rs6000/powerpc-isa207-htm-vsx32l.xml, and rs6000/powerpc-isa207-htm-vsx64l.xml to srv_xmlfiles. * linux-ppc-tdesc-init.h (enum ppc_linux_tdesc) <PPC_TDESC_ISA207_HTM_VSX>: New enum value. (init_registers_powerpc_isa207_htm_vsx32l) (init_registers_powerpc_isa207_htm_vsx64l): Declare. * linux-ppc-low.c (ppc_fill_tm_sprregset, ppc_store_tm_sprregset) (ppc_store_tm_cgprregset, ppc_store_tm_cfprregset) (ppc_store_tm_cvrregset, ppc_store_tm_cvsxregset) (ppc_store_tm_cpprregset, ppc_store_tm_cdscrregset) (ppc_store_tm_ctarregset): New functions. (ppc_regsets): Add entries for HTM regsets. (ppc_arch_setup): Set htm in features struct when needed. Set sizes for the HTM regsets. (ppc_get_ipa_tdesc_idx): Return PPC_TDESC_ISA207_HTM_VSX. (initialize_low_arch): Call init_registers_powerpc_isa207_htm_vsx32l and init_registers_powerpc_isa207_htm_vsx64l. * linux-ppc-ipa.c (get_ipa_tdesc): Handle PPC_TDESC_ISA207_HTM_VSX. (initialize_low_tracepoint): Call init_registers_powerpc_isa207_htm_vsx32l and init_registers_powerpc_isa207_htm_vsx64l. gdb/testsuite/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.arch/powerpc-htm-regs.c: New file. * gdb.arch/powerpc-htm-regs.exp: New file. gdb/doc/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.texinfo (PowerPC Features): Describe new features "org.gnu.gdb.power.htm.spr", "org.gnu.gdb.power.htm.core", "org.gnu.gdb.power.htm.fpu", "org.gnu.gdb.power.htm.altivec", "org.gnu.gdb.power.htm.vsx", "org.gnu.gdb.power.htm.ppr", "org.gnu.gdb.power.htm.dscr", "org.gnu.gdb.power.htm.tar".
2018-10-26 20:37:55 +08:00
else if (PPC_IS_TMSPR_REGNUM (regno))
{
gdb_assert (tdep->have_htm_spr);
fetch_regset (regcache, tid, NT_PPC_TM_SPR,
PPC_LINUX_SIZEOF_TM_SPRREGSET,
&ppc32_linux_tm_sprregset);
return;
}
else if (PPC_IS_CKPTGP_REGNUM (regno))
{
gdb_assert (tdep->have_htm_core);
const struct regset *cgprregset = ppc_linux_cgprregset (gdbarch);
fetch_regset (regcache, tid, NT_PPC_TM_CGPR,
(tdep->wordsize == 4?
PPC32_LINUX_SIZEOF_CGPRREGSET
: PPC64_LINUX_SIZEOF_CGPRREGSET),
cgprregset);
return;
}
else if (PPC_IS_CKPTFP_REGNUM (regno))
{
gdb_assert (tdep->have_htm_fpu);
fetch_regset (regcache, tid, NT_PPC_TM_CFPR,
PPC_LINUX_SIZEOF_CFPRREGSET,
&ppc32_linux_cfprregset);
return;
}
else if (PPC_IS_CKPTVMX_REGNUM (regno))
{
gdb_assert (tdep->have_htm_altivec);
const struct regset *cvmxregset = ppc_linux_cvmxregset (gdbarch);
fetch_regset (regcache, tid, NT_PPC_TM_CVMX,
PPC_LINUX_SIZEOF_CVMXREGSET,
cvmxregset);
return;
}
else if (PPC_IS_CKPTVSX_REGNUM (regno))
{
gdb_assert (tdep->have_htm_vsx);
fetch_regset (regcache, tid, NT_PPC_TM_CVSX,
PPC_LINUX_SIZEOF_CVSXREGSET,
&ppc32_linux_cvsxregset);
return;
}
else if (regno == PPC_CPPR_REGNUM)
{
gdb_assert (tdep->ppc_cppr_regnum != -1);
fetch_regset (regcache, tid, NT_PPC_TM_CPPR,
PPC_LINUX_SIZEOF_CPPRREGSET,
&ppc32_linux_cpprregset);
return;
}
else if (regno == PPC_CDSCR_REGNUM)
{
gdb_assert (tdep->ppc_cdscr_regnum != -1);
fetch_regset (regcache, tid, NT_PPC_TM_CDSCR,
PPC_LINUX_SIZEOF_CDSCRREGSET,
&ppc32_linux_cdscrregset);
return;
}
else if (regno == PPC_CTAR_REGNUM)
{
gdb_assert (tdep->ppc_ctar_regnum != -1);
fetch_regset (regcache, tid, NT_PPC_TM_CTAR,
PPC_LINUX_SIZEOF_CTARREGSET,
&ppc32_linux_ctarregset);
return;
}
if (regaddr == -1)
{
2007-11-16 Markus Deuling <deuling@de.ibm.com> * m32r-rom.c (m32r_supply_register): Use get_regcache_arch to get at the current architecture by regcache. * ppcnbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register) (fetch_register, supply_vrregset, fetch_ppc_registers) (store_altivec_register, store_spe_register, store_register) (fill_vrregset, store_ppc_registers): Likewise. * ppcobsd-nat.c (ppcobsd_supply_pcb): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers) (do_win32_store_inferior_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers) (m32r_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register, gdbsim_store_register): Likewise. * trad-frame.c (trad_frame_alloc_saved_regs): Replace current_gdbarch by gdbarch. * user-regs.c (user_reg_map_name_to_regnum): Likewise. * ppc-sysv-tdep.c (ppc_sysv_abi_push_dummy_call) (do_ppc_sysv_return_value, ppc64_sysv_abi_push_dummy_call) (ppc64_sysv_abi_return_value): Likewise. * m32c-tdep.c (m32c_register_reggroup_p): Likewise. * m2-lang.c (build_m2_types): Likewise. * ppc-linux-tdep.c (ppc_linux_sigtramp_cache * ppcnbsd-tdep.c (ppcnbsd_sigtramp_cache_init): Likewise. * ppcobsd-tdep.c (ppcobsd_sigtramp_frame_cache): Likewise. * rs6000-tdep.c (ppc_dwarf2_frame_init_reg): Likewise. * m68hc11-tdep.c (m68hc11_frame_unwind_cache): Use get_frame_arch to get at the current architecture by frame_info. * gcore.c (derive_stack_segment): Likewise. * shnbsd-nat.c (GETREGS_SUPPLIES): Add gdbarch parameter. (shnbsd_fetch_inferior_registers, shnbsd_store_inferior_registers): Add gdbarch to GETREGS_SUPPLIES call.
2007-11-16 12:53:46 +08:00
memset (buf, '\0', register_size (gdbarch, regno)); /* Supply zeroes */
regcache->raw_supply (regno, buf);
return;
}
/* Read the raw register using sizeof(long) sized chunks. On a
32-bit platform, 64-bit floating-point registers will require two
transfers. */
for (bytes_transferred = 0;
2007-11-16 Markus Deuling <deuling@de.ibm.com> * m32r-rom.c (m32r_supply_register): Use get_regcache_arch to get at the current architecture by regcache. * ppcnbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register) (fetch_register, supply_vrregset, fetch_ppc_registers) (store_altivec_register, store_spe_register, store_register) (fill_vrregset, store_ppc_registers): Likewise. * ppcobsd-nat.c (ppcobsd_supply_pcb): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers) (do_win32_store_inferior_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers) (m32r_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register, gdbsim_store_register): Likewise. * trad-frame.c (trad_frame_alloc_saved_regs): Replace current_gdbarch by gdbarch. * user-regs.c (user_reg_map_name_to_regnum): Likewise. * ppc-sysv-tdep.c (ppc_sysv_abi_push_dummy_call) (do_ppc_sysv_return_value, ppc64_sysv_abi_push_dummy_call) (ppc64_sysv_abi_return_value): Likewise. * m32c-tdep.c (m32c_register_reggroup_p): Likewise. * m2-lang.c (build_m2_types): Likewise. * ppc-linux-tdep.c (ppc_linux_sigtramp_cache * ppcnbsd-tdep.c (ppcnbsd_sigtramp_cache_init): Likewise. * ppcobsd-tdep.c (ppcobsd_sigtramp_frame_cache): Likewise. * rs6000-tdep.c (ppc_dwarf2_frame_init_reg): Likewise. * m68hc11-tdep.c (m68hc11_frame_unwind_cache): Use get_frame_arch to get at the current architecture by frame_info. * gcore.c (derive_stack_segment): Likewise. * shnbsd-nat.c (GETREGS_SUPPLIES): Add gdbarch parameter. (shnbsd_fetch_inferior_registers, shnbsd_store_inferior_registers): Add gdbarch to GETREGS_SUPPLIES call.
2007-11-16 12:53:46 +08:00
bytes_transferred < register_size (gdbarch, regno);
bytes_transferred += sizeof (long))
{
long l;
errno = 0;
l = ptrace (PTRACE_PEEKUSER, tid, (PTRACE_TYPE_ARG3) regaddr, 0);
regaddr += sizeof (long);
if (errno != 0)
{
char message[128];
xsnprintf (message, sizeof (message), "reading register %s (#%d)",
gdbarch_register_name (gdbarch, regno), regno);
perror_with_name (message);
}
memcpy (&buf[bytes_transferred], &l, sizeof (l));
}
/* Now supply the register. Keep in mind that the regcache's idea
of the register's size may not be a multiple of sizeof
(long). */
2007-11-16 Markus Deuling <deuling@de.ibm.com> * m32r-rom.c (m32r_supply_register): Use get_regcache_arch to get at the current architecture by regcache. * ppcnbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register) (fetch_register, supply_vrregset, fetch_ppc_registers) (store_altivec_register, store_spe_register, store_register) (fill_vrregset, store_ppc_registers): Likewise. * ppcobsd-nat.c (ppcobsd_supply_pcb): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers) (do_win32_store_inferior_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers) (m32r_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register, gdbsim_store_register): Likewise. * trad-frame.c (trad_frame_alloc_saved_regs): Replace current_gdbarch by gdbarch. * user-regs.c (user_reg_map_name_to_regnum): Likewise. * ppc-sysv-tdep.c (ppc_sysv_abi_push_dummy_call) (do_ppc_sysv_return_value, ppc64_sysv_abi_push_dummy_call) (ppc64_sysv_abi_return_value): Likewise. * m32c-tdep.c (m32c_register_reggroup_p): Likewise. * m2-lang.c (build_m2_types): Likewise. * ppc-linux-tdep.c (ppc_linux_sigtramp_cache * ppcnbsd-tdep.c (ppcnbsd_sigtramp_cache_init): Likewise. * ppcobsd-tdep.c (ppcobsd_sigtramp_frame_cache): Likewise. * rs6000-tdep.c (ppc_dwarf2_frame_init_reg): Likewise. * m68hc11-tdep.c (m68hc11_frame_unwind_cache): Use get_frame_arch to get at the current architecture by frame_info. * gcore.c (derive_stack_segment): Likewise. * shnbsd-nat.c (GETREGS_SUPPLIES): Add gdbarch parameter. (shnbsd_fetch_inferior_registers, shnbsd_store_inferior_registers): Add gdbarch to GETREGS_SUPPLIES call.
2007-11-16 12:53:46 +08:00
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
{
/* Little-endian values are always found at the left end of the
bytes transferred. */
regcache->raw_supply (regno, buf);
}
2007-11-16 Markus Deuling <deuling@de.ibm.com> * m32r-rom.c (m32r_supply_register): Use get_regcache_arch to get at the current architecture by regcache. * ppcnbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register) (fetch_register, supply_vrregset, fetch_ppc_registers) (store_altivec_register, store_spe_register, store_register) (fill_vrregset, store_ppc_registers): Likewise. * ppcobsd-nat.c (ppcobsd_supply_pcb): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers) (do_win32_store_inferior_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers) (m32r_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register, gdbsim_store_register): Likewise. * trad-frame.c (trad_frame_alloc_saved_regs): Replace current_gdbarch by gdbarch. * user-regs.c (user_reg_map_name_to_regnum): Likewise. * ppc-sysv-tdep.c (ppc_sysv_abi_push_dummy_call) (do_ppc_sysv_return_value, ppc64_sysv_abi_push_dummy_call) (ppc64_sysv_abi_return_value): Likewise. * m32c-tdep.c (m32c_register_reggroup_p): Likewise. * m2-lang.c (build_m2_types): Likewise. * ppc-linux-tdep.c (ppc_linux_sigtramp_cache * ppcnbsd-tdep.c (ppcnbsd_sigtramp_cache_init): Likewise. * ppcobsd-tdep.c (ppcobsd_sigtramp_frame_cache): Likewise. * rs6000-tdep.c (ppc_dwarf2_frame_init_reg): Likewise. * m68hc11-tdep.c (m68hc11_frame_unwind_cache): Use get_frame_arch to get at the current architecture by frame_info. * gcore.c (derive_stack_segment): Likewise. * shnbsd-nat.c (GETREGS_SUPPLIES): Add gdbarch parameter. (shnbsd_fetch_inferior_registers, shnbsd_store_inferior_registers): Add gdbarch to GETREGS_SUPPLIES call.
2007-11-16 12:53:46 +08:00
else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
{
/* Big-endian values are found at the right end of the bytes
transferred. */
2007-11-16 Markus Deuling <deuling@de.ibm.com> * m32r-rom.c (m32r_supply_register): Use get_regcache_arch to get at the current architecture by regcache. * ppcnbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register) (fetch_register, supply_vrregset, fetch_ppc_registers) (store_altivec_register, store_spe_register, store_register) (fill_vrregset, store_ppc_registers): Likewise. * ppcobsd-nat.c (ppcobsd_supply_pcb): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers) (do_win32_store_inferior_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers) (m32r_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register, gdbsim_store_register): Likewise. * trad-frame.c (trad_frame_alloc_saved_regs): Replace current_gdbarch by gdbarch. * user-regs.c (user_reg_map_name_to_regnum): Likewise. * ppc-sysv-tdep.c (ppc_sysv_abi_push_dummy_call) (do_ppc_sysv_return_value, ppc64_sysv_abi_push_dummy_call) (ppc64_sysv_abi_return_value): Likewise. * m32c-tdep.c (m32c_register_reggroup_p): Likewise. * m2-lang.c (build_m2_types): Likewise. * ppc-linux-tdep.c (ppc_linux_sigtramp_cache * ppcnbsd-tdep.c (ppcnbsd_sigtramp_cache_init): Likewise. * ppcobsd-tdep.c (ppcobsd_sigtramp_frame_cache): Likewise. * rs6000-tdep.c (ppc_dwarf2_frame_init_reg): Likewise. * m68hc11-tdep.c (m68hc11_frame_unwind_cache): Use get_frame_arch to get at the current architecture by frame_info. * gcore.c (derive_stack_segment): Likewise. * shnbsd-nat.c (GETREGS_SUPPLIES): Add gdbarch parameter. (shnbsd_fetch_inferior_registers, shnbsd_store_inferior_registers): Add gdbarch to GETREGS_SUPPLIES call.
2007-11-16 12:53:46 +08:00
size_t padding = (bytes_transferred - register_size (gdbarch, regno));
regcache->raw_supply (regno, buf + padding);
}
else
internal_error (__FILE__, __LINE__,
2005-02-11 Andrew Cagney <cagney@gnu.org> Mark up error_no_arg, query, perror_with_name, complaint, and internal_error. * breakpoint.c, cp-abi.c, cp-namespace.c, cp-support.c: Update. * cris-tdep.c, dbxread.c, dictionary.c, dsrec.c: Update. * dummy-frame.c, dve3900-rom.c, dwarf2-frame.c, dwarf2expr.c: Update. * dwarf2read.c, dwarfread.c, elfread.c, event-loop.c: Update. * exceptions.c, exec.c, f-lang.c, findvar.c, fork-child.c: Update. * frame-unwind.c, frame.c, frv-linux-tdep.c, frv-tdep.c: Update. * gdb_assert.h, gdbarch.c, gdbtypes.c, gnu-nat.c: Update. * go32-nat.c, hppa-tdep.c, hppabsd-nat.c, hpread.c: Update. * i386-linux-nat.c, i386-nat.c, i386-tdep.c, i386bsd-nat.c: Update. * i386fbsd-nat.c, inf-ptrace.c, inf-ttrace.c, infcall.c: Update. * infcmd.c, inflow.c, infptrace.c, infrun.c, inftarg.c: Update. * interps.c, language.c, linespec.c, linux-nat.c: Update. * m32r-linux-nat.c, m68k-tdep.c, m68kbsd-nat.c: Update. * m68klinux-nat.c, m88kbsd-nat.c, macroexp.c, macroscope.c: Update. * macrotab.c, maint.c, mdebugread.c, memattr.c: Update. * mips-linux-tdep.c, mips-tdep.c, mips64obsd-nat.c: Update. * mipsnbsd-nat.c, mn10300-tdep.c, monitor.c, nto-procfs.c: Update. * objc-lang.c, objfiles.c, objfiles.h, ocd.c, osabi.c: Update. * parse.c, ppc-bdm.c, ppc-linux-nat.c, ppc-sysv-tdep.c: Update. * ppcnbsd-nat.c, ppcobsd-nat.c, printcmd.c, procfs.c: Update. * regcache.c, reggroups.c, remote-e7000.c, remote-mips.c: Update. * remote-rdp.c, remote-sds.c, remote-sim.c, remote-st.c: Update. * remote-utils.c, remote.c, rs6000-nat.c, rs6000-tdep.c: Update. * s390-nat.c, s390-tdep.c, sentinel-frame.c, serial.c: Update. * sh-tdep.c, sh3-rom.c, sh64-tdep.c, shnbsd-nat.c: Update. * solib-aix5.c, solib-svr4.c, solib.c, source.c: Update. * sparc-nat.c, stabsread.c, stack.c, symfile.c, symtab.c: Update. * symtab.h, target.c, tracepoint.c, ui-file.c, ui-out.c: Update. * utils.c, valops.c, valprint.c, vax-nat.c, vaxbsd-nat.c: Update. * win32-nat.c, xcoffread.c, xstormy16-tdep.c: Update. * cli/cli-cmds.c, cli/cli-logging.c, cli/cli-script.c: Update. * cli/cli-setshow.c, mi/mi-cmd-break.c, mi/mi-cmds.c: Update. * mi/mi-console.c, mi/mi-getopt.c, mi/mi-out.c: Update. * tui/tui-file.c, tui/tui-interp.c: Update.
2005-02-12 02:13:55 +08:00
_("fetch_register: unexpected byte order: %d"),
2007-11-16 Markus Deuling <deuling@de.ibm.com> * m32r-rom.c (m32r_supply_register): Use get_regcache_arch to get at the current architecture by regcache. * ppcnbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register) (fetch_register, supply_vrregset, fetch_ppc_registers) (store_altivec_register, store_spe_register, store_register) (fill_vrregset, store_ppc_registers): Likewise. * ppcobsd-nat.c (ppcobsd_supply_pcb): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers) (do_win32_store_inferior_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers) (m32r_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register, gdbsim_store_register): Likewise. * trad-frame.c (trad_frame_alloc_saved_regs): Replace current_gdbarch by gdbarch. * user-regs.c (user_reg_map_name_to_regnum): Likewise. * ppc-sysv-tdep.c (ppc_sysv_abi_push_dummy_call) (do_ppc_sysv_return_value, ppc64_sysv_abi_push_dummy_call) (ppc64_sysv_abi_return_value): Likewise. * m32c-tdep.c (m32c_register_reggroup_p): Likewise. * m2-lang.c (build_m2_types): Likewise. * ppc-linux-tdep.c (ppc_linux_sigtramp_cache * ppcnbsd-tdep.c (ppcnbsd_sigtramp_cache_init): Likewise. * ppcobsd-tdep.c (ppcobsd_sigtramp_frame_cache): Likewise. * rs6000-tdep.c (ppc_dwarf2_frame_init_reg): Likewise. * m68hc11-tdep.c (m68hc11_frame_unwind_cache): Use get_frame_arch to get at the current architecture by frame_info. * gcore.c (derive_stack_segment): Likewise. * shnbsd-nat.c (GETREGS_SUPPLIES): Add gdbarch parameter. (shnbsd_fetch_inferior_registers, shnbsd_store_inferior_registers): Add gdbarch to GETREGS_SUPPLIES call.
2007-11-16 12:53:46 +08:00
gdbarch_byte_order (gdbarch));
}
/* This function actually issues the request to ptrace, telling
it to get all general-purpose registers and put them into the
specified regset.
If the ptrace request does not exist, this function returns 0
and properly sets the have_ptrace_* flag. If the request fails,
this function calls perror_with_name. Otherwise, if the request
succeeds, then the regcache gets filled and 1 is returned. */
static int
fetch_all_gp_regs (struct regcache *regcache, int tid)
{
gdb_gregset_t gregset;
if (ptrace (PTRACE_GETREGS, tid, 0, (void *) &gregset) < 0)
{
if (errno == EIO)
{
have_ptrace_getsetregs = 0;
return 0;
}
perror_with_name (_("Couldn't get general-purpose registers."));
}
supply_gregset (regcache, (const gdb_gregset_t *) &gregset);
return 1;
}
/* This is a wrapper for the fetch_all_gp_regs function. It is
responsible for verifying if this target has the ptrace request
that can be used to fetch all general-purpose registers at one
shot. If it doesn't, then we should fetch them using the
old-fashioned way, which is to iterate over the registers and
request them one by one. */
static void
fetch_gp_regs (struct regcache *regcache, int tid)
{
s/get_regcache_arch (regcache)/regcache->arch ()/g This patches removes get_regcache_arch, and use regache->arch () instead. The motivation of this change is that I am going to move some basic stuff into a base class of regcache. I don't need to update "client" code regcache->arch (). On the other hand, this patch shortens the code a little bit. gdb: 2017-10-25 Yao Qi <yao.qi@linaro.org> * aarch32-linux-nat.c (aarch32_gp_regcache_supply): Use regcache->arch () instead get_regcache_arch. * aarch64-fbsd-nat.c (aarch64_fbsd_fetch_inferior_registers): Likewise. (aarch64_fbsd_store_inferior_registers): Likewise. * aarch64-linux-nat.c (fetch_gregs_from_thread): Likewise. (store_gregs_to_thread): Likewise. (fetch_fpregs_from_thread): Likewise. (store_fpregs_to_thread): Likewise. * aarch64-tdep.c (aarch64_extract_return_value): Likewise. (aarch64_store_return_value): Likewise. (aarch64_software_single_step): Likewise. * aix-thread.c (aix_thread_wait): Likewise. (supply_reg32): Likewise. (supply_sprs64): Likewise. (supply_sprs32): Likewise. (fill_gprs64): Likewise. (fill_gprs32): Likewise. (fill_sprs64): Likewise. (fill_sprs32): Likewise. (store_regs_user_thread): Likewise. (store_regs_kernel_thread): Likewise. * alpha-bsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * alpha-tdep.c (alpha_extract_return_value): Likewise. (alpha_store_return_value): Likewise. (alpha_deal_with_atomic_sequence): Likewise. (alpha_next_pc): Likewise. (alpha_software_single_step): Likewise. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * amd64-nat.c (amd64_supply_native_gregset): Likewise. (amd64_collect_native_gregset): Likewise. * amd64-obsd-tdep.c (amd64obsd_supply_uthread): Likewise. (amd64obsd_collect_uthread): Likewise. * amd64-tdep.c (amd64_supply_fpregset): Likewise. (amd64_collect_fpregset): Likewise. (amd64_supply_fxsave): Likewise. (amd64_supply_xsave): Likewise. (amd64_collect_fxsave): Likewise. (amd64_collect_xsave): Likewise. * arc-tdep.c (arc_write_pc): Likewise. * arch-utils.c (default_skip_permanent_breakpoint): Likewise. * arm-fbsd-nat.c (arm_fbsd_fetch_inferior_registers): Likewise. (arm_fbsd_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_vfp_regs): Likewise. (store_vfp_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * arm-linux-tdep.c (arm_linux_supply_gregset): Likewise. (arm_linux_sigreturn_next_pc): Likewise. (arm_linux_get_next_pcs_syscall_next_pc): Likewise. * arm-nbsd-nat.c (arm_supply_gregset): Likewise. (fetch_register): Likewise. (store_register): Likewise. * arm-tdep.c (arm_is_thumb): Likewise. (displaced_in_arm_mode): Likewise. (bx_write_pc): Likewise. (arm_get_next_pcs_addr_bits_remove): Likewise. (arm_software_single_step): Likewise. (arm_extract_return_value): Likewise. (arm_store_return_value): Likewise. (arm_write_pc): Likewise. * bfin-tdep.c (bfin_extract_return_value): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * core-regset.c (fetch_core_registers): Likewise. * corelow.c (get_core_registers): Likewise. * cris-tdep.c (cris_store_return_value): Likewise. (cris_extract_return_value): Likewise. (find_step_target): Likewise. (find_step_target): Likewise. (cris_software_single_step): Likewise. * ctf.c (ctf_fetch_registers): Likewise. * darwin-nat.c (cancel_breakpoint): Likewise. * fbsd-tdep.c (fbsd_collect_thread_registers): Likewise. * frv-tdep.c (frv_extract_return_value): Likewise. * ft32-tdep.c (ft32_store_return_value): Likewise. (ft32_extract_return_value): Likewise. * go32-nat.c (fetch_register): Likewise. (go32_fetch_registers): Likewise. (go32_store_registers): Likewise. (store_register): Likewise. * h8300-tdep.c (h8300_extract_return_value): Likewise. (h8300_store_return_value): Likewise. * hppa-linux-nat.c (fetch_register): Likewise. (store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * i386-darwin-nat.c (i386_darwin_fetch_inferior_registers): Likewise. (i386_darwin_store_inferior_registers): Likewise. * i386-gnu-nat.c (gnu_fetch_registers): Likewise. (gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register): Likewise. (store_register): Likewise. (supply_gregset): Likewise. (fill_gregset): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. (i386_linux_resume): Likewise. * i386-linux-tdep.c (i386_linux_get_syscall_number_from_regcache): Likewise. * i386-nto-tdep.c (i386nto_supply_gregset): Likewise. * i386-obsd-nat.c (i386obsd_supply_pcb): Likewise. * i386-obsd-tdep.c (i386obsd_supply_uthread): Likewise. (i386obsd_collect_uthread): Likewise. * i386-tdep.c (i386_mmx_regnum_to_fp_regnum): Likewise. (i386_supply_gregset): Likewise. (i386_collect_gregset): Likewise. (i386_supply_fpregset): Likewise. (i386_collect_fpregset): Likewise. (i386_mpx_bd_base): Likewise. * i386-v4-nat.c (supply_fpregset): Likewise. (fill_fpregset): Likewise. * i387-tdep.c (i387_supply_fsave): Likewise. (i387_collect_fsave): Likewise. (i387_supply_fxsave): Likewise. (i387_collect_fxsave): Likewise. (i387_supply_xsave): Likewise. (i387_collect_xsave): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_registers): Likewise. * ia64-tdep.c (ia64_access_rse_reg): Likewise. (ia64_extract_return_value): Likewise. (ia64_store_return_value): Likewise. (find_func_descr): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_registers): Likewise. * infrun.c (use_displaced_stepping): Likewise. (displaced_step_prepare_throw): Likewise. (resume): Likewise. (proceed): Likewise. (do_target_wait): Likewise. (adjust_pc_after_break): Likewise. (handle_inferior_event_1): Likewise. (handle_signal_stop): Likewise. (save_infcall_suspend_state): Likewise. (restore_infcall_suspend_state): Likewise. * iq2000-tdep.c (iq2000_extract_return_value): Likewise. * jit.c (jit_frame_prev_register): Likewise. * linux-nat.c (save_stop_reason): Likewise. (linux_nat_wait_1): Likewise. (resume_stopped_resumed_lwps): Likewise. * linux-record.c (record_linux_sockaddr): Likewise. (record_linux_msghdr): Likewise. (record_linux_system_call): Likewise. * linux-tdep.c (linux_collect_thread_registers): Likewise. * lm32-tdep.c (lm32_extract_return_value): Likewise. (lm32_store_return_value): Likewise. * m32c-tdep.c (m32c_read_flg): Likewise. (m32c_pseudo_register_read): Likewise. (m32c_pseudo_register_write): Likewise. * m32r-linux-tdep.c (m32r_linux_supply_gregset): Likewise. (m32r_linux_collect_gregset): Likewise. * m32r-tdep.c (m32r_store_return_value): Likewise. (m32r_extract_return_value): Likewise. * m68k-bsd-nat.c (m68kbsd_supply_fpregset): Likewise. (m68kbsd_collect_fpregset): Likewise. * m68k-bsd-tdep.c (m68kbsd_supply_fpregset): Likewise. * m68k-linux-nat.c (fetch_register): Likewise. (old_fetch_inferior_registers): Likewise. (old_store_inferior_registers): Likewise. (store_regs): Likewise. * m68k-tdep.c (m68k_svr4_extract_return_value): Likewise. (m68k_svr4_store_return_value): Likewise. * m88k-tdep.c (m88k_store_arguments): Likewise. * mi/mi-main.c (mi_cmd_data_list_changed_registers): Likewise. (mi_cmd_data_write_register_values): Likewise. * mips-fbsd-nat.c (mips_fbsd_fetch_inferior_registers): Likewise. (mips_fbsd_store_inferior_registers): Likewise. * mips-fbsd-tdep.c (mips_fbsd_supply_fpregs): Likewise. (mips_fbsd_supply_gregs): Likewise. (mips_fbsd_collect_fpregs): Likewise. (mips_fbsd_collect_gregs): Likewise. (mips_fbsd_supply_fpregset): Likewise. (mips_fbsd_collect_fpregset): Likewise. (mips_fbsd_supply_gregset): Likewise. (mips_fbsd_collect_gregset): Likewise. * mips-linux-nat.c (supply_gregset): Likewise. (fill_gregset): Likewise. (supply_fpregset): Likewise. (fill_fpregset): Likewise. * mips-linux-tdep.c (mips_supply_gregset): Likewise. (mips_fill_gregset): Likewise. (mips_supply_fpregset): Likewise. (mips_fill_fpregset): Likewise. (mips64_supply_gregset): Likewise. (micromips_linux_sigframe_validate): Likewise. * mips-nbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * mips-nbsd-tdep.c (mipsnbsd_supply_fpregset): Likewise. (mipsnbsd_supply_gregset): Likewise. (mipsnbsd_iterate_over_regset_sections): Likewise. (mipsnbsd_supply_reg): Likewise. (mipsnbsd_supply_fpreg): Likewise. * mips-tdep.c (mips_in_frame_stub): Likewise. (mips_dummy_id): Likewise. (is_octeon_bbit_op): Likewise. (micromips_bc1_pc): Likewise. (extended_mips16_next_pc): Likewise. (mips16_next_pc): Likewise. (deal_with_atomic_sequence): Likewise. * moxie-tdep.c (moxie_process_readu): Likewise. * nios2-tdep.c (nios2_get_next_pc): Likewise. * nto-procfs.c (procfs_store_registers): Likewise. * ppc-fbsd-nat.c (ppcfbsd_fetch_inferior_registers): Likewise. (ppcfbsd_store_inferior_registers): Likewise. * ppc-linux-nat.c (fetch_vsx_register): Likewise. (fetch_altivec_register): Likewise. (get_spe_registers): Likewise. (fetch_spe_register): Likewise. (fetch_altivec_registers): Likewise. (fetch_all_gp_regs): Likewise. (fetch_all_fp_regs): Likewise. (store_vsx_register): Likewise. (store_altivec_register): Likewise. (set_spe_registers): Likewise. (store_spe_register): Likewise. (store_altivec_registers): Likewise. (store_all_gp_regs): Likewise. (store_all_fp_regs): Likewise. * ppc-linux-tdep.c (ppc_linux_supply_gregset): Likewise. (ppc_linux_collect_gregset): Likewise. (ppc_canonicalize_syscall): Likewise. (ppc_linux_record_signal): Likewise. (ppu2spu_prev_register): Likewise. * ppc-nbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-obsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * ppc-ravenscar-thread.c (ppc_ravenscar_generic_fetch_registers): Likewise. (ppc_ravenscar_generic_store_registers): Likewise. * procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ravenscar-thread.c (ravenscar_fetch_registers): Likewise. (ravenscar_store_registers): Likewise. (ravenscar_prepare_to_store): Likewise. * record-btrace.c (record_btrace_fetch_registers): Likewise. * record-full.c (record_full_wait_1): Likewise. (record_full_registers_change): Likewise. (record_full_store_registers): Likewise. (record_full_core_fetch_registers): Likewise. (record_full_save): Likewise. (record_full_goto_insn): Likewise. * regcache.c (regcache_register_size): Likewise. (get_regcache_arch): Remove. (regcache_read_pc): Likewise. * regcache.h (get_regcache_arch): Remove. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * remote.c (fetch_register_using_p): Likewise. (send_g_packet): Likewise. (remote_prepare_to_store): Likewise. (store_registers_using_G): Likewise. * reverse.c (save_bookmark_command): Likewise. (goto_bookmark_command): Likewise. * rs6000-aix-tdep.c (branch_dest): Likewise. * rs6000-nat.c (rs6000_ptrace64): Likewise. (fetch_register): Likewise. * rs6000-tdep.c (ppc_supply_reg): Likewise. (ppc_collect_reg): Likewise. (ppc_collect_gregset): Likewise. (ppc_collect_fpregset): Likewise. (ppc_collect_vsxregset): Likewise. (ppc_collect_vrregset): Likewise. (ppc_displaced_step_hw_singlestep): Likewise. (rs6000_pseudo_register_read): Likewise. (rs6000_pseudo_register_write): Likewise. * s390-linux-nat.c (supply_gregset): Likewise. (fill_gregset): Likewise. (s390_linux_fetch_inferior_registers): Likewise. * s390-linux-tdep.c (s390_write_pc): Likewise. (s390_software_single_step): Likewise. (s390_all_but_pc_registers_record): Likewise. (s390_linux_syscall_record): Likewise. * sentinel-frame.c (sentinel_frame_prev_arch): Likewise. * sh-nbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sh-tdep.c (sh_extract_return_value_nofpu): Likewise. (sh_extract_return_value_fpu): Likewise. (sh_store_return_value_nofpu): Likewise. (sh_corefile_supply_regset): Likewise. (sh_corefile_collect_regset): Likewise. * sh64-tdep.c (sh64_extract_return_value): Likewise. (sh64_store_return_value): Likewise. * sparc-linux-tdep.c (sparc32_linux_collect_core_fpregset): Likewise. * sparc-nat.c (sparc_fetch_inferior_registers): Likewise. (sparc_store_inferior_registers): Likewise. * sparc-ravenscar-thread.c (register_in_thread_descriptor_p): Likewise. (sparc_ravenscar_prepare_to_store): Likewise. * sparc-tdep.c (sparc32_store_arguments): Likewise. (sparc_analyze_control_transfer): Likewise. (sparc_step_trap): Likewise. (sparc_software_single_step): Likewise. (sparc32_gdbarch_init): Likewise. (sparc_supply_rwindow): Likewise. (sparc_collect_rwindow): Likewise. * sparc64-linux-tdep.c (sparc64_linux_collect_core_fpregset): Likewise. * sparc64-nbsd-nat.c (sparc64nbsd_supply_gregset): Likewise. (sparc64nbsd_collect_gregset): Likewise. (sparc64nbsd_supply_fpregset): Likewise. (sparc64nbsd_collect_fpregset): Likewise. * sparc64-tdep.c (sparc64_store_arguments): Likewise. (sparc64_supply_gregset): Likewise. (sparc64_collect_gregset): Likewise. (sparc64_supply_fpregset): Likewise. (sparc64_collect_fpregset): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. * spu-tdep.c (spu_unwind_sp): Likewise. (spu2ppu_prev_register): Likewise. (spu_memory_remove_breakpoint): Likewise. * stack.c (return_command): Likewise. * tic6x-tdep.c (tic6x_extract_signed_field): Likewise. * tracefile-tfile.c (tfile_fetch_registers): Likewise. * tracefile.c (trace_save_ctf): Likewise. * windows-nat.c (do_windows_fetch_inferior_registers): Likewise. (do_windows_store_inferior_registers): Likewise. (windows_resume): Likewise. * xtensa-linux-nat.c (fill_gregset): Likewise. (supply_gregset_reg): Likewise. * xtensa-tdep.c (xtensa_register_write_masked): Likewise. (xtensa_register_read_masked): Likewise. (xtensa_supply_gregset): Likewise. (xtensa_extract_return_value): Likewise. (xtensa_store_return_value): Likewise.
2017-10-25 23:37:03 +08:00
struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int i;
if (have_ptrace_getsetregs)
if (fetch_all_gp_regs (regcache, tid))
return;
/* If we've hit this point, it doesn't really matter which
architecture we are using. We just need to read the
registers in the "old-fashioned way". */
for (i = 0; i < ppc_num_gprs; i++)
fetch_register (regcache, tid, tdep->ppc_gp0_regnum + i);
}
/* This function actually issues the request to ptrace, telling
it to get all floating-point registers and put them into the
specified regset.
If the ptrace request does not exist, this function returns 0
and properly sets the have_ptrace_* flag. If the request fails,
this function calls perror_with_name. Otherwise, if the request
succeeds, then the regcache gets filled and 1 is returned. */
static int
fetch_all_fp_regs (struct regcache *regcache, int tid)
{
gdb_fpregset_t fpregs;
if (ptrace (PTRACE_GETFPREGS, tid, 0, (void *) &fpregs) < 0)
{
if (errno == EIO)
{
have_ptrace_getsetfpregs = 0;
return 0;
}
perror_with_name (_("Couldn't get floating-point registers."));
}
supply_fpregset (regcache, (const gdb_fpregset_t *) &fpregs);
return 1;
}
/* This is a wrapper for the fetch_all_fp_regs function. It is
responsible for verifying if this target has the ptrace request
that can be used to fetch all floating-point registers at one
shot. If it doesn't, then we should fetch them using the
old-fashioned way, which is to iterate over the registers and
request them one by one. */
static void
fetch_fp_regs (struct regcache *regcache, int tid)
{
s/get_regcache_arch (regcache)/regcache->arch ()/g This patches removes get_regcache_arch, and use regache->arch () instead. The motivation of this change is that I am going to move some basic stuff into a base class of regcache. I don't need to update "client" code regcache->arch (). On the other hand, this patch shortens the code a little bit. gdb: 2017-10-25 Yao Qi <yao.qi@linaro.org> * aarch32-linux-nat.c (aarch32_gp_regcache_supply): Use regcache->arch () instead get_regcache_arch. * aarch64-fbsd-nat.c (aarch64_fbsd_fetch_inferior_registers): Likewise. (aarch64_fbsd_store_inferior_registers): Likewise. * aarch64-linux-nat.c (fetch_gregs_from_thread): Likewise. (store_gregs_to_thread): Likewise. (fetch_fpregs_from_thread): Likewise. (store_fpregs_to_thread): Likewise. * aarch64-tdep.c (aarch64_extract_return_value): Likewise. (aarch64_store_return_value): Likewise. (aarch64_software_single_step): Likewise. * aix-thread.c (aix_thread_wait): Likewise. (supply_reg32): Likewise. (supply_sprs64): Likewise. (supply_sprs32): Likewise. (fill_gprs64): Likewise. (fill_gprs32): Likewise. (fill_sprs64): Likewise. (fill_sprs32): Likewise. (store_regs_user_thread): Likewise. (store_regs_kernel_thread): Likewise. * alpha-bsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * alpha-tdep.c (alpha_extract_return_value): Likewise. (alpha_store_return_value): Likewise. (alpha_deal_with_atomic_sequence): Likewise. (alpha_next_pc): Likewise. (alpha_software_single_step): Likewise. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * amd64-nat.c (amd64_supply_native_gregset): Likewise. (amd64_collect_native_gregset): Likewise. * amd64-obsd-tdep.c (amd64obsd_supply_uthread): Likewise. (amd64obsd_collect_uthread): Likewise. * amd64-tdep.c (amd64_supply_fpregset): Likewise. (amd64_collect_fpregset): Likewise. (amd64_supply_fxsave): Likewise. (amd64_supply_xsave): Likewise. (amd64_collect_fxsave): Likewise. (amd64_collect_xsave): Likewise. * arc-tdep.c (arc_write_pc): Likewise. * arch-utils.c (default_skip_permanent_breakpoint): Likewise. * arm-fbsd-nat.c (arm_fbsd_fetch_inferior_registers): Likewise. (arm_fbsd_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_vfp_regs): Likewise. (store_vfp_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * arm-linux-tdep.c (arm_linux_supply_gregset): Likewise. (arm_linux_sigreturn_next_pc): Likewise. (arm_linux_get_next_pcs_syscall_next_pc): Likewise. * arm-nbsd-nat.c (arm_supply_gregset): Likewise. (fetch_register): Likewise. (store_register): Likewise. * arm-tdep.c (arm_is_thumb): Likewise. (displaced_in_arm_mode): Likewise. (bx_write_pc): Likewise. (arm_get_next_pcs_addr_bits_remove): Likewise. (arm_software_single_step): Likewise. (arm_extract_return_value): Likewise. (arm_store_return_value): Likewise. (arm_write_pc): Likewise. * bfin-tdep.c (bfin_extract_return_value): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * core-regset.c (fetch_core_registers): Likewise. * corelow.c (get_core_registers): Likewise. * cris-tdep.c (cris_store_return_value): Likewise. (cris_extract_return_value): Likewise. (find_step_target): Likewise. (find_step_target): Likewise. (cris_software_single_step): Likewise. * ctf.c (ctf_fetch_registers): Likewise. * darwin-nat.c (cancel_breakpoint): Likewise. * fbsd-tdep.c (fbsd_collect_thread_registers): Likewise. * frv-tdep.c (frv_extract_return_value): Likewise. * ft32-tdep.c (ft32_store_return_value): Likewise. (ft32_extract_return_value): Likewise. * go32-nat.c (fetch_register): Likewise. (go32_fetch_registers): Likewise. (go32_store_registers): Likewise. (store_register): Likewise. * h8300-tdep.c (h8300_extract_return_value): Likewise. (h8300_store_return_value): Likewise. * hppa-linux-nat.c (fetch_register): Likewise. (store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * i386-darwin-nat.c (i386_darwin_fetch_inferior_registers): Likewise. (i386_darwin_store_inferior_registers): Likewise. * i386-gnu-nat.c (gnu_fetch_registers): Likewise. (gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register): Likewise. (store_register): Likewise. (supply_gregset): Likewise. (fill_gregset): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. (i386_linux_resume): Likewise. * i386-linux-tdep.c (i386_linux_get_syscall_number_from_regcache): Likewise. * i386-nto-tdep.c (i386nto_supply_gregset): Likewise. * i386-obsd-nat.c (i386obsd_supply_pcb): Likewise. * i386-obsd-tdep.c (i386obsd_supply_uthread): Likewise. (i386obsd_collect_uthread): Likewise. * i386-tdep.c (i386_mmx_regnum_to_fp_regnum): Likewise. (i386_supply_gregset): Likewise. (i386_collect_gregset): Likewise. (i386_supply_fpregset): Likewise. (i386_collect_fpregset): Likewise. (i386_mpx_bd_base): Likewise. * i386-v4-nat.c (supply_fpregset): Likewise. (fill_fpregset): Likewise. * i387-tdep.c (i387_supply_fsave): Likewise. (i387_collect_fsave): Likewise. (i387_supply_fxsave): Likewise. (i387_collect_fxsave): Likewise. (i387_supply_xsave): Likewise. (i387_collect_xsave): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_registers): Likewise. * ia64-tdep.c (ia64_access_rse_reg): Likewise. (ia64_extract_return_value): Likewise. (ia64_store_return_value): Likewise. (find_func_descr): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_registers): Likewise. * infrun.c (use_displaced_stepping): Likewise. (displaced_step_prepare_throw): Likewise. (resume): Likewise. (proceed): Likewise. (do_target_wait): Likewise. (adjust_pc_after_break): Likewise. (handle_inferior_event_1): Likewise. (handle_signal_stop): Likewise. (save_infcall_suspend_state): Likewise. (restore_infcall_suspend_state): Likewise. * iq2000-tdep.c (iq2000_extract_return_value): Likewise. * jit.c (jit_frame_prev_register): Likewise. * linux-nat.c (save_stop_reason): Likewise. (linux_nat_wait_1): Likewise. (resume_stopped_resumed_lwps): Likewise. * linux-record.c (record_linux_sockaddr): Likewise. (record_linux_msghdr): Likewise. (record_linux_system_call): Likewise. * linux-tdep.c (linux_collect_thread_registers): Likewise. * lm32-tdep.c (lm32_extract_return_value): Likewise. (lm32_store_return_value): Likewise. * m32c-tdep.c (m32c_read_flg): Likewise. (m32c_pseudo_register_read): Likewise. (m32c_pseudo_register_write): Likewise. * m32r-linux-tdep.c (m32r_linux_supply_gregset): Likewise. (m32r_linux_collect_gregset): Likewise. * m32r-tdep.c (m32r_store_return_value): Likewise. (m32r_extract_return_value): Likewise. * m68k-bsd-nat.c (m68kbsd_supply_fpregset): Likewise. (m68kbsd_collect_fpregset): Likewise. * m68k-bsd-tdep.c (m68kbsd_supply_fpregset): Likewise. * m68k-linux-nat.c (fetch_register): Likewise. (old_fetch_inferior_registers): Likewise. (old_store_inferior_registers): Likewise. (store_regs): Likewise. * m68k-tdep.c (m68k_svr4_extract_return_value): Likewise. (m68k_svr4_store_return_value): Likewise. * m88k-tdep.c (m88k_store_arguments): Likewise. * mi/mi-main.c (mi_cmd_data_list_changed_registers): Likewise. (mi_cmd_data_write_register_values): Likewise. * mips-fbsd-nat.c (mips_fbsd_fetch_inferior_registers): Likewise. (mips_fbsd_store_inferior_registers): Likewise. * mips-fbsd-tdep.c (mips_fbsd_supply_fpregs): Likewise. (mips_fbsd_supply_gregs): Likewise. (mips_fbsd_collect_fpregs): Likewise. (mips_fbsd_collect_gregs): Likewise. (mips_fbsd_supply_fpregset): Likewise. (mips_fbsd_collect_fpregset): Likewise. (mips_fbsd_supply_gregset): Likewise. (mips_fbsd_collect_gregset): Likewise. * mips-linux-nat.c (supply_gregset): Likewise. (fill_gregset): Likewise. (supply_fpregset): Likewise. (fill_fpregset): Likewise. * mips-linux-tdep.c (mips_supply_gregset): Likewise. (mips_fill_gregset): Likewise. (mips_supply_fpregset): Likewise. (mips_fill_fpregset): Likewise. (mips64_supply_gregset): Likewise. (micromips_linux_sigframe_validate): Likewise. * mips-nbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * mips-nbsd-tdep.c (mipsnbsd_supply_fpregset): Likewise. (mipsnbsd_supply_gregset): Likewise. (mipsnbsd_iterate_over_regset_sections): Likewise. (mipsnbsd_supply_reg): Likewise. (mipsnbsd_supply_fpreg): Likewise. * mips-tdep.c (mips_in_frame_stub): Likewise. (mips_dummy_id): Likewise. (is_octeon_bbit_op): Likewise. (micromips_bc1_pc): Likewise. (extended_mips16_next_pc): Likewise. (mips16_next_pc): Likewise. (deal_with_atomic_sequence): Likewise. * moxie-tdep.c (moxie_process_readu): Likewise. * nios2-tdep.c (nios2_get_next_pc): Likewise. * nto-procfs.c (procfs_store_registers): Likewise. * ppc-fbsd-nat.c (ppcfbsd_fetch_inferior_registers): Likewise. (ppcfbsd_store_inferior_registers): Likewise. * ppc-linux-nat.c (fetch_vsx_register): Likewise. (fetch_altivec_register): Likewise. (get_spe_registers): Likewise. (fetch_spe_register): Likewise. (fetch_altivec_registers): Likewise. (fetch_all_gp_regs): Likewise. (fetch_all_fp_regs): Likewise. (store_vsx_register): Likewise. (store_altivec_register): Likewise. (set_spe_registers): Likewise. (store_spe_register): Likewise. (store_altivec_registers): Likewise. (store_all_gp_regs): Likewise. (store_all_fp_regs): Likewise. * ppc-linux-tdep.c (ppc_linux_supply_gregset): Likewise. (ppc_linux_collect_gregset): Likewise. (ppc_canonicalize_syscall): Likewise. (ppc_linux_record_signal): Likewise. (ppu2spu_prev_register): Likewise. * ppc-nbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-obsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * ppc-ravenscar-thread.c (ppc_ravenscar_generic_fetch_registers): Likewise. (ppc_ravenscar_generic_store_registers): Likewise. * procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ravenscar-thread.c (ravenscar_fetch_registers): Likewise. (ravenscar_store_registers): Likewise. (ravenscar_prepare_to_store): Likewise. * record-btrace.c (record_btrace_fetch_registers): Likewise. * record-full.c (record_full_wait_1): Likewise. (record_full_registers_change): Likewise. (record_full_store_registers): Likewise. (record_full_core_fetch_registers): Likewise. (record_full_save): Likewise. (record_full_goto_insn): Likewise. * regcache.c (regcache_register_size): Likewise. (get_regcache_arch): Remove. (regcache_read_pc): Likewise. * regcache.h (get_regcache_arch): Remove. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * remote.c (fetch_register_using_p): Likewise. (send_g_packet): Likewise. (remote_prepare_to_store): Likewise. (store_registers_using_G): Likewise. * reverse.c (save_bookmark_command): Likewise. (goto_bookmark_command): Likewise. * rs6000-aix-tdep.c (branch_dest): Likewise. * rs6000-nat.c (rs6000_ptrace64): Likewise. (fetch_register): Likewise. * rs6000-tdep.c (ppc_supply_reg): Likewise. (ppc_collect_reg): Likewise. (ppc_collect_gregset): Likewise. (ppc_collect_fpregset): Likewise. (ppc_collect_vsxregset): Likewise. (ppc_collect_vrregset): Likewise. (ppc_displaced_step_hw_singlestep): Likewise. (rs6000_pseudo_register_read): Likewise. (rs6000_pseudo_register_write): Likewise. * s390-linux-nat.c (supply_gregset): Likewise. (fill_gregset): Likewise. (s390_linux_fetch_inferior_registers): Likewise. * s390-linux-tdep.c (s390_write_pc): Likewise. (s390_software_single_step): Likewise. (s390_all_but_pc_registers_record): Likewise. (s390_linux_syscall_record): Likewise. * sentinel-frame.c (sentinel_frame_prev_arch): Likewise. * sh-nbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sh-tdep.c (sh_extract_return_value_nofpu): Likewise. (sh_extract_return_value_fpu): Likewise. (sh_store_return_value_nofpu): Likewise. (sh_corefile_supply_regset): Likewise. (sh_corefile_collect_regset): Likewise. * sh64-tdep.c (sh64_extract_return_value): Likewise. (sh64_store_return_value): Likewise. * sparc-linux-tdep.c (sparc32_linux_collect_core_fpregset): Likewise. * sparc-nat.c (sparc_fetch_inferior_registers): Likewise. (sparc_store_inferior_registers): Likewise. * sparc-ravenscar-thread.c (register_in_thread_descriptor_p): Likewise. (sparc_ravenscar_prepare_to_store): Likewise. * sparc-tdep.c (sparc32_store_arguments): Likewise. (sparc_analyze_control_transfer): Likewise. (sparc_step_trap): Likewise. (sparc_software_single_step): Likewise. (sparc32_gdbarch_init): Likewise. (sparc_supply_rwindow): Likewise. (sparc_collect_rwindow): Likewise. * sparc64-linux-tdep.c (sparc64_linux_collect_core_fpregset): Likewise. * sparc64-nbsd-nat.c (sparc64nbsd_supply_gregset): Likewise. (sparc64nbsd_collect_gregset): Likewise. (sparc64nbsd_supply_fpregset): Likewise. (sparc64nbsd_collect_fpregset): Likewise. * sparc64-tdep.c (sparc64_store_arguments): Likewise. (sparc64_supply_gregset): Likewise. (sparc64_collect_gregset): Likewise. (sparc64_supply_fpregset): Likewise. (sparc64_collect_fpregset): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. * spu-tdep.c (spu_unwind_sp): Likewise. (spu2ppu_prev_register): Likewise. (spu_memory_remove_breakpoint): Likewise. * stack.c (return_command): Likewise. * tic6x-tdep.c (tic6x_extract_signed_field): Likewise. * tracefile-tfile.c (tfile_fetch_registers): Likewise. * tracefile.c (trace_save_ctf): Likewise. * windows-nat.c (do_windows_fetch_inferior_registers): Likewise. (do_windows_store_inferior_registers): Likewise. (windows_resume): Likewise. * xtensa-linux-nat.c (fill_gregset): Likewise. (supply_gregset_reg): Likewise. * xtensa-tdep.c (xtensa_register_write_masked): Likewise. (xtensa_register_read_masked): Likewise. (xtensa_supply_gregset): Likewise. (xtensa_extract_return_value): Likewise. (xtensa_store_return_value): Likewise.
2017-10-25 23:37:03 +08:00
struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int i;
if (have_ptrace_getsetfpregs)
if (fetch_all_fp_regs (regcache, tid))
return;
/* If we've hit this point, it doesn't really matter which
architecture we are using. We just need to read the
registers in the "old-fashioned way". */
for (i = 0; i < ppc_num_fprs; i++)
fetch_register (regcache, tid, tdep->ppc_fp0_regnum + i);
}
static void
* target.h (struct regcache): Add forward declaration. (struct target_ops): Add REGCACHE parameter to to_fetch_registers and to_store_registers target operations. (target_fetch_registers, target_store_registers): Update. * regcache.c (regcache_raw_read): Replace register_cached by regcache_valid_p. Pass regcache to target_fetch_registers. (regcache_raw_write): Pass regcache to target_store_registers. * arm-linux-nat.c (store_fpregister, store_fpregs, store_register, store_regs, store_wmmx_regs): Replace register_cached by regcache_valid_p. * bsd-kvm.c (bsd_kvm_open, bsd_kvm_proc_cmd): Pass current_regcache to target_fetch_registers calls. * corelow.c (core_open): Likewise. * linux-nat.c (linux_nat_corefile_thread_callback): Likewise. * proc-service.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * sol-thread.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * win32-nat.c (win32_resume): Likewise. * ia64-tdep.c (ia64_store_return_value): Pass current_regcache to target_store_registers call. * rs6000-tdep.c (rs6000_push_dummy_call): Likewise. * inferior.h (store_inferior_registers): Update prototype. (fetch_inferior_registers): Likewise. * gnu-nat.c (gnu_store_registers, gnu_fetch_registers): Likewise. * mips-linux-nat.c (super_fetch_registers, super_store_registers): Update function pointer signatures. * aix-thread.c (aix_thread_fetch_registers): Add REGCACHE parameter, use it instead of current_regcache, update calls. (aix_thread_store_registers): Likewise. * alphabsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * amd64bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_fpregister, fetch_fpregs, store_fpregister, store_fpregs, fetch_register, fetch_regs, store_register, store_regs, fetch_wmmx_regs, store_wmmx_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * armnbsd-nat.c (fetch_register, fetch_regs, fetch_fp_register, fetch_fp_regs, armnbsd_fetch_registers): Likewise. (store_register, store_regs, store_fp_register, store_fp_regs, armnbsd_store_registers): Likewise. * bsd-kvm.c (bsd_kvm_fetch_pcb, bsd_kvm_fetch_registers): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * corelow.c (get_core_registers): Likewise. * go32-nat.c (fetch_register, go32_fetch_registers, store_register, go32_store_registers): Likewise. * hppabsd-nat.c (hppabsd_fetch_registers): Likewise. (hppabsd_store_registers): Likewise. * hppa-hpux-nat.c (hppa_hpux_fetch_register): Likewise. (hppa_hpux_fetch_inferior_registers): Likewise. (hppa_hpux_store_register): Likewise. (hppa_hpux_store_inferior_registers): Likewise. * hppa-linux-nat.c (fetch_register, store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * hpux-thread.c (hpux_thread_fetch_registers): Likewise. (hpux_thread_store_registers): Likewise. * i386bsd-nat.c (i386bsd_fetch_inferior_registers): Likewise. (i386bsd_store_inferior_registers): Likewise. * i386gnu-nat.c (fetch_fpregs, gnu_fetch_registers, store_fpregs, gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register, store_register, fetch_regs, store_regs, fetch_fpregs, store_fpregs, fetch_fpxregs, store_fpxregs): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_register): Likewise. (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_register): Likewise. (ia64_linux_store_registers): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. (inf_child_store_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register): Likewise. (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_register): Likewise. (inf_ptrace_store_registers): Likewise. * infptrace.c (fetch_register, store_register): Likewise. (fetch_inferior_registers, store_inferior_registers): Likewise. * m32r-linux-nat.c (fetch_regs, store_regs): Likewise. (m32r_linux_fetch_inferior_registers): Likewise. (m32r_linux_store_inferior_registers): Likewise. * m68kbsd-nat.c (m68kbsd_fetch_inferior_registers): Likewise. (m68kbsd_store_inferior_registers): Likewise. * m68klinux-nat.c (fetch_register, old_fetch_inferior_registers, store_register, old_store_inferior_registers, fetch_regs, store_regs, fetch_fpregs, store_fpregs): Likewise. (m68k_linux_fetch_inferior_registers): Likewise. (m68k_linux_store_inferior_registers): Likewise. * m88kbsd-nat.c (m88kbsd_fetch_inferior_registers): Likewise. (m88kbsd_store_inferior_registers): Likewise. * mips64obsd-nat.c (mips64obsd_fetch_inferior_registers): Likewise. (mips64obsd_store_inferior_registers): Likewise. * mips-linux-nat.c (mips64_linux_regsets_fetch_registers): Likewise. (mips64_linux_regsets_store_registers): Likewise. (mips64_linux_fetch_registers): Likewise. (mips64_linux_store_registers): Likewise. * mipsnbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * monitor.c (monitor_fetch_register, monitor_store_register): Likewise. (monitor_fetch_registers, monitor_store_registers): Likewise. * nto-procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register, fetch_register, supply_vrregset, fetch_altivec_registers, fetch_ppc_registers, ppc_linux_fetch_inferior_registers): Likewise. (store_altivec_register, store_spe_register, store_register, fill_vrregset, store_altivec_registers, store_ppc_registers, ppc_linux_store_inferior_registers): Likewise. * ppcnbsd-nat.c (ppcnbsd_fetch_inferior_registers): Likewise. (ppcnbsd_store_inferior_registers): Likewise. * ppcobsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote.c (fetch_register_using_p, process_g_packet, fetch_registers_using_g, remote_fetch_registers): Likewise. (store_register_using_P, store_registers_using_G, remote_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers, m32r_fetch_register, m32r_store_register, m32r_store_register): Likewise. * remote-mips.c (mips_fetch_registers, mips_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * rs6000-nat.c (fetch_register, store_register): Likewise. (rs6000_fetch_inferior_registers): Likewise. (rs6000_store_inferior_registers): Likewise. * s390-nat.c (fetch_regs, store_regs): Likewise. (fetch_fpregs, store_fpregs): Likewise. (s390_linux_fetch_inferior_registers): Likewise. (s390_linux_store_inferior_registers): Likewise. * shnbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sol-thread.c (sol_thread_fetch_registers): Likewise. (sol_thread_store_registers): Likewise. * sparc-nat.c (fetch_inferior_registers): Likewise. (store_inferior_registers): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. (spu_store_inferior_registers): Likewise. * target.c (debug_print_register): Likewise. (debug_to_fetch_registers, debug_to_store_registers): Likewise. * vaxbsd-nat.c (vaxbsd_fetch_inferior_registers): Likewise. (vaxbsd_store_inferior_registers): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers): Likewise. (win32_fetch_inferior_registers): Likewise. (win32_store_inferior_registers): Likewise.
2007-05-06 22:34:38 +08:00
fetch_ppc_registers (struct regcache *regcache, int tid)
{
s/get_regcache_arch (regcache)/regcache->arch ()/g This patches removes get_regcache_arch, and use regache->arch () instead. The motivation of this change is that I am going to move some basic stuff into a base class of regcache. I don't need to update "client" code regcache->arch (). On the other hand, this patch shortens the code a little bit. gdb: 2017-10-25 Yao Qi <yao.qi@linaro.org> * aarch32-linux-nat.c (aarch32_gp_regcache_supply): Use regcache->arch () instead get_regcache_arch. * aarch64-fbsd-nat.c (aarch64_fbsd_fetch_inferior_registers): Likewise. (aarch64_fbsd_store_inferior_registers): Likewise. * aarch64-linux-nat.c (fetch_gregs_from_thread): Likewise. (store_gregs_to_thread): Likewise. (fetch_fpregs_from_thread): Likewise. (store_fpregs_to_thread): Likewise. * aarch64-tdep.c (aarch64_extract_return_value): Likewise. (aarch64_store_return_value): Likewise. (aarch64_software_single_step): Likewise. * aix-thread.c (aix_thread_wait): Likewise. (supply_reg32): Likewise. (supply_sprs64): Likewise. (supply_sprs32): Likewise. (fill_gprs64): Likewise. (fill_gprs32): Likewise. (fill_sprs64): Likewise. (fill_sprs32): Likewise. (store_regs_user_thread): Likewise. (store_regs_kernel_thread): Likewise. * alpha-bsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * alpha-tdep.c (alpha_extract_return_value): Likewise. (alpha_store_return_value): Likewise. (alpha_deal_with_atomic_sequence): Likewise. (alpha_next_pc): Likewise. (alpha_software_single_step): Likewise. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * amd64-nat.c (amd64_supply_native_gregset): Likewise. (amd64_collect_native_gregset): Likewise. * amd64-obsd-tdep.c (amd64obsd_supply_uthread): Likewise. (amd64obsd_collect_uthread): Likewise. * amd64-tdep.c (amd64_supply_fpregset): Likewise. (amd64_collect_fpregset): Likewise. (amd64_supply_fxsave): Likewise. (amd64_supply_xsave): Likewise. (amd64_collect_fxsave): Likewise. (amd64_collect_xsave): Likewise. * arc-tdep.c (arc_write_pc): Likewise. * arch-utils.c (default_skip_permanent_breakpoint): Likewise. * arm-fbsd-nat.c (arm_fbsd_fetch_inferior_registers): Likewise. (arm_fbsd_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_vfp_regs): Likewise. (store_vfp_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * arm-linux-tdep.c (arm_linux_supply_gregset): Likewise. (arm_linux_sigreturn_next_pc): Likewise. (arm_linux_get_next_pcs_syscall_next_pc): Likewise. * arm-nbsd-nat.c (arm_supply_gregset): Likewise. (fetch_register): Likewise. (store_register): Likewise. * arm-tdep.c (arm_is_thumb): Likewise. (displaced_in_arm_mode): Likewise. (bx_write_pc): Likewise. (arm_get_next_pcs_addr_bits_remove): Likewise. (arm_software_single_step): Likewise. (arm_extract_return_value): Likewise. (arm_store_return_value): Likewise. (arm_write_pc): Likewise. * bfin-tdep.c (bfin_extract_return_value): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * core-regset.c (fetch_core_registers): Likewise. * corelow.c (get_core_registers): Likewise. * cris-tdep.c (cris_store_return_value): Likewise. (cris_extract_return_value): Likewise. (find_step_target): Likewise. (find_step_target): Likewise. (cris_software_single_step): Likewise. * ctf.c (ctf_fetch_registers): Likewise. * darwin-nat.c (cancel_breakpoint): Likewise. * fbsd-tdep.c (fbsd_collect_thread_registers): Likewise. * frv-tdep.c (frv_extract_return_value): Likewise. * ft32-tdep.c (ft32_store_return_value): Likewise. (ft32_extract_return_value): Likewise. * go32-nat.c (fetch_register): Likewise. (go32_fetch_registers): Likewise. (go32_store_registers): Likewise. (store_register): Likewise. * h8300-tdep.c (h8300_extract_return_value): Likewise. (h8300_store_return_value): Likewise. * hppa-linux-nat.c (fetch_register): Likewise. (store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * i386-darwin-nat.c (i386_darwin_fetch_inferior_registers): Likewise. (i386_darwin_store_inferior_registers): Likewise. * i386-gnu-nat.c (gnu_fetch_registers): Likewise. (gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register): Likewise. (store_register): Likewise. (supply_gregset): Likewise. (fill_gregset): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. (i386_linux_resume): Likewise. * i386-linux-tdep.c (i386_linux_get_syscall_number_from_regcache): Likewise. * i386-nto-tdep.c (i386nto_supply_gregset): Likewise. * i386-obsd-nat.c (i386obsd_supply_pcb): Likewise. * i386-obsd-tdep.c (i386obsd_supply_uthread): Likewise. (i386obsd_collect_uthread): Likewise. * i386-tdep.c (i386_mmx_regnum_to_fp_regnum): Likewise. (i386_supply_gregset): Likewise. (i386_collect_gregset): Likewise. (i386_supply_fpregset): Likewise. (i386_collect_fpregset): Likewise. (i386_mpx_bd_base): Likewise. * i386-v4-nat.c (supply_fpregset): Likewise. (fill_fpregset): Likewise. * i387-tdep.c (i387_supply_fsave): Likewise. (i387_collect_fsave): Likewise. (i387_supply_fxsave): Likewise. (i387_collect_fxsave): Likewise. (i387_supply_xsave): Likewise. (i387_collect_xsave): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_registers): Likewise. * ia64-tdep.c (ia64_access_rse_reg): Likewise. (ia64_extract_return_value): Likewise. (ia64_store_return_value): Likewise. (find_func_descr): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_registers): Likewise. * infrun.c (use_displaced_stepping): Likewise. (displaced_step_prepare_throw): Likewise. (resume): Likewise. (proceed): Likewise. (do_target_wait): Likewise. (adjust_pc_after_break): Likewise. (handle_inferior_event_1): Likewise. (handle_signal_stop): Likewise. (save_infcall_suspend_state): Likewise. (restore_infcall_suspend_state): Likewise. * iq2000-tdep.c (iq2000_extract_return_value): Likewise. * jit.c (jit_frame_prev_register): Likewise. * linux-nat.c (save_stop_reason): Likewise. (linux_nat_wait_1): Likewise. (resume_stopped_resumed_lwps): Likewise. * linux-record.c (record_linux_sockaddr): Likewise. (record_linux_msghdr): Likewise. (record_linux_system_call): Likewise. * linux-tdep.c (linux_collect_thread_registers): Likewise. * lm32-tdep.c (lm32_extract_return_value): Likewise. (lm32_store_return_value): Likewise. * m32c-tdep.c (m32c_read_flg): Likewise. (m32c_pseudo_register_read): Likewise. (m32c_pseudo_register_write): Likewise. * m32r-linux-tdep.c (m32r_linux_supply_gregset): Likewise. (m32r_linux_collect_gregset): Likewise. * m32r-tdep.c (m32r_store_return_value): Likewise. (m32r_extract_return_value): Likewise. * m68k-bsd-nat.c (m68kbsd_supply_fpregset): Likewise. (m68kbsd_collect_fpregset): Likewise. * m68k-bsd-tdep.c (m68kbsd_supply_fpregset): Likewise. * m68k-linux-nat.c (fetch_register): Likewise. (old_fetch_inferior_registers): Likewise. (old_store_inferior_registers): Likewise. (store_regs): Likewise. * m68k-tdep.c (m68k_svr4_extract_return_value): Likewise. (m68k_svr4_store_return_value): Likewise. * m88k-tdep.c (m88k_store_arguments): Likewise. * mi/mi-main.c (mi_cmd_data_list_changed_registers): Likewise. (mi_cmd_data_write_register_values): Likewise. * mips-fbsd-nat.c (mips_fbsd_fetch_inferior_registers): Likewise. (mips_fbsd_store_inferior_registers): Likewise. * mips-fbsd-tdep.c (mips_fbsd_supply_fpregs): Likewise. (mips_fbsd_supply_gregs): Likewise. (mips_fbsd_collect_fpregs): Likewise. (mips_fbsd_collect_gregs): Likewise. (mips_fbsd_supply_fpregset): Likewise. (mips_fbsd_collect_fpregset): Likewise. (mips_fbsd_supply_gregset): Likewise. (mips_fbsd_collect_gregset): Likewise. * mips-linux-nat.c (supply_gregset): Likewise. (fill_gregset): Likewise. (supply_fpregset): Likewise. (fill_fpregset): Likewise. * mips-linux-tdep.c (mips_supply_gregset): Likewise. (mips_fill_gregset): Likewise. (mips_supply_fpregset): Likewise. (mips_fill_fpregset): Likewise. (mips64_supply_gregset): Likewise. (micromips_linux_sigframe_validate): Likewise. * mips-nbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * mips-nbsd-tdep.c (mipsnbsd_supply_fpregset): Likewise. (mipsnbsd_supply_gregset): Likewise. (mipsnbsd_iterate_over_regset_sections): Likewise. (mipsnbsd_supply_reg): Likewise. (mipsnbsd_supply_fpreg): Likewise. * mips-tdep.c (mips_in_frame_stub): Likewise. (mips_dummy_id): Likewise. (is_octeon_bbit_op): Likewise. (micromips_bc1_pc): Likewise. (extended_mips16_next_pc): Likewise. (mips16_next_pc): Likewise. (deal_with_atomic_sequence): Likewise. * moxie-tdep.c (moxie_process_readu): Likewise. * nios2-tdep.c (nios2_get_next_pc): Likewise. * nto-procfs.c (procfs_store_registers): Likewise. * ppc-fbsd-nat.c (ppcfbsd_fetch_inferior_registers): Likewise. (ppcfbsd_store_inferior_registers): Likewise. * ppc-linux-nat.c (fetch_vsx_register): Likewise. (fetch_altivec_register): Likewise. (get_spe_registers): Likewise. (fetch_spe_register): Likewise. (fetch_altivec_registers): Likewise. (fetch_all_gp_regs): Likewise. (fetch_all_fp_regs): Likewise. (store_vsx_register): Likewise. (store_altivec_register): Likewise. (set_spe_registers): Likewise. (store_spe_register): Likewise. (store_altivec_registers): Likewise. (store_all_gp_regs): Likewise. (store_all_fp_regs): Likewise. * ppc-linux-tdep.c (ppc_linux_supply_gregset): Likewise. (ppc_linux_collect_gregset): Likewise. (ppc_canonicalize_syscall): Likewise. (ppc_linux_record_signal): Likewise. (ppu2spu_prev_register): Likewise. * ppc-nbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-obsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * ppc-ravenscar-thread.c (ppc_ravenscar_generic_fetch_registers): Likewise. (ppc_ravenscar_generic_store_registers): Likewise. * procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ravenscar-thread.c (ravenscar_fetch_registers): Likewise. (ravenscar_store_registers): Likewise. (ravenscar_prepare_to_store): Likewise. * record-btrace.c (record_btrace_fetch_registers): Likewise. * record-full.c (record_full_wait_1): Likewise. (record_full_registers_change): Likewise. (record_full_store_registers): Likewise. (record_full_core_fetch_registers): Likewise. (record_full_save): Likewise. (record_full_goto_insn): Likewise. * regcache.c (regcache_register_size): Likewise. (get_regcache_arch): Remove. (regcache_read_pc): Likewise. * regcache.h (get_regcache_arch): Remove. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * remote.c (fetch_register_using_p): Likewise. (send_g_packet): Likewise. (remote_prepare_to_store): Likewise. (store_registers_using_G): Likewise. * reverse.c (save_bookmark_command): Likewise. (goto_bookmark_command): Likewise. * rs6000-aix-tdep.c (branch_dest): Likewise. * rs6000-nat.c (rs6000_ptrace64): Likewise. (fetch_register): Likewise. * rs6000-tdep.c (ppc_supply_reg): Likewise. (ppc_collect_reg): Likewise. (ppc_collect_gregset): Likewise. (ppc_collect_fpregset): Likewise. (ppc_collect_vsxregset): Likewise. (ppc_collect_vrregset): Likewise. (ppc_displaced_step_hw_singlestep): Likewise. (rs6000_pseudo_register_read): Likewise. (rs6000_pseudo_register_write): Likewise. * s390-linux-nat.c (supply_gregset): Likewise. (fill_gregset): Likewise. (s390_linux_fetch_inferior_registers): Likewise. * s390-linux-tdep.c (s390_write_pc): Likewise. (s390_software_single_step): Likewise. (s390_all_but_pc_registers_record): Likewise. (s390_linux_syscall_record): Likewise. * sentinel-frame.c (sentinel_frame_prev_arch): Likewise. * sh-nbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sh-tdep.c (sh_extract_return_value_nofpu): Likewise. (sh_extract_return_value_fpu): Likewise. (sh_store_return_value_nofpu): Likewise. (sh_corefile_supply_regset): Likewise. (sh_corefile_collect_regset): Likewise. * sh64-tdep.c (sh64_extract_return_value): Likewise. (sh64_store_return_value): Likewise. * sparc-linux-tdep.c (sparc32_linux_collect_core_fpregset): Likewise. * sparc-nat.c (sparc_fetch_inferior_registers): Likewise. (sparc_store_inferior_registers): Likewise. * sparc-ravenscar-thread.c (register_in_thread_descriptor_p): Likewise. (sparc_ravenscar_prepare_to_store): Likewise. * sparc-tdep.c (sparc32_store_arguments): Likewise. (sparc_analyze_control_transfer): Likewise. (sparc_step_trap): Likewise. (sparc_software_single_step): Likewise. (sparc32_gdbarch_init): Likewise. (sparc_supply_rwindow): Likewise. (sparc_collect_rwindow): Likewise. * sparc64-linux-tdep.c (sparc64_linux_collect_core_fpregset): Likewise. * sparc64-nbsd-nat.c (sparc64nbsd_supply_gregset): Likewise. (sparc64nbsd_collect_gregset): Likewise. (sparc64nbsd_supply_fpregset): Likewise. (sparc64nbsd_collect_fpregset): Likewise. * sparc64-tdep.c (sparc64_store_arguments): Likewise. (sparc64_supply_gregset): Likewise. (sparc64_collect_gregset): Likewise. (sparc64_supply_fpregset): Likewise. (sparc64_collect_fpregset): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. * spu-tdep.c (spu_unwind_sp): Likewise. (spu2ppu_prev_register): Likewise. (spu_memory_remove_breakpoint): Likewise. * stack.c (return_command): Likewise. * tic6x-tdep.c (tic6x_extract_signed_field): Likewise. * tracefile-tfile.c (tfile_fetch_registers): Likewise. * tracefile.c (trace_save_ctf): Likewise. * windows-nat.c (do_windows_fetch_inferior_registers): Likewise. (do_windows_store_inferior_registers): Likewise. (windows_resume): Likewise. * xtensa-linux-nat.c (fill_gregset): Likewise. (supply_gregset_reg): Likewise. * xtensa-tdep.c (xtensa_register_write_masked): Likewise. (xtensa_register_read_masked): Likewise. (xtensa_supply_gregset): Likewise. (xtensa_extract_return_value): Likewise. (xtensa_store_return_value): Likewise.
2017-10-25 23:37:03 +08:00
struct gdbarch *gdbarch = regcache->arch ();
2007-11-16 Markus Deuling <deuling@de.ibm.com> * m32r-rom.c (m32r_supply_register): Use get_regcache_arch to get at the current architecture by regcache. * ppcnbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register) (fetch_register, supply_vrregset, fetch_ppc_registers) (store_altivec_register, store_spe_register, store_register) (fill_vrregset, store_ppc_registers): Likewise. * ppcobsd-nat.c (ppcobsd_supply_pcb): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers) (do_win32_store_inferior_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers) (m32r_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register, gdbsim_store_register): Likewise. * trad-frame.c (trad_frame_alloc_saved_regs): Replace current_gdbarch by gdbarch. * user-regs.c (user_reg_map_name_to_regnum): Likewise. * ppc-sysv-tdep.c (ppc_sysv_abi_push_dummy_call) (do_ppc_sysv_return_value, ppc64_sysv_abi_push_dummy_call) (ppc64_sysv_abi_return_value): Likewise. * m32c-tdep.c (m32c_register_reggroup_p): Likewise. * m2-lang.c (build_m2_types): Likewise. * ppc-linux-tdep.c (ppc_linux_sigtramp_cache * ppcnbsd-tdep.c (ppcnbsd_sigtramp_cache_init): Likewise. * ppcobsd-tdep.c (ppcobsd_sigtramp_frame_cache): Likewise. * rs6000-tdep.c (ppc_dwarf2_frame_init_reg): Likewise. * m68hc11-tdep.c (m68hc11_frame_unwind_cache): Use get_frame_arch to get at the current architecture by frame_info. * gcore.c (derive_stack_segment): Likewise. * shnbsd-nat.c (GETREGS_SUPPLIES): Add gdbarch parameter. (shnbsd_fetch_inferior_registers, shnbsd_store_inferior_registers): Add gdbarch to GETREGS_SUPPLIES call.
2007-11-16 12:53:46 +08:00
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
fetch_gp_regs (regcache, tid);
if (tdep->ppc_fp0_regnum >= 0)
fetch_fp_regs (regcache, tid);
2007-11-16 Markus Deuling <deuling@de.ibm.com> * m32r-rom.c (m32r_supply_register): Use get_regcache_arch to get at the current architecture by regcache. * ppcnbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register) (fetch_register, supply_vrregset, fetch_ppc_registers) (store_altivec_register, store_spe_register, store_register) (fill_vrregset, store_ppc_registers): Likewise. * ppcobsd-nat.c (ppcobsd_supply_pcb): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers) (do_win32_store_inferior_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers) (m32r_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register, gdbsim_store_register): Likewise. * trad-frame.c (trad_frame_alloc_saved_regs): Replace current_gdbarch by gdbarch. * user-regs.c (user_reg_map_name_to_regnum): Likewise. * ppc-sysv-tdep.c (ppc_sysv_abi_push_dummy_call) (do_ppc_sysv_return_value, ppc64_sysv_abi_push_dummy_call) (ppc64_sysv_abi_return_value): Likewise. * m32c-tdep.c (m32c_register_reggroup_p): Likewise. * m2-lang.c (build_m2_types): Likewise. * ppc-linux-tdep.c (ppc_linux_sigtramp_cache * ppcnbsd-tdep.c (ppcnbsd_sigtramp_cache_init): Likewise. * ppcobsd-tdep.c (ppcobsd_sigtramp_frame_cache): Likewise. * rs6000-tdep.c (ppc_dwarf2_frame_init_reg): Likewise. * m68hc11-tdep.c (m68hc11_frame_unwind_cache): Use get_frame_arch to get at the current architecture by frame_info. * gcore.c (derive_stack_segment): Likewise. * shnbsd-nat.c (GETREGS_SUPPLIES): Add gdbarch parameter. (shnbsd_fetch_inferior_registers, shnbsd_store_inferior_registers): Add gdbarch to GETREGS_SUPPLIES call.
2007-11-16 12:53:46 +08:00
fetch_register (regcache, tid, gdbarch_pc_regnum (gdbarch));
if (tdep->ppc_ps_regnum != -1)
* target.h (struct regcache): Add forward declaration. (struct target_ops): Add REGCACHE parameter to to_fetch_registers and to_store_registers target operations. (target_fetch_registers, target_store_registers): Update. * regcache.c (regcache_raw_read): Replace register_cached by regcache_valid_p. Pass regcache to target_fetch_registers. (regcache_raw_write): Pass regcache to target_store_registers. * arm-linux-nat.c (store_fpregister, store_fpregs, store_register, store_regs, store_wmmx_regs): Replace register_cached by regcache_valid_p. * bsd-kvm.c (bsd_kvm_open, bsd_kvm_proc_cmd): Pass current_regcache to target_fetch_registers calls. * corelow.c (core_open): Likewise. * linux-nat.c (linux_nat_corefile_thread_callback): Likewise. * proc-service.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * sol-thread.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * win32-nat.c (win32_resume): Likewise. * ia64-tdep.c (ia64_store_return_value): Pass current_regcache to target_store_registers call. * rs6000-tdep.c (rs6000_push_dummy_call): Likewise. * inferior.h (store_inferior_registers): Update prototype. (fetch_inferior_registers): Likewise. * gnu-nat.c (gnu_store_registers, gnu_fetch_registers): Likewise. * mips-linux-nat.c (super_fetch_registers, super_store_registers): Update function pointer signatures. * aix-thread.c (aix_thread_fetch_registers): Add REGCACHE parameter, use it instead of current_regcache, update calls. (aix_thread_store_registers): Likewise. * alphabsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * amd64bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_fpregister, fetch_fpregs, store_fpregister, store_fpregs, fetch_register, fetch_regs, store_register, store_regs, fetch_wmmx_regs, store_wmmx_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * armnbsd-nat.c (fetch_register, fetch_regs, fetch_fp_register, fetch_fp_regs, armnbsd_fetch_registers): Likewise. (store_register, store_regs, store_fp_register, store_fp_regs, armnbsd_store_registers): Likewise. * bsd-kvm.c (bsd_kvm_fetch_pcb, bsd_kvm_fetch_registers): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * corelow.c (get_core_registers): Likewise. * go32-nat.c (fetch_register, go32_fetch_registers, store_register, go32_store_registers): Likewise. * hppabsd-nat.c (hppabsd_fetch_registers): Likewise. (hppabsd_store_registers): Likewise. * hppa-hpux-nat.c (hppa_hpux_fetch_register): Likewise. (hppa_hpux_fetch_inferior_registers): Likewise. (hppa_hpux_store_register): Likewise. (hppa_hpux_store_inferior_registers): Likewise. * hppa-linux-nat.c (fetch_register, store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * hpux-thread.c (hpux_thread_fetch_registers): Likewise. (hpux_thread_store_registers): Likewise. * i386bsd-nat.c (i386bsd_fetch_inferior_registers): Likewise. (i386bsd_store_inferior_registers): Likewise. * i386gnu-nat.c (fetch_fpregs, gnu_fetch_registers, store_fpregs, gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register, store_register, fetch_regs, store_regs, fetch_fpregs, store_fpregs, fetch_fpxregs, store_fpxregs): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_register): Likewise. (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_register): Likewise. (ia64_linux_store_registers): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. (inf_child_store_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register): Likewise. (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_register): Likewise. (inf_ptrace_store_registers): Likewise. * infptrace.c (fetch_register, store_register): Likewise. (fetch_inferior_registers, store_inferior_registers): Likewise. * m32r-linux-nat.c (fetch_regs, store_regs): Likewise. (m32r_linux_fetch_inferior_registers): Likewise. (m32r_linux_store_inferior_registers): Likewise. * m68kbsd-nat.c (m68kbsd_fetch_inferior_registers): Likewise. (m68kbsd_store_inferior_registers): Likewise. * m68klinux-nat.c (fetch_register, old_fetch_inferior_registers, store_register, old_store_inferior_registers, fetch_regs, store_regs, fetch_fpregs, store_fpregs): Likewise. (m68k_linux_fetch_inferior_registers): Likewise. (m68k_linux_store_inferior_registers): Likewise. * m88kbsd-nat.c (m88kbsd_fetch_inferior_registers): Likewise. (m88kbsd_store_inferior_registers): Likewise. * mips64obsd-nat.c (mips64obsd_fetch_inferior_registers): Likewise. (mips64obsd_store_inferior_registers): Likewise. * mips-linux-nat.c (mips64_linux_regsets_fetch_registers): Likewise. (mips64_linux_regsets_store_registers): Likewise. (mips64_linux_fetch_registers): Likewise. (mips64_linux_store_registers): Likewise. * mipsnbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * monitor.c (monitor_fetch_register, monitor_store_register): Likewise. (monitor_fetch_registers, monitor_store_registers): Likewise. * nto-procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register, fetch_register, supply_vrregset, fetch_altivec_registers, fetch_ppc_registers, ppc_linux_fetch_inferior_registers): Likewise. (store_altivec_register, store_spe_register, store_register, fill_vrregset, store_altivec_registers, store_ppc_registers, ppc_linux_store_inferior_registers): Likewise. * ppcnbsd-nat.c (ppcnbsd_fetch_inferior_registers): Likewise. (ppcnbsd_store_inferior_registers): Likewise. * ppcobsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote.c (fetch_register_using_p, process_g_packet, fetch_registers_using_g, remote_fetch_registers): Likewise. (store_register_using_P, store_registers_using_G, remote_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers, m32r_fetch_register, m32r_store_register, m32r_store_register): Likewise. * remote-mips.c (mips_fetch_registers, mips_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * rs6000-nat.c (fetch_register, store_register): Likewise. (rs6000_fetch_inferior_registers): Likewise. (rs6000_store_inferior_registers): Likewise. * s390-nat.c (fetch_regs, store_regs): Likewise. (fetch_fpregs, store_fpregs): Likewise. (s390_linux_fetch_inferior_registers): Likewise. (s390_linux_store_inferior_registers): Likewise. * shnbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sol-thread.c (sol_thread_fetch_registers): Likewise. (sol_thread_store_registers): Likewise. * sparc-nat.c (fetch_inferior_registers): Likewise. (store_inferior_registers): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. (spu_store_inferior_registers): Likewise. * target.c (debug_print_register): Likewise. (debug_to_fetch_registers, debug_to_store_registers): Likewise. * vaxbsd-nat.c (vaxbsd_fetch_inferior_registers): Likewise. (vaxbsd_store_inferior_registers): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers): Likewise. (win32_fetch_inferior_registers): Likewise. (win32_store_inferior_registers): Likewise.
2007-05-06 22:34:38 +08:00
fetch_register (regcache, tid, tdep->ppc_ps_regnum);
if (tdep->ppc_cr_regnum != -1)
* target.h (struct regcache): Add forward declaration. (struct target_ops): Add REGCACHE parameter to to_fetch_registers and to_store_registers target operations. (target_fetch_registers, target_store_registers): Update. * regcache.c (regcache_raw_read): Replace register_cached by regcache_valid_p. Pass regcache to target_fetch_registers. (regcache_raw_write): Pass regcache to target_store_registers. * arm-linux-nat.c (store_fpregister, store_fpregs, store_register, store_regs, store_wmmx_regs): Replace register_cached by regcache_valid_p. * bsd-kvm.c (bsd_kvm_open, bsd_kvm_proc_cmd): Pass current_regcache to target_fetch_registers calls. * corelow.c (core_open): Likewise. * linux-nat.c (linux_nat_corefile_thread_callback): Likewise. * proc-service.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * sol-thread.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * win32-nat.c (win32_resume): Likewise. * ia64-tdep.c (ia64_store_return_value): Pass current_regcache to target_store_registers call. * rs6000-tdep.c (rs6000_push_dummy_call): Likewise. * inferior.h (store_inferior_registers): Update prototype. (fetch_inferior_registers): Likewise. * gnu-nat.c (gnu_store_registers, gnu_fetch_registers): Likewise. * mips-linux-nat.c (super_fetch_registers, super_store_registers): Update function pointer signatures. * aix-thread.c (aix_thread_fetch_registers): Add REGCACHE parameter, use it instead of current_regcache, update calls. (aix_thread_store_registers): Likewise. * alphabsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * amd64bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_fpregister, fetch_fpregs, store_fpregister, store_fpregs, fetch_register, fetch_regs, store_register, store_regs, fetch_wmmx_regs, store_wmmx_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * armnbsd-nat.c (fetch_register, fetch_regs, fetch_fp_register, fetch_fp_regs, armnbsd_fetch_registers): Likewise. (store_register, store_regs, store_fp_register, store_fp_regs, armnbsd_store_registers): Likewise. * bsd-kvm.c (bsd_kvm_fetch_pcb, bsd_kvm_fetch_registers): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * corelow.c (get_core_registers): Likewise. * go32-nat.c (fetch_register, go32_fetch_registers, store_register, go32_store_registers): Likewise. * hppabsd-nat.c (hppabsd_fetch_registers): Likewise. (hppabsd_store_registers): Likewise. * hppa-hpux-nat.c (hppa_hpux_fetch_register): Likewise. (hppa_hpux_fetch_inferior_registers): Likewise. (hppa_hpux_store_register): Likewise. (hppa_hpux_store_inferior_registers): Likewise. * hppa-linux-nat.c (fetch_register, store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * hpux-thread.c (hpux_thread_fetch_registers): Likewise. (hpux_thread_store_registers): Likewise. * i386bsd-nat.c (i386bsd_fetch_inferior_registers): Likewise. (i386bsd_store_inferior_registers): Likewise. * i386gnu-nat.c (fetch_fpregs, gnu_fetch_registers, store_fpregs, gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register, store_register, fetch_regs, store_regs, fetch_fpregs, store_fpregs, fetch_fpxregs, store_fpxregs): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_register): Likewise. (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_register): Likewise. (ia64_linux_store_registers): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. (inf_child_store_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register): Likewise. (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_register): Likewise. (inf_ptrace_store_registers): Likewise. * infptrace.c (fetch_register, store_register): Likewise. (fetch_inferior_registers, store_inferior_registers): Likewise. * m32r-linux-nat.c (fetch_regs, store_regs): Likewise. (m32r_linux_fetch_inferior_registers): Likewise. (m32r_linux_store_inferior_registers): Likewise. * m68kbsd-nat.c (m68kbsd_fetch_inferior_registers): Likewise. (m68kbsd_store_inferior_registers): Likewise. * m68klinux-nat.c (fetch_register, old_fetch_inferior_registers, store_register, old_store_inferior_registers, fetch_regs, store_regs, fetch_fpregs, store_fpregs): Likewise. (m68k_linux_fetch_inferior_registers): Likewise. (m68k_linux_store_inferior_registers): Likewise. * m88kbsd-nat.c (m88kbsd_fetch_inferior_registers): Likewise. (m88kbsd_store_inferior_registers): Likewise. * mips64obsd-nat.c (mips64obsd_fetch_inferior_registers): Likewise. (mips64obsd_store_inferior_registers): Likewise. * mips-linux-nat.c (mips64_linux_regsets_fetch_registers): Likewise. (mips64_linux_regsets_store_registers): Likewise. (mips64_linux_fetch_registers): Likewise. (mips64_linux_store_registers): Likewise. * mipsnbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * monitor.c (monitor_fetch_register, monitor_store_register): Likewise. (monitor_fetch_registers, monitor_store_registers): Likewise. * nto-procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register, fetch_register, supply_vrregset, fetch_altivec_registers, fetch_ppc_registers, ppc_linux_fetch_inferior_registers): Likewise. (store_altivec_register, store_spe_register, store_register, fill_vrregset, store_altivec_registers, store_ppc_registers, ppc_linux_store_inferior_registers): Likewise. * ppcnbsd-nat.c (ppcnbsd_fetch_inferior_registers): Likewise. (ppcnbsd_store_inferior_registers): Likewise. * ppcobsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote.c (fetch_register_using_p, process_g_packet, fetch_registers_using_g, remote_fetch_registers): Likewise. (store_register_using_P, store_registers_using_G, remote_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers, m32r_fetch_register, m32r_store_register, m32r_store_register): Likewise. * remote-mips.c (mips_fetch_registers, mips_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * rs6000-nat.c (fetch_register, store_register): Likewise. (rs6000_fetch_inferior_registers): Likewise. (rs6000_store_inferior_registers): Likewise. * s390-nat.c (fetch_regs, store_regs): Likewise. (fetch_fpregs, store_fpregs): Likewise. (s390_linux_fetch_inferior_registers): Likewise. (s390_linux_store_inferior_registers): Likewise. * shnbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sol-thread.c (sol_thread_fetch_registers): Likewise. (sol_thread_store_registers): Likewise. * sparc-nat.c (fetch_inferior_registers): Likewise. (store_inferior_registers): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. (spu_store_inferior_registers): Likewise. * target.c (debug_print_register): Likewise. (debug_to_fetch_registers, debug_to_store_registers): Likewise. * vaxbsd-nat.c (vaxbsd_fetch_inferior_registers): Likewise. (vaxbsd_store_inferior_registers): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers): Likewise. (win32_fetch_inferior_registers): Likewise. (win32_store_inferior_registers): Likewise.
2007-05-06 22:34:38 +08:00
fetch_register (regcache, tid, tdep->ppc_cr_regnum);
if (tdep->ppc_lr_regnum != -1)
* target.h (struct regcache): Add forward declaration. (struct target_ops): Add REGCACHE parameter to to_fetch_registers and to_store_registers target operations. (target_fetch_registers, target_store_registers): Update. * regcache.c (regcache_raw_read): Replace register_cached by regcache_valid_p. Pass regcache to target_fetch_registers. (regcache_raw_write): Pass regcache to target_store_registers. * arm-linux-nat.c (store_fpregister, store_fpregs, store_register, store_regs, store_wmmx_regs): Replace register_cached by regcache_valid_p. * bsd-kvm.c (bsd_kvm_open, bsd_kvm_proc_cmd): Pass current_regcache to target_fetch_registers calls. * corelow.c (core_open): Likewise. * linux-nat.c (linux_nat_corefile_thread_callback): Likewise. * proc-service.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * sol-thread.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * win32-nat.c (win32_resume): Likewise. * ia64-tdep.c (ia64_store_return_value): Pass current_regcache to target_store_registers call. * rs6000-tdep.c (rs6000_push_dummy_call): Likewise. * inferior.h (store_inferior_registers): Update prototype. (fetch_inferior_registers): Likewise. * gnu-nat.c (gnu_store_registers, gnu_fetch_registers): Likewise. * mips-linux-nat.c (super_fetch_registers, super_store_registers): Update function pointer signatures. * aix-thread.c (aix_thread_fetch_registers): Add REGCACHE parameter, use it instead of current_regcache, update calls. (aix_thread_store_registers): Likewise. * alphabsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * amd64bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_fpregister, fetch_fpregs, store_fpregister, store_fpregs, fetch_register, fetch_regs, store_register, store_regs, fetch_wmmx_regs, store_wmmx_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * armnbsd-nat.c (fetch_register, fetch_regs, fetch_fp_register, fetch_fp_regs, armnbsd_fetch_registers): Likewise. (store_register, store_regs, store_fp_register, store_fp_regs, armnbsd_store_registers): Likewise. * bsd-kvm.c (bsd_kvm_fetch_pcb, bsd_kvm_fetch_registers): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * corelow.c (get_core_registers): Likewise. * go32-nat.c (fetch_register, go32_fetch_registers, store_register, go32_store_registers): Likewise. * hppabsd-nat.c (hppabsd_fetch_registers): Likewise. (hppabsd_store_registers): Likewise. * hppa-hpux-nat.c (hppa_hpux_fetch_register): Likewise. (hppa_hpux_fetch_inferior_registers): Likewise. (hppa_hpux_store_register): Likewise. (hppa_hpux_store_inferior_registers): Likewise. * hppa-linux-nat.c (fetch_register, store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * hpux-thread.c (hpux_thread_fetch_registers): Likewise. (hpux_thread_store_registers): Likewise. * i386bsd-nat.c (i386bsd_fetch_inferior_registers): Likewise. (i386bsd_store_inferior_registers): Likewise. * i386gnu-nat.c (fetch_fpregs, gnu_fetch_registers, store_fpregs, gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register, store_register, fetch_regs, store_regs, fetch_fpregs, store_fpregs, fetch_fpxregs, store_fpxregs): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_register): Likewise. (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_register): Likewise. (ia64_linux_store_registers): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. (inf_child_store_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register): Likewise. (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_register): Likewise. (inf_ptrace_store_registers): Likewise. * infptrace.c (fetch_register, store_register): Likewise. (fetch_inferior_registers, store_inferior_registers): Likewise. * m32r-linux-nat.c (fetch_regs, store_regs): Likewise. (m32r_linux_fetch_inferior_registers): Likewise. (m32r_linux_store_inferior_registers): Likewise. * m68kbsd-nat.c (m68kbsd_fetch_inferior_registers): Likewise. (m68kbsd_store_inferior_registers): Likewise. * m68klinux-nat.c (fetch_register, old_fetch_inferior_registers, store_register, old_store_inferior_registers, fetch_regs, store_regs, fetch_fpregs, store_fpregs): Likewise. (m68k_linux_fetch_inferior_registers): Likewise. (m68k_linux_store_inferior_registers): Likewise. * m88kbsd-nat.c (m88kbsd_fetch_inferior_registers): Likewise. (m88kbsd_store_inferior_registers): Likewise. * mips64obsd-nat.c (mips64obsd_fetch_inferior_registers): Likewise. (mips64obsd_store_inferior_registers): Likewise. * mips-linux-nat.c (mips64_linux_regsets_fetch_registers): Likewise. (mips64_linux_regsets_store_registers): Likewise. (mips64_linux_fetch_registers): Likewise. (mips64_linux_store_registers): Likewise. * mipsnbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * monitor.c (monitor_fetch_register, monitor_store_register): Likewise. (monitor_fetch_registers, monitor_store_registers): Likewise. * nto-procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register, fetch_register, supply_vrregset, fetch_altivec_registers, fetch_ppc_registers, ppc_linux_fetch_inferior_registers): Likewise. (store_altivec_register, store_spe_register, store_register, fill_vrregset, store_altivec_registers, store_ppc_registers, ppc_linux_store_inferior_registers): Likewise. * ppcnbsd-nat.c (ppcnbsd_fetch_inferior_registers): Likewise. (ppcnbsd_store_inferior_registers): Likewise. * ppcobsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote.c (fetch_register_using_p, process_g_packet, fetch_registers_using_g, remote_fetch_registers): Likewise. (store_register_using_P, store_registers_using_G, remote_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers, m32r_fetch_register, m32r_store_register, m32r_store_register): Likewise. * remote-mips.c (mips_fetch_registers, mips_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * rs6000-nat.c (fetch_register, store_register): Likewise. (rs6000_fetch_inferior_registers): Likewise. (rs6000_store_inferior_registers): Likewise. * s390-nat.c (fetch_regs, store_regs): Likewise. (fetch_fpregs, store_fpregs): Likewise. (s390_linux_fetch_inferior_registers): Likewise. (s390_linux_store_inferior_registers): Likewise. * shnbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sol-thread.c (sol_thread_fetch_registers): Likewise. (sol_thread_store_registers): Likewise. * sparc-nat.c (fetch_inferior_registers): Likewise. (store_inferior_registers): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. (spu_store_inferior_registers): Likewise. * target.c (debug_print_register): Likewise. (debug_to_fetch_registers, debug_to_store_registers): Likewise. * vaxbsd-nat.c (vaxbsd_fetch_inferior_registers): Likewise. (vaxbsd_store_inferior_registers): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers): Likewise. (win32_fetch_inferior_registers): Likewise. (win32_store_inferior_registers): Likewise.
2007-05-06 22:34:38 +08:00
fetch_register (regcache, tid, tdep->ppc_lr_regnum);
if (tdep->ppc_ctr_regnum != -1)
* target.h (struct regcache): Add forward declaration. (struct target_ops): Add REGCACHE parameter to to_fetch_registers and to_store_registers target operations. (target_fetch_registers, target_store_registers): Update. * regcache.c (regcache_raw_read): Replace register_cached by regcache_valid_p. Pass regcache to target_fetch_registers. (regcache_raw_write): Pass regcache to target_store_registers. * arm-linux-nat.c (store_fpregister, store_fpregs, store_register, store_regs, store_wmmx_regs): Replace register_cached by regcache_valid_p. * bsd-kvm.c (bsd_kvm_open, bsd_kvm_proc_cmd): Pass current_regcache to target_fetch_registers calls. * corelow.c (core_open): Likewise. * linux-nat.c (linux_nat_corefile_thread_callback): Likewise. * proc-service.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * sol-thread.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * win32-nat.c (win32_resume): Likewise. * ia64-tdep.c (ia64_store_return_value): Pass current_regcache to target_store_registers call. * rs6000-tdep.c (rs6000_push_dummy_call): Likewise. * inferior.h (store_inferior_registers): Update prototype. (fetch_inferior_registers): Likewise. * gnu-nat.c (gnu_store_registers, gnu_fetch_registers): Likewise. * mips-linux-nat.c (super_fetch_registers, super_store_registers): Update function pointer signatures. * aix-thread.c (aix_thread_fetch_registers): Add REGCACHE parameter, use it instead of current_regcache, update calls. (aix_thread_store_registers): Likewise. * alphabsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * amd64bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_fpregister, fetch_fpregs, store_fpregister, store_fpregs, fetch_register, fetch_regs, store_register, store_regs, fetch_wmmx_regs, store_wmmx_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * armnbsd-nat.c (fetch_register, fetch_regs, fetch_fp_register, fetch_fp_regs, armnbsd_fetch_registers): Likewise. (store_register, store_regs, store_fp_register, store_fp_regs, armnbsd_store_registers): Likewise. * bsd-kvm.c (bsd_kvm_fetch_pcb, bsd_kvm_fetch_registers): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * corelow.c (get_core_registers): Likewise. * go32-nat.c (fetch_register, go32_fetch_registers, store_register, go32_store_registers): Likewise. * hppabsd-nat.c (hppabsd_fetch_registers): Likewise. (hppabsd_store_registers): Likewise. * hppa-hpux-nat.c (hppa_hpux_fetch_register): Likewise. (hppa_hpux_fetch_inferior_registers): Likewise. (hppa_hpux_store_register): Likewise. (hppa_hpux_store_inferior_registers): Likewise. * hppa-linux-nat.c (fetch_register, store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * hpux-thread.c (hpux_thread_fetch_registers): Likewise. (hpux_thread_store_registers): Likewise. * i386bsd-nat.c (i386bsd_fetch_inferior_registers): Likewise. (i386bsd_store_inferior_registers): Likewise. * i386gnu-nat.c (fetch_fpregs, gnu_fetch_registers, store_fpregs, gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register, store_register, fetch_regs, store_regs, fetch_fpregs, store_fpregs, fetch_fpxregs, store_fpxregs): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_register): Likewise. (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_register): Likewise. (ia64_linux_store_registers): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. (inf_child_store_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register): Likewise. (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_register): Likewise. (inf_ptrace_store_registers): Likewise. * infptrace.c (fetch_register, store_register): Likewise. (fetch_inferior_registers, store_inferior_registers): Likewise. * m32r-linux-nat.c (fetch_regs, store_regs): Likewise. (m32r_linux_fetch_inferior_registers): Likewise. (m32r_linux_store_inferior_registers): Likewise. * m68kbsd-nat.c (m68kbsd_fetch_inferior_registers): Likewise. (m68kbsd_store_inferior_registers): Likewise. * m68klinux-nat.c (fetch_register, old_fetch_inferior_registers, store_register, old_store_inferior_registers, fetch_regs, store_regs, fetch_fpregs, store_fpregs): Likewise. (m68k_linux_fetch_inferior_registers): Likewise. (m68k_linux_store_inferior_registers): Likewise. * m88kbsd-nat.c (m88kbsd_fetch_inferior_registers): Likewise. (m88kbsd_store_inferior_registers): Likewise. * mips64obsd-nat.c (mips64obsd_fetch_inferior_registers): Likewise. (mips64obsd_store_inferior_registers): Likewise. * mips-linux-nat.c (mips64_linux_regsets_fetch_registers): Likewise. (mips64_linux_regsets_store_registers): Likewise. (mips64_linux_fetch_registers): Likewise. (mips64_linux_store_registers): Likewise. * mipsnbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * monitor.c (monitor_fetch_register, monitor_store_register): Likewise. (monitor_fetch_registers, monitor_store_registers): Likewise. * nto-procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register, fetch_register, supply_vrregset, fetch_altivec_registers, fetch_ppc_registers, ppc_linux_fetch_inferior_registers): Likewise. (store_altivec_register, store_spe_register, store_register, fill_vrregset, store_altivec_registers, store_ppc_registers, ppc_linux_store_inferior_registers): Likewise. * ppcnbsd-nat.c (ppcnbsd_fetch_inferior_registers): Likewise. (ppcnbsd_store_inferior_registers): Likewise. * ppcobsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote.c (fetch_register_using_p, process_g_packet, fetch_registers_using_g, remote_fetch_registers): Likewise. (store_register_using_P, store_registers_using_G, remote_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers, m32r_fetch_register, m32r_store_register, m32r_store_register): Likewise. * remote-mips.c (mips_fetch_registers, mips_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * rs6000-nat.c (fetch_register, store_register): Likewise. (rs6000_fetch_inferior_registers): Likewise. (rs6000_store_inferior_registers): Likewise. * s390-nat.c (fetch_regs, store_regs): Likewise. (fetch_fpregs, store_fpregs): Likewise. (s390_linux_fetch_inferior_registers): Likewise. (s390_linux_store_inferior_registers): Likewise. * shnbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sol-thread.c (sol_thread_fetch_registers): Likewise. (sol_thread_store_registers): Likewise. * sparc-nat.c (fetch_inferior_registers): Likewise. (store_inferior_registers): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. (spu_store_inferior_registers): Likewise. * target.c (debug_print_register): Likewise. (debug_to_fetch_registers, debug_to_store_registers): Likewise. * vaxbsd-nat.c (vaxbsd_fetch_inferior_registers): Likewise. (vaxbsd_store_inferior_registers): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers): Likewise. (win32_fetch_inferior_registers): Likewise. (win32_store_inferior_registers): Likewise.
2007-05-06 22:34:38 +08:00
fetch_register (regcache, tid, tdep->ppc_ctr_regnum);
if (tdep->ppc_xer_regnum != -1)
* target.h (struct regcache): Add forward declaration. (struct target_ops): Add REGCACHE parameter to to_fetch_registers and to_store_registers target operations. (target_fetch_registers, target_store_registers): Update. * regcache.c (regcache_raw_read): Replace register_cached by regcache_valid_p. Pass regcache to target_fetch_registers. (regcache_raw_write): Pass regcache to target_store_registers. * arm-linux-nat.c (store_fpregister, store_fpregs, store_register, store_regs, store_wmmx_regs): Replace register_cached by regcache_valid_p. * bsd-kvm.c (bsd_kvm_open, bsd_kvm_proc_cmd): Pass current_regcache to target_fetch_registers calls. * corelow.c (core_open): Likewise. * linux-nat.c (linux_nat_corefile_thread_callback): Likewise. * proc-service.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * sol-thread.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * win32-nat.c (win32_resume): Likewise. * ia64-tdep.c (ia64_store_return_value): Pass current_regcache to target_store_registers call. * rs6000-tdep.c (rs6000_push_dummy_call): Likewise. * inferior.h (store_inferior_registers): Update prototype. (fetch_inferior_registers): Likewise. * gnu-nat.c (gnu_store_registers, gnu_fetch_registers): Likewise. * mips-linux-nat.c (super_fetch_registers, super_store_registers): Update function pointer signatures. * aix-thread.c (aix_thread_fetch_registers): Add REGCACHE parameter, use it instead of current_regcache, update calls. (aix_thread_store_registers): Likewise. * alphabsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * amd64bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_fpregister, fetch_fpregs, store_fpregister, store_fpregs, fetch_register, fetch_regs, store_register, store_regs, fetch_wmmx_regs, store_wmmx_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * armnbsd-nat.c (fetch_register, fetch_regs, fetch_fp_register, fetch_fp_regs, armnbsd_fetch_registers): Likewise. (store_register, store_regs, store_fp_register, store_fp_regs, armnbsd_store_registers): Likewise. * bsd-kvm.c (bsd_kvm_fetch_pcb, bsd_kvm_fetch_registers): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * corelow.c (get_core_registers): Likewise. * go32-nat.c (fetch_register, go32_fetch_registers, store_register, go32_store_registers): Likewise. * hppabsd-nat.c (hppabsd_fetch_registers): Likewise. (hppabsd_store_registers): Likewise. * hppa-hpux-nat.c (hppa_hpux_fetch_register): Likewise. (hppa_hpux_fetch_inferior_registers): Likewise. (hppa_hpux_store_register): Likewise. (hppa_hpux_store_inferior_registers): Likewise. * hppa-linux-nat.c (fetch_register, store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * hpux-thread.c (hpux_thread_fetch_registers): Likewise. (hpux_thread_store_registers): Likewise. * i386bsd-nat.c (i386bsd_fetch_inferior_registers): Likewise. (i386bsd_store_inferior_registers): Likewise. * i386gnu-nat.c (fetch_fpregs, gnu_fetch_registers, store_fpregs, gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register, store_register, fetch_regs, store_regs, fetch_fpregs, store_fpregs, fetch_fpxregs, store_fpxregs): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_register): Likewise. (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_register): Likewise. (ia64_linux_store_registers): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. (inf_child_store_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register): Likewise. (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_register): Likewise. (inf_ptrace_store_registers): Likewise. * infptrace.c (fetch_register, store_register): Likewise. (fetch_inferior_registers, store_inferior_registers): Likewise. * m32r-linux-nat.c (fetch_regs, store_regs): Likewise. (m32r_linux_fetch_inferior_registers): Likewise. (m32r_linux_store_inferior_registers): Likewise. * m68kbsd-nat.c (m68kbsd_fetch_inferior_registers): Likewise. (m68kbsd_store_inferior_registers): Likewise. * m68klinux-nat.c (fetch_register, old_fetch_inferior_registers, store_register, old_store_inferior_registers, fetch_regs, store_regs, fetch_fpregs, store_fpregs): Likewise. (m68k_linux_fetch_inferior_registers): Likewise. (m68k_linux_store_inferior_registers): Likewise. * m88kbsd-nat.c (m88kbsd_fetch_inferior_registers): Likewise. (m88kbsd_store_inferior_registers): Likewise. * mips64obsd-nat.c (mips64obsd_fetch_inferior_registers): Likewise. (mips64obsd_store_inferior_registers): Likewise. * mips-linux-nat.c (mips64_linux_regsets_fetch_registers): Likewise. (mips64_linux_regsets_store_registers): Likewise. (mips64_linux_fetch_registers): Likewise. (mips64_linux_store_registers): Likewise. * mipsnbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * monitor.c (monitor_fetch_register, monitor_store_register): Likewise. (monitor_fetch_registers, monitor_store_registers): Likewise. * nto-procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register, fetch_register, supply_vrregset, fetch_altivec_registers, fetch_ppc_registers, ppc_linux_fetch_inferior_registers): Likewise. (store_altivec_register, store_spe_register, store_register, fill_vrregset, store_altivec_registers, store_ppc_registers, ppc_linux_store_inferior_registers): Likewise. * ppcnbsd-nat.c (ppcnbsd_fetch_inferior_registers): Likewise. (ppcnbsd_store_inferior_registers): Likewise. * ppcobsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote.c (fetch_register_using_p, process_g_packet, fetch_registers_using_g, remote_fetch_registers): Likewise. (store_register_using_P, store_registers_using_G, remote_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers, m32r_fetch_register, m32r_store_register, m32r_store_register): Likewise. * remote-mips.c (mips_fetch_registers, mips_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * rs6000-nat.c (fetch_register, store_register): Likewise. (rs6000_fetch_inferior_registers): Likewise. (rs6000_store_inferior_registers): Likewise. * s390-nat.c (fetch_regs, store_regs): Likewise. (fetch_fpregs, store_fpregs): Likewise. (s390_linux_fetch_inferior_registers): Likewise. (s390_linux_store_inferior_registers): Likewise. * shnbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sol-thread.c (sol_thread_fetch_registers): Likewise. (sol_thread_store_registers): Likewise. * sparc-nat.c (fetch_inferior_registers): Likewise. (store_inferior_registers): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. (spu_store_inferior_registers): Likewise. * target.c (debug_print_register): Likewise. (debug_to_fetch_registers, debug_to_store_registers): Likewise. * vaxbsd-nat.c (vaxbsd_fetch_inferior_registers): Likewise. (vaxbsd_store_inferior_registers): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers): Likewise. (win32_fetch_inferior_registers): Likewise. (win32_store_inferior_registers): Likewise.
2007-05-06 22:34:38 +08:00
fetch_register (regcache, tid, tdep->ppc_xer_regnum);
if (tdep->ppc_mq_regnum != -1)
* target.h (struct regcache): Add forward declaration. (struct target_ops): Add REGCACHE parameter to to_fetch_registers and to_store_registers target operations. (target_fetch_registers, target_store_registers): Update. * regcache.c (regcache_raw_read): Replace register_cached by regcache_valid_p. Pass regcache to target_fetch_registers. (regcache_raw_write): Pass regcache to target_store_registers. * arm-linux-nat.c (store_fpregister, store_fpregs, store_register, store_regs, store_wmmx_regs): Replace register_cached by regcache_valid_p. * bsd-kvm.c (bsd_kvm_open, bsd_kvm_proc_cmd): Pass current_regcache to target_fetch_registers calls. * corelow.c (core_open): Likewise. * linux-nat.c (linux_nat_corefile_thread_callback): Likewise. * proc-service.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * sol-thread.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * win32-nat.c (win32_resume): Likewise. * ia64-tdep.c (ia64_store_return_value): Pass current_regcache to target_store_registers call. * rs6000-tdep.c (rs6000_push_dummy_call): Likewise. * inferior.h (store_inferior_registers): Update prototype. (fetch_inferior_registers): Likewise. * gnu-nat.c (gnu_store_registers, gnu_fetch_registers): Likewise. * mips-linux-nat.c (super_fetch_registers, super_store_registers): Update function pointer signatures. * aix-thread.c (aix_thread_fetch_registers): Add REGCACHE parameter, use it instead of current_regcache, update calls. (aix_thread_store_registers): Likewise. * alphabsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * amd64bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_fpregister, fetch_fpregs, store_fpregister, store_fpregs, fetch_register, fetch_regs, store_register, store_regs, fetch_wmmx_regs, store_wmmx_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * armnbsd-nat.c (fetch_register, fetch_regs, fetch_fp_register, fetch_fp_regs, armnbsd_fetch_registers): Likewise. (store_register, store_regs, store_fp_register, store_fp_regs, armnbsd_store_registers): Likewise. * bsd-kvm.c (bsd_kvm_fetch_pcb, bsd_kvm_fetch_registers): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * corelow.c (get_core_registers): Likewise. * go32-nat.c (fetch_register, go32_fetch_registers, store_register, go32_store_registers): Likewise. * hppabsd-nat.c (hppabsd_fetch_registers): Likewise. (hppabsd_store_registers): Likewise. * hppa-hpux-nat.c (hppa_hpux_fetch_register): Likewise. (hppa_hpux_fetch_inferior_registers): Likewise. (hppa_hpux_store_register): Likewise. (hppa_hpux_store_inferior_registers): Likewise. * hppa-linux-nat.c (fetch_register, store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * hpux-thread.c (hpux_thread_fetch_registers): Likewise. (hpux_thread_store_registers): Likewise. * i386bsd-nat.c (i386bsd_fetch_inferior_registers): Likewise. (i386bsd_store_inferior_registers): Likewise. * i386gnu-nat.c (fetch_fpregs, gnu_fetch_registers, store_fpregs, gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register, store_register, fetch_regs, store_regs, fetch_fpregs, store_fpregs, fetch_fpxregs, store_fpxregs): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_register): Likewise. (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_register): Likewise. (ia64_linux_store_registers): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. (inf_child_store_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register): Likewise. (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_register): Likewise. (inf_ptrace_store_registers): Likewise. * infptrace.c (fetch_register, store_register): Likewise. (fetch_inferior_registers, store_inferior_registers): Likewise. * m32r-linux-nat.c (fetch_regs, store_regs): Likewise. (m32r_linux_fetch_inferior_registers): Likewise. (m32r_linux_store_inferior_registers): Likewise. * m68kbsd-nat.c (m68kbsd_fetch_inferior_registers): Likewise. (m68kbsd_store_inferior_registers): Likewise. * m68klinux-nat.c (fetch_register, old_fetch_inferior_registers, store_register, old_store_inferior_registers, fetch_regs, store_regs, fetch_fpregs, store_fpregs): Likewise. (m68k_linux_fetch_inferior_registers): Likewise. (m68k_linux_store_inferior_registers): Likewise. * m88kbsd-nat.c (m88kbsd_fetch_inferior_registers): Likewise. (m88kbsd_store_inferior_registers): Likewise. * mips64obsd-nat.c (mips64obsd_fetch_inferior_registers): Likewise. (mips64obsd_store_inferior_registers): Likewise. * mips-linux-nat.c (mips64_linux_regsets_fetch_registers): Likewise. (mips64_linux_regsets_store_registers): Likewise. (mips64_linux_fetch_registers): Likewise. (mips64_linux_store_registers): Likewise. * mipsnbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * monitor.c (monitor_fetch_register, monitor_store_register): Likewise. (monitor_fetch_registers, monitor_store_registers): Likewise. * nto-procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register, fetch_register, supply_vrregset, fetch_altivec_registers, fetch_ppc_registers, ppc_linux_fetch_inferior_registers): Likewise. (store_altivec_register, store_spe_register, store_register, fill_vrregset, store_altivec_registers, store_ppc_registers, ppc_linux_store_inferior_registers): Likewise. * ppcnbsd-nat.c (ppcnbsd_fetch_inferior_registers): Likewise. (ppcnbsd_store_inferior_registers): Likewise. * ppcobsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote.c (fetch_register_using_p, process_g_packet, fetch_registers_using_g, remote_fetch_registers): Likewise. (store_register_using_P, store_registers_using_G, remote_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers, m32r_fetch_register, m32r_store_register, m32r_store_register): Likewise. * remote-mips.c (mips_fetch_registers, mips_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * rs6000-nat.c (fetch_register, store_register): Likewise. (rs6000_fetch_inferior_registers): Likewise. (rs6000_store_inferior_registers): Likewise. * s390-nat.c (fetch_regs, store_regs): Likewise. (fetch_fpregs, store_fpregs): Likewise. (s390_linux_fetch_inferior_registers): Likewise. (s390_linux_store_inferior_registers): Likewise. * shnbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sol-thread.c (sol_thread_fetch_registers): Likewise. (sol_thread_store_registers): Likewise. * sparc-nat.c (fetch_inferior_registers): Likewise. (store_inferior_registers): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. (spu_store_inferior_registers): Likewise. * target.c (debug_print_register): Likewise. (debug_to_fetch_registers, debug_to_store_registers): Likewise. * vaxbsd-nat.c (vaxbsd_fetch_inferior_registers): Likewise. (vaxbsd_store_inferior_registers): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers): Likewise. (win32_fetch_inferior_registers): Likewise. (win32_store_inferior_registers): Likewise.
2007-05-06 22:34:38 +08:00
fetch_register (regcache, tid, tdep->ppc_mq_regnum);
ChangeLog: * Makefile.in (ppc_linux_tdep_h): New macro. (powerpc_32l_c, powerpc_altivec32_c, powerpc_altivec32l_c): Likewise. (powerpc_64l_c, powerpc_altivec64_c, powerpc_altivec64l_c): Likewise. (powerpc_e500l_c): Likewise. (ppc-linux-nat.o): Update dependencies. (ppc-linux-tdep.o): Update dependencies. (rs6000-tdep.o): Update dependencies. * ppc-tdep.h (ppc_linux_memory_remove_breakpoint): Remove. (ppc_linux_svr4_fetch_link_map_offsets): Remove. (ppc_linux_gregset, ppc_linux_fpregset): Move to ppc-linux-tdep.h (ppc_supply_reg, ppc_collect_reg): Add prototypes. (tdesc_powerpc_e500): Remove. * rs6000.c: Include "features/rs6000/powerpc-altivec32.c" and "features/rs6000/powerpc-altivec64.c". (ppc_supply_reg, ppc_collect_reg): Make global. (variants): Use tdesc_powerpc_32 for "powerpc" and tdesc_powerpc_altivec64 for "powerpc64". (_initialize_rs6000_tdep): Initialize AltiVec descriptions. * ppc-linux-tdep.h: New file. * ppc-linux-tdep.c: Include "ppc-linux-tdep.c". Include "features/rs6000/powerpc-32l.c". Include "features/rs6000/powerpc-altivec32l.c". Include "features/rs6000/powerpc-64l.c". Include "features/rs6000/powerpc-altivec64l.c". Include "features/rs6000/powerpc-e500l.c". (ppc_linux_supply_gregset): New function. (ppc_linux_collect_gregset): Handle orig_r3 and trap registers. (ppc32_linux_gregset): Use ppc_linux_supply_gregset. (ppc64_linux_gregset): Likewise. (ppc_linux_sigtramp_cache): Handle orig_r3 and trap registers. (ppc_linux_trap_reg_p): New function. (ppc_linux_write_pc): New function. (ppc_linux_core_read_description): New function. (ppc_linux_init_abi): Install ppc_linux_write_pc and ppc_linux_core_read_description. Install orig_r3 and trap registers if present in the target description. (_initialize_ppc_linux_tdep): Initialize Linux target descriptions. * ppc-linux-nat.c: Include "ppc-linux-tdep.h". (PT_ORIG_R3, PT_TRAP): Define if necessary. (ppc_register_u_addr): Handle orig_r3 and trap registers. (fetch_ppc_registers): Likewise. (store_ppc_registers): Likewise. (store_register): Likewise. (ppc_linux_read_description): Check whether AltiVec is supported. Check whether inferior is 32-bit or 64-bit. Return the appropriate Linux target description. * features/Makefile (WHICH): Use rs6000/powerpc-32l and rs6000/powerpc-altivec32l instead of rs6000/powerpc-32. Use rs6000/powerpc-64l and rs6000/powerpc-altivec64l instead of rs6000/powerpc-64. Use rs6000/powerpc-e500l instead of rs6000/powerpc-e500. Update -expedite variables accordingly. * features/rs6000/power-spe.xml: Use regnum 73 for "acc". * features/rs6000/powerpc-32.xml: Do not include power-altivec.xml. * features/rs6000/powerpc-64.xml: Do not include power-altivec.xml. * features/rs6000/powerpc-e500.c: Regenerate. * features/rs6000/powerpc-32.c: Regenerate. * features/rs6000/powerpc-64.c: Regenerate. * features/rs6000/power-linux.xml: New file. * features/rs6000/power64-linux.xml: New file. * features/rs6000/powerpc-32l.xml: New file. * features/rs6000/powerpc-altivec32l.xml: New file. * features/rs6000/powerpc-64l.xml: New file. * features/rs6000/powerpc-altivec64l.xml: New file. * features/rs6000/powerpc-e500l.xml: New file. * features/rs6000/powerpc-32l.c: New (generated) file. * features/rs6000/powerpc-altivec32l.c: New (generated) file. * features/rs6000/powerpc-64l.c: New (generated) file. * features/rs6000/powerpc-altivec64l.c: New (generated) file. * features/rs6000/powerpc-e500l.xml: New (generated) file. * regformats/reg-ppc.dat: Remove. * regformats/reg-ppc64.dat: Remove. * regformats/rs6000/powerpc-32.dat: Remove. * regformats/rs6000/powerpc-64.dat: Remove. * regformats/rs6000/powerpc-e500.dat: Remove. * regformats/rs6000/powerpc-32l.dat: New (generated) file. * regformats/rs6000/powerpc-altivec32l.dat: New (generated) file. * regformats/rs6000/powerpc-64l.dat: New (generated) file. * regformats/rs6000/powerpc-altivec64l.dat: New (generated) file. * regformats/rs6000/powerpc-e500l.dat: New (generated) file. gdbserver/ChangeLog: * configure.srv (powerpc*-*-linux*): Set srv_regobj to powerpc-32l.o, powerpc-altivec32l.o, powerpc-e500l.o, powerpc-64l.o, and powerpc-altivec64l.o. Remove rs6000/powerpc-32.xml, rs6000/powerpc-64.xml, and rs6000/powerpc-e500.xml; add rs6000/powerpc-32l.xml, rs6000/powerpc-altivec32l.xml, rs6000/powerpc-e500l.xml, rs6000/powerpc-64l.xml, rs6000/powerpc-altivec64l.xml, rs6000/power-linux.xml, and rs6000/power64-linux.xml to srv_xmlfiles. * Makefile.in (reg-ppc.o, reg-ppc.c): Remove, replace by ... (powerpc-32l.o, powerpc-32l.c): ... these new rules. (powerpc-32.o, powerpc-32.c): Remove, replace by ... (powerpc-altivec32l.o, powerpc-altivec32l.c): ... these new rules. (powerpc-e500.o, powerpc-e500.c): Remove, replace by ... (powerpc-e500l.o, powerpc-e500l.c): ... these new rules. (reg-ppc64.o, reg-ppc64.c): Remove, replace by ... (powerpc-64l.o, powerpc-64l.c): ... these new rules. (powerpc-64.o, powerpc-64.c): Remove, replace by ... (powerpc-altivec64l.o, powerpc-altivec64l.c): ... these new rules. (clean): Update. * linux-ppc-low.c (init_registers_ppc): Remove, replace by ... (init_registers_powerpc_32l): ... this new prototype. (init_registers_powerpc_32): Remove, replace by ... (init_registers_powerpc_altivec32l): ... this new prototype. (init_registers_powerpc_e500): Remove, replace by ... (init_registers_powerpc_e500l): ... this new prototype. (init_registers_ppc64): Remove, replace by ... (init_registers_powerpc_64l): ... this new prototype. (init_registers_powerpc_64): Remove, replace by ... (init_registers_powerpc_altivec64l): ... this new prototype. (ppc_num_regs): Set to 73. (PT_ORIG_R3, PT_TRAP): Define if necessary. (ppc_regmap, ppc_regmap_e500): Add values for orig_r3 and trap. (ppc_cannot_store_register): Handle orig_r3 and trap. (ppc_arch_setup): Update init_registers_... calls. (ppc_fill_gregset): Handle orig_r3 and trap. * inferiors.c (clear_inferiors): Reset current_inferior.
2008-05-04 01:16:44 +08:00
if (ppc_linux_trap_reg_p (gdbarch))
{
fetch_register (regcache, tid, PPC_ORIG_R3_REGNUM);
fetch_register (regcache, tid, PPC_TRAP_REGNUM);
}
if (tdep->ppc_fpscr_regnum != -1)
* target.h (struct regcache): Add forward declaration. (struct target_ops): Add REGCACHE parameter to to_fetch_registers and to_store_registers target operations. (target_fetch_registers, target_store_registers): Update. * regcache.c (regcache_raw_read): Replace register_cached by regcache_valid_p. Pass regcache to target_fetch_registers. (regcache_raw_write): Pass regcache to target_store_registers. * arm-linux-nat.c (store_fpregister, store_fpregs, store_register, store_regs, store_wmmx_regs): Replace register_cached by regcache_valid_p. * bsd-kvm.c (bsd_kvm_open, bsd_kvm_proc_cmd): Pass current_regcache to target_fetch_registers calls. * corelow.c (core_open): Likewise. * linux-nat.c (linux_nat_corefile_thread_callback): Likewise. * proc-service.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * sol-thread.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * win32-nat.c (win32_resume): Likewise. * ia64-tdep.c (ia64_store_return_value): Pass current_regcache to target_store_registers call. * rs6000-tdep.c (rs6000_push_dummy_call): Likewise. * inferior.h (store_inferior_registers): Update prototype. (fetch_inferior_registers): Likewise. * gnu-nat.c (gnu_store_registers, gnu_fetch_registers): Likewise. * mips-linux-nat.c (super_fetch_registers, super_store_registers): Update function pointer signatures. * aix-thread.c (aix_thread_fetch_registers): Add REGCACHE parameter, use it instead of current_regcache, update calls. (aix_thread_store_registers): Likewise. * alphabsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * amd64bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_fpregister, fetch_fpregs, store_fpregister, store_fpregs, fetch_register, fetch_regs, store_register, store_regs, fetch_wmmx_regs, store_wmmx_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * armnbsd-nat.c (fetch_register, fetch_regs, fetch_fp_register, fetch_fp_regs, armnbsd_fetch_registers): Likewise. (store_register, store_regs, store_fp_register, store_fp_regs, armnbsd_store_registers): Likewise. * bsd-kvm.c (bsd_kvm_fetch_pcb, bsd_kvm_fetch_registers): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * corelow.c (get_core_registers): Likewise. * go32-nat.c (fetch_register, go32_fetch_registers, store_register, go32_store_registers): Likewise. * hppabsd-nat.c (hppabsd_fetch_registers): Likewise. (hppabsd_store_registers): Likewise. * hppa-hpux-nat.c (hppa_hpux_fetch_register): Likewise. (hppa_hpux_fetch_inferior_registers): Likewise. (hppa_hpux_store_register): Likewise. (hppa_hpux_store_inferior_registers): Likewise. * hppa-linux-nat.c (fetch_register, store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * hpux-thread.c (hpux_thread_fetch_registers): Likewise. (hpux_thread_store_registers): Likewise. * i386bsd-nat.c (i386bsd_fetch_inferior_registers): Likewise. (i386bsd_store_inferior_registers): Likewise. * i386gnu-nat.c (fetch_fpregs, gnu_fetch_registers, store_fpregs, gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register, store_register, fetch_regs, store_regs, fetch_fpregs, store_fpregs, fetch_fpxregs, store_fpxregs): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_register): Likewise. (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_register): Likewise. (ia64_linux_store_registers): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. (inf_child_store_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register): Likewise. (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_register): Likewise. (inf_ptrace_store_registers): Likewise. * infptrace.c (fetch_register, store_register): Likewise. (fetch_inferior_registers, store_inferior_registers): Likewise. * m32r-linux-nat.c (fetch_regs, store_regs): Likewise. (m32r_linux_fetch_inferior_registers): Likewise. (m32r_linux_store_inferior_registers): Likewise. * m68kbsd-nat.c (m68kbsd_fetch_inferior_registers): Likewise. (m68kbsd_store_inferior_registers): Likewise. * m68klinux-nat.c (fetch_register, old_fetch_inferior_registers, store_register, old_store_inferior_registers, fetch_regs, store_regs, fetch_fpregs, store_fpregs): Likewise. (m68k_linux_fetch_inferior_registers): Likewise. (m68k_linux_store_inferior_registers): Likewise. * m88kbsd-nat.c (m88kbsd_fetch_inferior_registers): Likewise. (m88kbsd_store_inferior_registers): Likewise. * mips64obsd-nat.c (mips64obsd_fetch_inferior_registers): Likewise. (mips64obsd_store_inferior_registers): Likewise. * mips-linux-nat.c (mips64_linux_regsets_fetch_registers): Likewise. (mips64_linux_regsets_store_registers): Likewise. (mips64_linux_fetch_registers): Likewise. (mips64_linux_store_registers): Likewise. * mipsnbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * monitor.c (monitor_fetch_register, monitor_store_register): Likewise. (monitor_fetch_registers, monitor_store_registers): Likewise. * nto-procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register, fetch_register, supply_vrregset, fetch_altivec_registers, fetch_ppc_registers, ppc_linux_fetch_inferior_registers): Likewise. (store_altivec_register, store_spe_register, store_register, fill_vrregset, store_altivec_registers, store_ppc_registers, ppc_linux_store_inferior_registers): Likewise. * ppcnbsd-nat.c (ppcnbsd_fetch_inferior_registers): Likewise. (ppcnbsd_store_inferior_registers): Likewise. * ppcobsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote.c (fetch_register_using_p, process_g_packet, fetch_registers_using_g, remote_fetch_registers): Likewise. (store_register_using_P, store_registers_using_G, remote_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers, m32r_fetch_register, m32r_store_register, m32r_store_register): Likewise. * remote-mips.c (mips_fetch_registers, mips_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * rs6000-nat.c (fetch_register, store_register): Likewise. (rs6000_fetch_inferior_registers): Likewise. (rs6000_store_inferior_registers): Likewise. * s390-nat.c (fetch_regs, store_regs): Likewise. (fetch_fpregs, store_fpregs): Likewise. (s390_linux_fetch_inferior_registers): Likewise. (s390_linux_store_inferior_registers): Likewise. * shnbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sol-thread.c (sol_thread_fetch_registers): Likewise. (sol_thread_store_registers): Likewise. * sparc-nat.c (fetch_inferior_registers): Likewise. (store_inferior_registers): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. (spu_store_inferior_registers): Likewise. * target.c (debug_print_register): Likewise. (debug_to_fetch_registers, debug_to_store_registers): Likewise. * vaxbsd-nat.c (vaxbsd_fetch_inferior_registers): Likewise. (vaxbsd_store_inferior_registers): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers): Likewise. (win32_fetch_inferior_registers): Likewise. (win32_store_inferior_registers): Likewise.
2007-05-06 22:34:38 +08:00
fetch_register (regcache, tid, tdep->ppc_fpscr_regnum);
if (have_ptrace_getvrregs)
if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1)
[PowerPC] Fix access to VSCR in linux targets The 4-byte VSCR register is found inside a 16-byte field in the regset returned by ptrace and in core files. The position of VSCR depends on the endianess of the target, which was previously assumed to be big-endian for the purpose of getting VSCR. This patch removes this assumption to fix access to VSCR in little-endian mode. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-tdep.h (struct ppc_reg_offsets): Remove vector register offset fields. * ppc-fbsd-tdep.c (ppc32_fbsd_reg_offsets): Remove initializers for vector register offset fields. (ppc64_fbsd_reg_offsets): Likewise. * ppc-nbsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-nat.c (_initialize_ppcobsd_nat): Remove assignment to vector register offset fields. * rs6000-aix-tdep.c (rs6000_aix32_reg_offsets): Remove initializers for vector register offset fields. (rs6000_aix64_reg_offsets): Likewise. * rs6000-tdep.c (ppc_vrreg_offset): Remove. (ppc_supply_vrregset): Remove. (ppc_collect_vrregset): Remove. * ppc-linux-tdep.c (ppc_linux_collect_vrregset): New function. (ppc_linux_vrregset) : New function. (ppc32_le_linux_vrregmap, ppc32_be_linux_vrregmap) (ppc32_le_linux_vrregset, ppc32_be_linux_vrregset): New globals. (ppc32_linux_vrregset): Remove. (ppc_linux_iterate_over_regset_sections): Call ppc_linux_vrregset and use result instead of ppc32_linux_vrregset. (ppc32_linux_reg_offsets): Remove initializers for vector register offset fields. (ppc64_linux_reg_offsets): Likewise. * ppc-linux-tdep.h (ppc_linux_vrregset): New declaration. * ppc-linux-nat.c: Include regset.h. (gdb_vrregset_t): Adjust comment to account for little-endian mode. (supply_vrregset, fill_vrregset): Remove. (fetch_altivec_register, store_altivec_register): Remove. (fetch_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to supply registers. (store_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to collect registers. (fetch_register): Call fetch_altivec_registers instead of fetch_altivec_register. (store_register): Call store_altivec_registers instead of store_altivec_register. (fetch_ppc_registers): Call fetch_altivec_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_altivec_registers with -1 for the new regno parameter. gdb/gdbserver/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * linux-ppc-low.c (ppc_fill_vrregset): Add vscr_offset variable. Set vscr_offset to 0 in little-endian mode and 12 in big-endian mode. Call collect_register_by_name with vscr using vscr_offset. Zero-pad vscr and vrsave fields in collector buffer. (ppc_store_vrregset): Add and set vscr_offset variable as in ppc_fill_vrregset. Call supply_register_by_name with vscr using vscr_offset.
2018-05-22 22:09:05 +08:00
fetch_altivec_registers (regcache, tid, -1);
* rs6000-tdep: Include "features/rs6000/powerpc-vsx32.c". Include "features/rs6000/powerpc-vsx64.c". (ppc_supply_vsxregset): New function. (ppc_collect_vsxregset): New function. (IS_VSX_PSEUDOREG): New macro. (IS_EFP_PSEUDOREG): New macro. (vsx_register_p): New function. (ppc_vsx_support_p): New function. (rs6000_builtin_type_vec128): New function. (rs6000_register_name): Hide upper halves of vs0~vs31. Return correct names for VSX registers and EFPR registers. (rs6000_pseudo_register_type): Return correct types for VSX and EFPR registers. (rs6000_pseudo_register_reggroup_p): Return correct group for VSX and EFPR registers. (ppc_pseudo_register_read): Rename to dfp_pseudo_register_read. (ppc_pseudo_register_write): Rename to dfp_pseudo_register_write. (vsx_pseudo_register_read): New function. (vsx_pseudo_register_write): New function. (efpr_pseudo_register_read): New function. (efpr_pseudo_register_write): New function. (rs6000_pseudo_register_read): Call new VSX and EFPR read functions. (rs6000_pseudo_register_write): Call new VSX and EFPR write functions. (rs6000_gdbarch_init): Declare have_vsx. Initialize new upper half VSX registers. Initialize VSX-related and EFPR-related pseudo-registers variables. Adjust the number of pseudo registers accordingly. * ppc-linux-nat.c: Define PTRACE_GETVSXREGS, PTRACE_SETVSXREGS and SIZEOF_VSRREGS. (gdb_vsxregset_t): New type. (have_ptrace_getsetvsxregs): New variable. (fetch_vsx_register): New function. (fetch_register): Handle VSX registers. (fetch_vsx_registers): New function. (fetch_ppc_registers): Handle VSX registers. (store_ppc_registers): Handle VSX registers. (store_vsx_register): New function. (store_register): Handle VSX registers. (store_vsx_registers): New function. (ppc_linux_read_description): Handle VSX-enabled inferiors. (gdb_vsxregset_t): New type. (supply_vsxregset): New function. (fill_vsxregset): New function. * ppc-tdep.h (vsx_register_p): New prototype. (vsx_support_p): New prototype. (ppc_vsr0_regnum): New variable. (ppc_vsr0_upper_regnum): Likewise. (ppc_efpr0_regnum): Likewise. (ppc_builtin_type_vec128): New type. (ppc_num_vsrs): New constant. (ppc_num_vshrs): New constant. (ppc_num_efprs): Likewise. Define POWERPC_VEC_VSX PPC_VSR0_UPPER_REGNUM and PPC_VSR31_UPPER_REGNUM. (ppc_supply_vsxregset): New prototype. (ppc_collect_vsxregset): New prototype. * ppc-linux-tdep.c: Include "features/rs6000/powerpc-vsx32l.c" Include "features/rs6000/powerpc-vsx64l.c". (_initialize_ppc_linux_tdep): Initialize VSX-enabled targets. (ppc_linux_regset_sections): Add new ".reg-ppc-vsx" field. (ppc32_linux_vsxregset): New 32-bit VSX-enabled regset. (ppc_linux_regset_from_core_section): Handle VSX core section. (ppc_linux_core_read_description): Support VSX-enabled core files. * ppc-linux-tdep.h: Declare *tdesc_powerpc_vsx32l Declare tdesc_powerpc_vsx64l * corelow.c (get_core_register_section): Support VSX-enabled core files. * features/rs6000/power-vsx.xml: New VSX descriptions. * features/rs6000/powerpc-vsx32.xml: New file. * features/rs6000/powerpc-vsx32l.xml: New file. * features/rs6000/powerpc-vsx64.xml: New file. * features/rs6000/powerpc-vsx64l.xml: New file. * features/rs6000/powerpc-vsx32.c: New file (generated). * features/rs6000/powerpc-vsx32l.c: New file (generated). * features/rs6000/powerpc-vsx64.c: New file (generated). * features/rs6000/powerpc-vsx64l.c: New file (generated). * features/Makefile: Updated with new descriptions. * regformats/rs6000/powerpc-vsx32l.dat: New file (generated). * regformats/rs6000/powerpc-vsx64l.dat: New file (generated). * testsuite/gdb.arch/vsx-regs.c: New source file. * testsuite/gdb.arch/vsx-regs.exp: New testcase. * testsuite/lib/gdb.exp (skip_vsx_tests): New function.
2008-08-15 23:18:34 +08:00
if (have_ptrace_getsetvsxregs)
if (tdep->ppc_vsr0_upper_regnum != -1)
[PowerPC] Fix VSX registers in linux core files The functions used by the VSX regset to collect and supply registers from core files where incorrect. This patch changes the regset to use the standard regset collect/supply functions to fix this. The native target is also changed to use the same regset. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-linux-tdep.c (ppc_linux_vsxregset): New function. (ppc32_linux_vsxregmap): New global. (ppc32_linux_vsxregset): Initialize with ppc32_linux_vsxregmap, regcache_supply_regset, and regcache_collect_regset. * ppc-linux-tdep.h (ppc_linux_vsxregset): Declare. * ppc-linux-nat.c (supply_vsxregset, fill_vsxregset): Remove. (fetch_vsx_register, store_vsx_register): Remove. (fetch_vsx_registers): Add regno parameter. Get regset using ppc_linux_vsxregset. Use regset to supply registers. (store_vsx_registers): Add regno parameter. Get regset using ppc_linux_vsxregset. Use regset to collect registers. (fetch_register): Call fetch_vsx_registers instead of fetch_vsx_register. (store_register): Call store_vsx_registers instead of store_vsx_register. (fetch_ppc_registers): Call fetch_vsx_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_vsx_registers with -1 for the new regno parameter. * rs6000-tdep.c (ppc_vsx_support_p, ppc_supply_vsxreget) (ppc_collect_vsxregset): Remove. gdb/testsuite/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * gdb.arch/powerpc-vsx-gcore.exp: New file.
2018-05-22 22:09:05 +08:00
fetch_vsx_registers (regcache, tid, -1);
Change the layout of the PowerPC E500 raw register cache to allow the lower 32-bit halves of the GPRS to be their own raw registers, not pseudoregisters. * ppc-tdep.h (struct gdbarch_tdep): Remove ppc_gprs_pseudo_p flag; add ppc_ev0_upper_regnum flag. * rs6000-tdep.c: #include "reggroups.h". (spe_register_p): Recognize the ev upper half registers as SPE registers. (init_sim_regno_table): Build gdb->sim mappings for the upper-half registers. (e500_move_ev_register): New function. (e500_pseudo_register_read, e500_pseudo_register_write): The 'ev' vector registers are the pseudo-registers now, formed by splicing together the gprs and the upper-half registers. (e500_register_reggroup_p): New function. (P): Macro deleted. (P8, A4): New macro. (PPC_EV_REGS, PPC_GPRS_PSEUDO_REGS): Macros deleted. (PPC_SPE_GP_REGS, PPC_SPE_UPPER_GP_REGS, PPC_EV_PSEUDO_REGS): New macros. (registers_e500): Rearrange register set so that the raw register set contains 32-bit GPRs and upper-half registers, and the SPE vector registers become pseudo-registers. (rs6000_gdbarch_init): Don't initialize tdep->ppc_gprs_pseudo_p; it has been deleted. Initialize ppc_ev0_upper_regnum. Many other register numbers are now the same for the E500 as they are for other PowerPC variants. Register e500_register_reggroup_p as the register group function for the E500. * Makefile.in (rs6000-tdep.o): Update dependencies. Adapt PPC E500 native support to the new raw regcache layout. * ppc-linux-nat.c (struct gdb_evrregset_t): Doc fixes. (read_spliced_spe_reg, write_spliced_spe_reg): Deleted. (fetch_spe_register, store_spe_register): Handle fetching/storing all the SPE registers at once, if regno == -1. These now take over the job of fetch_spe_registers and store_spe_registers. (fetch_spe_registers, store_spe_registers): Deleted. (fetch_ppc_registers, store_ppc_registers): Fetch/store gprs unconditionally; they're always raw. Fetch/store SPE upper half registers, if present, instead of ev registers. (fetch_register, store_register): Remove sanity checks: gprs are never pseudo-registers now, so we never need to even mention any registers that are ever pseudoregisters.
2004-08-05 01:17:55 +08:00
if (tdep->ppc_ev0_upper_regnum >= 0)
* target.h (struct regcache): Add forward declaration. (struct target_ops): Add REGCACHE parameter to to_fetch_registers and to_store_registers target operations. (target_fetch_registers, target_store_registers): Update. * regcache.c (regcache_raw_read): Replace register_cached by regcache_valid_p. Pass regcache to target_fetch_registers. (regcache_raw_write): Pass regcache to target_store_registers. * arm-linux-nat.c (store_fpregister, store_fpregs, store_register, store_regs, store_wmmx_regs): Replace register_cached by regcache_valid_p. * bsd-kvm.c (bsd_kvm_open, bsd_kvm_proc_cmd): Pass current_regcache to target_fetch_registers calls. * corelow.c (core_open): Likewise. * linux-nat.c (linux_nat_corefile_thread_callback): Likewise. * proc-service.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * sol-thread.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * win32-nat.c (win32_resume): Likewise. * ia64-tdep.c (ia64_store_return_value): Pass current_regcache to target_store_registers call. * rs6000-tdep.c (rs6000_push_dummy_call): Likewise. * inferior.h (store_inferior_registers): Update prototype. (fetch_inferior_registers): Likewise. * gnu-nat.c (gnu_store_registers, gnu_fetch_registers): Likewise. * mips-linux-nat.c (super_fetch_registers, super_store_registers): Update function pointer signatures. * aix-thread.c (aix_thread_fetch_registers): Add REGCACHE parameter, use it instead of current_regcache, update calls. (aix_thread_store_registers): Likewise. * alphabsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * amd64bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_fpregister, fetch_fpregs, store_fpregister, store_fpregs, fetch_register, fetch_regs, store_register, store_regs, fetch_wmmx_regs, store_wmmx_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * armnbsd-nat.c (fetch_register, fetch_regs, fetch_fp_register, fetch_fp_regs, armnbsd_fetch_registers): Likewise. (store_register, store_regs, store_fp_register, store_fp_regs, armnbsd_store_registers): Likewise. * bsd-kvm.c (bsd_kvm_fetch_pcb, bsd_kvm_fetch_registers): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * corelow.c (get_core_registers): Likewise. * go32-nat.c (fetch_register, go32_fetch_registers, store_register, go32_store_registers): Likewise. * hppabsd-nat.c (hppabsd_fetch_registers): Likewise. (hppabsd_store_registers): Likewise. * hppa-hpux-nat.c (hppa_hpux_fetch_register): Likewise. (hppa_hpux_fetch_inferior_registers): Likewise. (hppa_hpux_store_register): Likewise. (hppa_hpux_store_inferior_registers): Likewise. * hppa-linux-nat.c (fetch_register, store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * hpux-thread.c (hpux_thread_fetch_registers): Likewise. (hpux_thread_store_registers): Likewise. * i386bsd-nat.c (i386bsd_fetch_inferior_registers): Likewise. (i386bsd_store_inferior_registers): Likewise. * i386gnu-nat.c (fetch_fpregs, gnu_fetch_registers, store_fpregs, gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register, store_register, fetch_regs, store_regs, fetch_fpregs, store_fpregs, fetch_fpxregs, store_fpxregs): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_register): Likewise. (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_register): Likewise. (ia64_linux_store_registers): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. (inf_child_store_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register): Likewise. (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_register): Likewise. (inf_ptrace_store_registers): Likewise. * infptrace.c (fetch_register, store_register): Likewise. (fetch_inferior_registers, store_inferior_registers): Likewise. * m32r-linux-nat.c (fetch_regs, store_regs): Likewise. (m32r_linux_fetch_inferior_registers): Likewise. (m32r_linux_store_inferior_registers): Likewise. * m68kbsd-nat.c (m68kbsd_fetch_inferior_registers): Likewise. (m68kbsd_store_inferior_registers): Likewise. * m68klinux-nat.c (fetch_register, old_fetch_inferior_registers, store_register, old_store_inferior_registers, fetch_regs, store_regs, fetch_fpregs, store_fpregs): Likewise. (m68k_linux_fetch_inferior_registers): Likewise. (m68k_linux_store_inferior_registers): Likewise. * m88kbsd-nat.c (m88kbsd_fetch_inferior_registers): Likewise. (m88kbsd_store_inferior_registers): Likewise. * mips64obsd-nat.c (mips64obsd_fetch_inferior_registers): Likewise. (mips64obsd_store_inferior_registers): Likewise. * mips-linux-nat.c (mips64_linux_regsets_fetch_registers): Likewise. (mips64_linux_regsets_store_registers): Likewise. (mips64_linux_fetch_registers): Likewise. (mips64_linux_store_registers): Likewise. * mipsnbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * monitor.c (monitor_fetch_register, monitor_store_register): Likewise. (monitor_fetch_registers, monitor_store_registers): Likewise. * nto-procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register, fetch_register, supply_vrregset, fetch_altivec_registers, fetch_ppc_registers, ppc_linux_fetch_inferior_registers): Likewise. (store_altivec_register, store_spe_register, store_register, fill_vrregset, store_altivec_registers, store_ppc_registers, ppc_linux_store_inferior_registers): Likewise. * ppcnbsd-nat.c (ppcnbsd_fetch_inferior_registers): Likewise. (ppcnbsd_store_inferior_registers): Likewise. * ppcobsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote.c (fetch_register_using_p, process_g_packet, fetch_registers_using_g, remote_fetch_registers): Likewise. (store_register_using_P, store_registers_using_G, remote_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers, m32r_fetch_register, m32r_store_register, m32r_store_register): Likewise. * remote-mips.c (mips_fetch_registers, mips_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * rs6000-nat.c (fetch_register, store_register): Likewise. (rs6000_fetch_inferior_registers): Likewise. (rs6000_store_inferior_registers): Likewise. * s390-nat.c (fetch_regs, store_regs): Likewise. (fetch_fpregs, store_fpregs): Likewise. (s390_linux_fetch_inferior_registers): Likewise. (s390_linux_store_inferior_registers): Likewise. * shnbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sol-thread.c (sol_thread_fetch_registers): Likewise. (sol_thread_store_registers): Likewise. * sparc-nat.c (fetch_inferior_registers): Likewise. (store_inferior_registers): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. (spu_store_inferior_registers): Likewise. * target.c (debug_print_register): Likewise. (debug_to_fetch_registers, debug_to_store_registers): Likewise. * vaxbsd-nat.c (vaxbsd_fetch_inferior_registers): Likewise. (vaxbsd_store_inferior_registers): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers): Likewise. (win32_fetch_inferior_registers): Likewise. (win32_store_inferior_registers): Likewise.
2007-05-06 22:34:38 +08:00
fetch_spe_register (regcache, tid, -1);
[PowerPC] Add support for PPR and DSCR This patch adds gdb support for the Program Priorty Register and the Data Stream Control Register, for the powerpc linux native and core file targets, and for the powerpc linux server stub. gdb/ChangeLog: 2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * arch/ppc-linux-tdesc.h (tdesc_powerpc_isa205_ppr_dscr_vsx32l) (tdesc_powerpc_isa205_ppr_dscr_vsx64l): Declare. * arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_PPRREGSET) (PPC_LINUX_SIZEOF_DSCRREGSET): Define. (struct ppc_linux_features) <ppr_dscr>: New field. (ppc_linux_no_features): Add initializer for ppr_dscr field. * arch/ppc-linux-common.c (ppc_linux_match_description): Return new tdescs. * nat/ppc-linux.h (PPC_FEATURE2_DSCR, NT_PPC_PPR, NT_PPC_DSCR): Define if not already defined. * features/Makefile (WHICH): Add rs6000/powerpc-isa205-ppr-dscr-vsx32l and rs6000/powerpc-isa205-ppr-dscr-vsx64l. (XMLTOC): Add rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml and rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml. * features/rs6000/power-dscr.xml: New file. * features/rs6000/power-ppr.xml: New file. * features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml: New file. * features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml: New file. * features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.c: Generate. * features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.c: Generate. * regformats/rs6000/powerpc-isa205-ppr-dscr-vsx32l.dat: Generate. * regformats/rs6000/powerpc-isa205-ppr-dscr-vsx64l.dat: Generate. * ppc-linux-nat.c: Include <sys/uio.h>. (fetch_regset, store_regset, check_regset): New functions. (fetch_register, fetch_ppc_registers): Call fetch_regset with DSCR and PPR regsets. (store_register, store_ppc_registers): Call store_regset with DSCR and PPR regsets. (ppc_linux_get_hwcap2): New function. (ppc_linux_nat_target::read_description): Call ppc_linux_get_hwcap2 and check_regset, set ppr_dscr field in the features struct if needed. * ppc-linux-tdep.c: Include features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.c and features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.c. (ppc32_regmap_ppr, ppc32_regmap_dscr, ppc32_linux_pprregset) (ppc32_linux_dscrregset): New globals. (ppc_linux_iterate_over_regset_sections): Call back with the ppr and dscr regsets. (ppc_linux_core_read_description): Check if the ppr and dscr sections are present and set ppr_dscr in the features struct. (_initialize_ppc_linux_tdep): Call initialize_tdesc_powerpc_isa205_ppr_dscr_vsx32l and initialize_tdesc_powerpc_isa205_ppr_dscr_vsx64l. * ppc-linux-tdep.h (ppc32_linux_pprregset) (ppc32_linux_dscrregset): Declare. * ppc-tdep.h (struct gdbarch_tdep) <ppc_ppr_regnum>: New field. <ppc_dscr_regnum>: New field. (enum) <PPC_PPR_REGNUM, PPC_DSCR_REGNUM>: New enum values. * rs6000-tdep.c (rs6000_gdbarch_init): Look for and validate ppr and dscr features. (ppc_process_record_op31): Record changes to PPR and DSCR. gdb/gdbserver/ChangeLog: 2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * configure.srv (ipa_ppc_linux_regobj): Add powerpc-isa205-ppr-dscr-vsx32l-ipa.o and powerpc-isa205-ppr-dscr-vsx64l-ipa.o. (powerpc*-*-linux*): Add powerpc-isa205-ppr-dscr-vsx32l.o and powerpc-isa205-ppr-dscr-vsx64l.o to srv_regobj, add rs6000/power-dscr.xml, rs6000/power-ppr.xml, rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml and rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml to srv_xmlfiles. * linux-ppc-tdesc-init.h (enum ppc_linux_tdesc) <PPC_TDESC_ISA205_PPR_DSCR_VSX>: New enum value. (init_registers_powerpc_isa205_ppr_dscr_vsx32l) (init_registers_powerpc_isa205_ppr_dscr_vsx64l): Declare. * linux-ppc-low.c: Include "elf/common.h" and <sys/uio.h>. (ppc_hwcap): Add comment. (ppc_hwcap2): New global. (ppc_check_regset, ppc_fill_pprregset, ppc_store_pprregset) (ppc_fill_dscrregset, ppc_store_dscrregset): New functions. (ppc_regsets): Add entries for the DSCR and PPR regsets. (ppc_arch_setup): Get AT_HWCAP2. Set ppr_dscr in features struct when needed. Set sizes for the the DSCR and PPR regsets. (ppc_get_ipa_tdesc_idx): Return PPC_TDESC_ISA205_PPR_DSCR_VSX. (initialize_low_arch): Call init_registers_powerpc_isa205_ppr_dscr_vsx32l and init_registers_powerpc_isa205_ppr_dscr_vsx64l. * linux-ppc-ipa.c (get_ipa_tdesc): Handle PPC_TDESC_ISA205_PPR_DSCR_VSX. (initialize_low_tracepoint): Call init_registers_powerpc_isa205_ppr_dscr_vsx32l and init_registers_powerpc_isa205_ppr_dscr_vsx64l. gdb/testsuite/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.arch/powerpc-ppr-dscr.c: New file. * gdb.arch/powerpc-ppr-dscr.exp: New file. gdb/doc/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.texinfo (PowerPC Features): Describe new features "org.gnu.gdb.power.ppr" and "org.gnu.gdb.power.dscr".
2018-10-26 20:37:54 +08:00
if (tdep->ppc_ppr_regnum != -1)
fetch_regset (regcache, tid, NT_PPC_PPR,
PPC_LINUX_SIZEOF_PPRREGSET,
&ppc32_linux_pprregset);
if (tdep->ppc_dscr_regnum != -1)
fetch_regset (regcache, tid, NT_PPC_DSCR,
PPC_LINUX_SIZEOF_DSCRREGSET,
&ppc32_linux_dscrregset);
[PowerPC] Add support for TAR This patch adds support for the Target Address Register for powerpc linux native and core file targets, and in the powerpc linux server stub. gdb/ChangeLog: 2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * arch/ppc-linux-tdesc.h (tdesc_powerpc_isa207_vsx32l) (tdesc_powerpc_isa207_vsx64l): Declare. * arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_TARREGSET): Define. (struct ppc_linux_features) <isa207>: New field. (ppc_linux_no_features): Add initializer for isa207 field. * arch/ppc-linux-common.c (ppc_linux_match_description): Return new tdescs. * nat/ppc-linux.h (PPC_FEATURE2_ARCH_2_07, PPC_FEATURE2_TAR) (NT_PPC_TAR): Define if not already defined. * features/Makefile (WHICH): Add rs6000/powerpc-isa207-vsx32l and rs6000/powerpc-isa207-vsx64l. (XMLTOC): Add rs6000/powerpc-isa207-vsx32l.xml and rs6000/powerpc-isa207-vsx64l.xml. * features/rs6000/power-tar.xml: New file. * features/rs6000/powerpc-isa207-vsx32l.xml: New file. * features/rs6000/powerpc-isa207-vsx64l.xml: New file. * features/rs6000/powerpc-isa207-vsx32l.c: Generate. * features/rs6000/powerpc-isa207-vsx64l.c: Generate. * regformats/rs6000/powerpc-isa207-vsx32l.dat: Generate. * regformats/rs6000/powerpc-isa207-vsx64l.dat: Generate. * ppc-linux-nat.c (fetch_register, fetch_ppc_registers): Call fetch_regset with the TAR regset. (store_register, store_ppc_registers): Call store_regset with the TAR regset. (ppc_linux_nat_target::read_description): Set isa207 field in the features struct if needed. * ppc-linux-tdep.c: Include features/rs6000/powerpc-isa207-vsx32l.c and features/rs6000/powerpc-isa207-vsx64l.c. (ppc32_regmap_tar, ppc32_linux_tarregset): New globals. (ppc_linux_iterate_over_regset_sections): Call back with the tar regset. (ppc_linux_core_read_description): Check if the tar section is present and set isa207 in the features struct. (_initialize_ppc_linux_tdep): Call initialize_tdesc_powerpc_isa207_vsx32l and initialize_tdesc_powerpc_isa207_vsx64l. * ppc-linux-tdep.h (ppc32_linux_tarregset): Declare. * ppc-tdep.h (gdbarch_tdep) <ppc_tar_regnum>: New field. (enum) <PPC_TAR_REGNUM>: New enum value. * rs6000-tdep.c (rs6000_gdbarch_init): Look for and validate tar feature. (ppc_process_record_op31): Record changes to TAR. gdb/gdbserver/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * configure.srv (ipa_ppc_linux_regobj): Add powerpc-isa207-vsx64l-ipa.o and powerpc-isa207-vsx32l-ipa.o. (powerpc*-*-linux*): Add powerpc-isa207-vsx32l.o and powerpc-isa207-vsx64l.o to srv_regobj, add rs6000/power-tar.xml, rs6000/powerpc-isa207-vsx32l.xml, and rs6000/powerpc-isa207-vsx64l.xml to srv_xmlfiles. * linux-ppc-tdesc-init.h (enum ppc_linux_tdesc) <PPC_TDESC_ISA207_VSX>: New enum value. (init_registers_powerpc_isa207_vsx32l): Declare. (init_registers_powerpc_isa207_vsx64l): Declare. * linux-ppc-low.c (ppc_fill_tarregset): New function. (ppc_store_tarregset): New function. (ppc_regsets): Add entry for the TAR regset. (ppc_arch_setup): Set isa207 in features struct when needed. Set size for the TAR regsets. (ppc_get_ipa_tdesc_idx): Return PPC_TDESC_ISA207_VSX. (initialize_low_arch): Call init_registers_powerpc_isa207_vsx32l and init_registers_powerpc_isa207_vsx64l. * linux-ppc-ipa.c (get_ipa_tdesc): Handle PPC_TDESC_ISA207_VSX. (initialize_low_tracepoint): Call init_registers_powerpc_isa207_vsx32l and init_registers_powerpc_isa207_vsx64l. gdb/testsuite/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.arch/powerpc-tar.c: New file. * gdb.arch/powerpc-tar.exp: New file. gdb/doc/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.texinfo (PowerPC Features): Describe new feature "org.gnu.gdb.power.tar".
2018-10-26 20:37:54 +08:00
if (tdep->ppc_tar_regnum != -1)
fetch_regset (regcache, tid, NT_PPC_TAR,
PPC_LINUX_SIZEOF_TARREGSET,
&ppc32_linux_tarregset);
[PowerPC] Add support for EBB and PMU registers This patch adds support for registers of the Event Based Branching and Performance Monitoring Units for the powerpc linux native and core file targets, and for the powerpc linux server stub. All three EBB registers are accessible. Only a subset of the PMU registers can be accessed through ptrace. Because of this, the PMU registers are enumerated individually in gdbarch_tdep, as opposed to having a single "have_pmu" flag. This is intended to make it easier to add additional PMU registers in the future, since checking a "have_pmu" flag elsewhere in the code would no longer be correct. The tdesc feature is named org.gnu.gdb.power.linux.pmu because of this. It's unclear if it makes sense to save and restore these registers across function calls, since some of them can be modified asynchronously. They are also not tracked in record-replay mode. The kernel can return ENODATA when ptrace is used to get the EBB registers, unless a linux performance event that uses EBB is open in the inferior. For this reason, the "fill" functions in the server stub for the ebb register sets is not implemented. Since gdbserver writes all registers in one go before resuming the inferior, this error would not be detected at the time the user tries to write to one of the registers on the client side, and gdbserver would print out warnings every time it resumes the inferior when no ebb performance event is opened, so there is currently no straightforward way to handle this case. This means the ebb registers in the client-side regcache can become dirty when the user tries to write to them, until the inferior is resumed and stopped again. A related issue is that 'G' packets used to write to unrelated registers will include bad data for the EBB registers if they are unavailable, since no register status information is included in the 'G' packet. This data won't be written to the inferior by the gdbserver stub because the "fill" functions are not implemented, and currently the gdbserver stub doesn't change the status of the registers in its own regcache in response to 'G' packets. Another limitation for the ebb registers is that traceframes don't record if registers are available or not, so if these registers are collected when a tracepoint is hit and the inferior has no ebb event opened, the user will see zero values for all of them, instead of the usual <unavailable>. Because these registers are often unavailable, trying to store them with target_store_registers with -1 for the regno argument (all registers) would almost always fail, so they are ignored in this case. gdb/ChangeLog: 2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_EBBREGSET) (PPC_LINUX_SIZEOF_PMUREGSET): Declare. * nat/ppc-linux.h (PPC_FEATURE2_EBB, NT_PPC_EBB, NT_PPC_PMU): Define if not already defined. * features/rs6000/power-ebb.xml: New file. * features/rs6000/power-linux-pmu.xml: New file. * features/rs6000/powerpc-isa207-vsx32l.xml: Include ebb and pmu features. * features/rs6000/powerpc-isa207-vsx64l.xml: Likewise. * features/rs6000/powerpc-isa207-vsx32l.c: Re-generate. * features/rs6000/powerpc-isa207-vsx64l.c: Re-generate. * regformats/rs6000/powerpc-isa207-vsx32l.dat: Re-generate. * regformats/rs6000/powerpc-isa207-vsx64l.dat: Re-generate. * ppc-linux-nat.c (fetch_register, fetch_ppc_registers): Call fetch_regset with ebb and pmu regsets. (store_register, store_ppc_registers): Call store_regset with ebb and pmu regsets. (ppc_linux_nat_target::read_description): Set isa207 field in the features struct if ebb and pmu are avaiable. * ppc-linux-tdep.c (ppc32_regmap_ebb, ppc32_regmap_pmu) (ppc32_linux_ebbregset, ppc32_linux_pmuregset): New globals. (ppc_linux_iterate_over_regset_sections): Call back with the ebb and pmu regsets. (ppc_linux_core_read_description): Check if the pmu section is present and set isa207 in the features struct. * ppc-linux-tdep.h (ppc32_linux_ebbregset) (ppc32_linux_pmuregset): Declare. * ppc-tdep.h (struct gdbarch_tdep) <ppc_mmcr0_regnum>: New field. <ppc_mmcr2_regnum, ppc_siar_regnum, ppc_sdar_regnum>: New fields. <ppc_sier_regnum>: New field. (enum): <PPC_BESCR_REGNUM, PPC_EBBHR_REGNUM, PPC_EBBRR_REGNUM>: New enum values. <PPC_MMCR0_REGNUM, PPC_MMCR2_REGNUM, PPC_SIAR_REGNUM>: New enum values. <PPC_SDAR_REGNUM, PPC_SIER_REGNUM>: New enum values. (PPC_IS_EBB_REGNUM, PPC_IS_PMU_REGNUM): Define. * rs6000-tdep.c (rs6000_gdbarch_init): Look for and validate the ebb and pmu features. gdb/gdbserver/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * configure.srv (powerpc*-*-linux*): Add rs6000/power-ebb.xml and rs6000/power-linux-pmu.xml to srv_xmlfiles. * linux-ppc-low.c (ppc_store_ebbregset, ppc_fill_pmuregset) (ppc_store_pmuregset): New functions. (ppc_regsets): Add entries for ebb and pmu regsets. (ppc_arch_setup): Set isa207 in features struct if the ebb and pmu regsets are available. Set sizes for these regsets. gdb/doc/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.texinfo (PowerPC Features): Describe new features "org.gnu.gdb.power.ebb" and "org.gnu.gdb.power.linux.pmu".
2018-10-26 20:37:54 +08:00
if (tdep->have_ebb)
fetch_regset (regcache, tid, NT_PPC_EBB,
PPC_LINUX_SIZEOF_EBBREGSET,
&ppc32_linux_ebbregset);
if (tdep->ppc_mmcr0_regnum != -1)
fetch_regset (regcache, tid, NT_PPC_PMU,
PPC_LINUX_SIZEOF_PMUREGSET,
&ppc32_linux_pmuregset);
[PowerPC] Add support for HTM registers This patch adds support for Hardware Transactional Memory registers for the powerpc linux native and core file targets, and for the pwoerpc linux server stub. These registers include both the HTM special-purpose registers (TFHAR, TEXASR and TFIAR) as well as the set of registers that are checkpointed (saved) when a transaction is initiated, which the processor restores in the event of a transaction failure. The set of checkpointed general-purpose registers is returned by the linux kernel in the same format as the regular general-purpose registers, defined in struct pt_regs. However, the architecture specifies that only some of the registers present in pt_regs are checkpointed (GPRs 0-31, CR, XER, LR and CTR). The kernel fills the slots for MSR and NIP with other info. The other fields usually don't have meaningful values. GDB doesn't define registers that are not checkpointed in the architecture, but when generating a core file, GDB fills the slot for the checkpointed MSR with the regular MSR. These are usually similar, although some bits might be different, and in some cases the checkpointed MSR will have a value of 0 in a kernel-generated core-file. The checkpointed NIP is filled with TFHAR by GDB in the core-file, which is what the kernel does. The other fields are set to 0 by GDB. Core files generated by the kernel have a note section for checkpointed GPRs with the same size for both 32-bit and 64-bit threads, and the values for the registers of a 32-bit thread are squeezed in the first half, with no useful data in the second half. GDB generates a smaller note section for 32-bit threads, but can read both sizes. The checkpointed XER is required to be 32-bit in the target description documentation, even though the more recent ISAs define it as 64-bit wide, since the high-order 32-bits are reserved, and because in Linux there is no way to get a 64-bit checkpointed XER for 32-bit threads. If this changes in the future, the target description feature requirement can be relaxed to allow for a 64-bit checkpointed XER. Access to the checkpointed CR (condition register) can be confusing. The architecture only specifies that CR fields 1 to 7 (the 24 least significant bits) are checkpointed, but the kernel provides all 8 fields (32 bits). The value of field 0 is not masked by ptrace, so it will sometimes show the result of some kernel operation, probably treclaim., which sets this field. The checkpointed registers are marked not to be saved and restored. Inferior function calls during an active transaction don't work well, and it's unclear what should be done in this case. TEXASR and TFIAR can be altered asynchronously, during transaction failure recording, so they are also not saved and restored. For consistency neither is TFHAR. Record and replay also doesn't work well when transactions are involved. This patch doesn't address this, so the values of the HTM SPRs will sometimes be innacurate when the record/relay target is enabled. For instance, executing a "tbegin." alters TFHAR and TEXASR, but these changes are not currently recorded. Because the checkpointed registers are only available when a transaction is active (or suspended), ptrace can return ENODATA when gdb tries to read these registers and the inferior is not in a transactional state. The registers are set to the unavailable state when this happens. When gbd tries to write to one of these registers, and it is unavailable, an error is raised. The "fill" functions for checkpointed register sets in the server stub are not implemented for the same reason as for the EBB register set, since ptrace can also return ENODATA for checkpointed regsets. The same issues with 'G' packets apply here. Just like for the EBB registers, tracepoints will not mark the checkpointed registers as unavailable if the inferior was not in a transaction, so their content will also show 0 instead of <unavailable> when inspecting trace data. The new tests record the values of the regular registers before stepping the inferior through a "tbegin." instruction to start a transaction, then the checkpointed registers are checked against the recorded pre-transactional values. New values are written to the checkpointed registers and recorded, the inferior continues until the transaction aborts (which is usually immediately when it is resumed), and the regular registers are checked against the recorded values, because the abort should have reverted the registers to these values. Like for the EBB registers, target_store_registers will ignore the checkpointed registers when called with -1 as the regno argument (store all registers in one go). gdb/ChangeLog: 2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * arch/ppc-linux-tdesc.h (tdesc_powerpc_isa207_htm_vsx32l) (tdesc_powerpc_isa207_htm_vsx64l): Declare. * arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_TM_SPRREGSET) (PPC32_LINUX_SIZEOF_CGPRREGSET, PPC64_LINUX_SIZEOF_CGPRREGSET) (PPC_LINUX_SIZEOF_CFPRREGSET, PPC_LINUX_SIZEOF_CVMXREGSET) (PPC_LINUX_SIZEOF_CVSXREGSET, PPC_LINUX_SIZEOF_CPPRREGSET) (PPC_LINUX_SIZEOF_CDSCRREGSET, PPC_LINUX_SIZEOF_CTARREGSET): Define. (struct ppc_linux_features) <htm>: New field. (ppc_linux_no_features): Add initializer for htm field. * arch/ppc-linux-common.c (ppc_linux_match_description): Return new tdescs. * nat/ppc-linux.h (PPC_FEATURE2_HTM, NT_PPC_TM_CGPR) (NT_PPC_TM_CFPR, NT_PPC_TM_CVMX, NT_PPC_TM_CVSX) (NT_PPC_TM_SPR, NT_PPC_TM_CTAR, NT_PPC_TM_CPPR, NT_PPC_TM_CDSCR): Define if not already defined. * features/Makefile (WHICH): Add rs6000/powerpc-isa207-htm-vsx32l and rs6000/powerpc-isa207-htm-vsx64l. (XMLTOC): Add rs6000/powerpc-isa207-htm-vsx32l.xml and rs6000/powerpc-isa207-htm-vsx64l.xml. * features/rs6000/power-htm-spr.xml: New file. * features/rs6000/power-htm-core.xml: New file. * features/rs6000/power64-htm-core.xml: New file. * features/rs6000/power-htm-fpu.xml: New file. * features/rs6000/power-htm-altivec.xml: New file. * features/rs6000/power-htm-vsx.xml: New file. * features/rs6000/power-htm-ppr.xml: New file. * features/rs6000/power-htm-dscr.xml: New file. * features/rs6000/power-htm-tar.xml: New file. * features/rs6000/powerpc-isa207-htm-vsx32l.xml: New file. * features/rs6000/powerpc-isa207-htm-vsx64l.xml: New file. * features/rs6000/powerpc-isa207-htm-vsx32l.c: Generate. * features/rs6000/powerpc-isa207-htm-vsx64l.c: Generate. * regformats/rs6000/powerpc-isa207-htm-vsx32l.dat: Generate. * regformats/rs6000/powerpc-isa207-htm-vsx64l.dat: Generate. * ppc-linux-nat.c (fetch_register, fetch_ppc_registers): Call fetch_regset with HTM regsets. (store_register, store_ppc_registers): Call store_regset with HTM regsets. (ppc_linux_nat_target::read_description): Set htm field in the features struct if needed. * ppc-linux-tdep.c: Include features/rs6000/powerpc-isa207-htm-vsx32l.c and features/rs6000/powerpc-isa207-htm-vsx64l.c. (ppc32_regmap_tm_spr, ppc32_regmap_cgpr, ppc64_le_regmap_cgpr) (ppc64_be_regmap_cgpr, ppc32_regmap_cfpr, ppc32_le_regmap_cvmx) (ppc32_be_regmap_cvmx, ppc32_regmap_cvsx, ppc32_regmap_cppr) (ppc32_regmap_cdscr, ppc32_regmap_ctar): New globals. (ppc32_linux_tm_sprregset, ppc32_linux_cgprregset) (ppc64_be_linux_cgprregset, ppc64_le_linux_cgprregset) (ppc32_linux_cfprregset, ppc32_le_linux_cvmxregset) (ppc32_be_linux_cvmxregset, ppc32_linux_cvsxregset) (ppc32_linux_cpprregset, ppc32_linux_cdscrregset) (ppc32_linux_ctarregset): New globals. (ppc_linux_cgprregset, ppc_linux_cvmxregset): New functions. (ppc_linux_collect_core_cpgrregset): New function. (ppc_linux_iterate_over_regset_sections): Call back with the htm regsets. (ppc_linux_core_read_description): Check if the tm spr section is present and set htm in the features struct. (_initialize_ppc_linux_tdep): Call initialize_tdesc_powerpc_isa207_htm_vsx32l and initialize_tdesc_powerpc_isa207_htm_vsx64l. * ppc-linux-tdep.h (ppc_linux_cgprregset, ppc_linux_cvmxregset): Declare. (ppc32_linux_tm_sprregset, ppc32_linux_cfprregset) (ppc32_linux_cvsxregset, ppc32_linux_cpprregset) (ppc32_linux_cdscrregset, ppc32_linux_ctarregset): Declare. * ppc-tdep.h (struct gdbarch_tdep) <have_htm_spr, have_htm_core>: New fields. <have_htm_fpu, have_htm_altivec, have_htm_vsx>: Likewise. <ppc_cppr_regnum, ppc_cdscr_regnum, ppc_ctar_regnum>: Likewise. <ppc_cdl0_regnum, ppc_cvsr0_regnum, ppc_cefpr0_regnum>: Likewise. (enum) <PPC_TFHAR_REGNUM, PPC_TEXASR_REGNUM, PPC_TFIAR_REGNUM>: New enum fields. <PPC_CR0_REGNUM, PPC_CCR_REGNUM, PPC_CXER_REGNUM>: Likewise. <PPC_CLR_REGNUM, PPC_CCTR_REGNUM, PPC_CF0_REGNUM>: Likewise. <PPC_CFPSCR_REGNUM, PPC_CVR0_REGNUM, PPC_CVSCR_REGNUM>: Likewise. <PPC_CVRSAVE_REGNUM, PPC_CVSR0_UPPER_REGNUM>: Likewise. <PPC_CPPR_REGNUM, PPC_CDSCR_REGNUM>: Likewise. <PPC_CTAR_REGNUM>: Likewise. (PPC_IS_TMSPR_REGNUM, PPC_IS_CKPTGP_REGNUM, PPC_IS_CKPTFP_REGNUM) (PPC_IS_CKPTVMX_REGNUM, PPC_IS_CKPTVSX_REGNUM): Define. * rs6000-tdep.c (IS_CDFP_PSEUDOREG, IS_CVSX_PSEUDOREG) (IS_CEFP_PSEUDOREG): Define. (rs6000_register_name): Hide the upper halves of checkpointed VSX registers. Return names for the checkpointed DFP, VSX, and EFP pseudo registers. (rs6000_pseudo_register_type): Remove initial assert and raise an internal error in the else clause instead. Return types for the checkpointed DFP, VSX, and EFP pseudo registers. (dfp_pseudo_register_read, dfp_pseudo_register_write): Handle checkpointed DFP pseudo registers. (vsx_pseudo_register_read, vsx_pseudo_register_write): Handle checkpointed VSX pseudo registers. (efp_pseudo_register_read, efp_pseudo_register_write): Rename from efpr_pseudo_register_read and efpr_pseudo_register_write. Handle checkpointed EFP pseudo registers. (rs6000_pseudo_register_read, rs6000_pseudo_register_write): Handle checkpointed DFP, VSX, and EFP registers. (dfp_ax_pseudo_register_collect, vsx_ax_pseudo_register_collect) (efp_ax_pseudo_register_collect): New functions. (rs6000_ax_pseudo_register_collect): Move DFP, VSX and EFP pseudo register logic to new functions. Handle checkpointed DFP, VSX, and EFP pseudo registers. (rs6000_gdbarch_init): Look for and validate the htm features. Include checkpointed DFP, VSX and EFP pseudo-registers. * NEWS: Mention access to PPR, DSCR, TAR, EBB/PMU registers and HTM registers. gdb/gdbserver/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * configure.srv (ipa_ppc_linux_regobj): Add powerpc-isa207-htm-vsx32l-ipa.o and powerpc-isa207-htm-vsx64l-ipa.o. (powerpc*-*-linux*): Add powerpc-isa207-htm-vsx32l.o and powerpc-isa207-htm-vsx64l.o to srv_regobj. Add rs6000/power-htm-spr.xml, rs6000/power-htm-core.xml, rs6000/power64-htm-core.xml, rs6000/power-htm-fpu.xml, rs6000/power-htm-altivec.xml, rs6000/power-htm-vsx.xml, rs6000/power-htm-ppr.xml, rs6000/power-htm-dscr.xml, rs6000/power-htm-tar.xml, rs6000/powerpc-isa207-htm-vsx32l.xml, and rs6000/powerpc-isa207-htm-vsx64l.xml to srv_xmlfiles. * linux-ppc-tdesc-init.h (enum ppc_linux_tdesc) <PPC_TDESC_ISA207_HTM_VSX>: New enum value. (init_registers_powerpc_isa207_htm_vsx32l) (init_registers_powerpc_isa207_htm_vsx64l): Declare. * linux-ppc-low.c (ppc_fill_tm_sprregset, ppc_store_tm_sprregset) (ppc_store_tm_cgprregset, ppc_store_tm_cfprregset) (ppc_store_tm_cvrregset, ppc_store_tm_cvsxregset) (ppc_store_tm_cpprregset, ppc_store_tm_cdscrregset) (ppc_store_tm_ctarregset): New functions. (ppc_regsets): Add entries for HTM regsets. (ppc_arch_setup): Set htm in features struct when needed. Set sizes for the HTM regsets. (ppc_get_ipa_tdesc_idx): Return PPC_TDESC_ISA207_HTM_VSX. (initialize_low_arch): Call init_registers_powerpc_isa207_htm_vsx32l and init_registers_powerpc_isa207_htm_vsx64l. * linux-ppc-ipa.c (get_ipa_tdesc): Handle PPC_TDESC_ISA207_HTM_VSX. (initialize_low_tracepoint): Call init_registers_powerpc_isa207_htm_vsx32l and init_registers_powerpc_isa207_htm_vsx64l. gdb/testsuite/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.arch/powerpc-htm-regs.c: New file. * gdb.arch/powerpc-htm-regs.exp: New file. gdb/doc/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.texinfo (PowerPC Features): Describe new features "org.gnu.gdb.power.htm.spr", "org.gnu.gdb.power.htm.core", "org.gnu.gdb.power.htm.fpu", "org.gnu.gdb.power.htm.altivec", "org.gnu.gdb.power.htm.vsx", "org.gnu.gdb.power.htm.ppr", "org.gnu.gdb.power.htm.dscr", "org.gnu.gdb.power.htm.tar".
2018-10-26 20:37:55 +08:00
if (tdep->have_htm_spr)
fetch_regset (regcache, tid, NT_PPC_TM_SPR,
PPC_LINUX_SIZEOF_TM_SPRREGSET,
&ppc32_linux_tm_sprregset);
if (tdep->have_htm_core)
{
const struct regset *cgprregset = ppc_linux_cgprregset (gdbarch);
fetch_regset (regcache, tid, NT_PPC_TM_CGPR,
(tdep->wordsize == 4?
PPC32_LINUX_SIZEOF_CGPRREGSET
: PPC64_LINUX_SIZEOF_CGPRREGSET),
cgprregset);
}
if (tdep->have_htm_fpu)
fetch_regset (regcache, tid, NT_PPC_TM_CFPR,
PPC_LINUX_SIZEOF_CFPRREGSET,
&ppc32_linux_cfprregset);
if (tdep->have_htm_altivec)
{
const struct regset *cvmxregset = ppc_linux_cvmxregset (gdbarch);
fetch_regset (regcache, tid, NT_PPC_TM_CVMX,
PPC_LINUX_SIZEOF_CVMXREGSET,
cvmxregset);
}
if (tdep->have_htm_vsx)
fetch_regset (regcache, tid, NT_PPC_TM_CVSX,
PPC_LINUX_SIZEOF_CVSXREGSET,
&ppc32_linux_cvsxregset);
if (tdep->ppc_cppr_regnum != -1)
fetch_regset (regcache, tid, NT_PPC_TM_CPPR,
PPC_LINUX_SIZEOF_CPPRREGSET,
&ppc32_linux_cpprregset);
if (tdep->ppc_cdscr_regnum != -1)
fetch_regset (regcache, tid, NT_PPC_TM_CDSCR,
PPC_LINUX_SIZEOF_CDSCRREGSET,
&ppc32_linux_cdscrregset);
if (tdep->ppc_ctar_regnum != -1)
fetch_regset (regcache, tid, NT_PPC_TM_CTAR,
PPC_LINUX_SIZEOF_CTARREGSET,
&ppc32_linux_ctarregset);
}
/* Fetch registers from the child process. Fetch all registers if
regno == -1, otherwise fetch all general registers or all floating
point registers depending upon the value of regno. */
Convert struct target_ops to C++ I.e., use C++ virtual methods and inheritance instead of tables of function pointers. Unfortunately, there's no way to do a smooth transition. ALL native targets in the tree must be converted at the same time. I've tested all I could with cross compilers and with help from GCC compile farm, but naturally I haven't been able to test many of the ports. Still, I made a best effort to port everything over, and while I expect some build problems due to typos and such, which should be trivial to fix, I don't expect any design problems. * Implementation notes: - The flattened current_target is gone. References to current_target or current_target.beneath are replaced with references to target_stack (the top of the stack) directly. - To keep "set debug target" working, this adds a new debug_stratum layer that sits on top of the stack, prints the debug, and delegates to the target beneath. In addition, this makes the shortname and longname properties of target_ops be virtual methods instead of data fields, and makes the debug target defer those to the target beneath. This is so that debug code sprinkled around that does "if (debugtarget) ..." can transparently print the name of the target beneath. A patch later in the series actually splits out the shortname/longname methods to a separate structure, but I preferred to keep that chance separate as it is associated with changing a bit the design of how targets are registered and open. - Since you can't check whether a C++ virtual method is overridden, the old method of checking whether a target_ops implements a method by comparing the function pointer must be replaced with something else. Some cases are fixed by adding a parallel "can_do_foo" target_ops methods. E.g.,: + for (t = target_stack; t != NULL; t = t->beneath) { - if (t->to_create_inferior != NULL) + if (t->can_create_inferior ()) break; } Others are fixed by changing void return type to bool or int return type, and have the default implementation return false or -1, to indicate lack of support. - make-target-delegates was adjusted to generate C++ classes and methods. It needed tweaks to grok "virtual" in front of the target method name, and for the fact that methods are no longer function pointers. (In particular, the current code parsing the return type was simple because it could simply parse up until the '(' in '(*to_foo)'. It now generates a couple C++ classes that inherit target_ops: dummy_target and debug_target. Since we need to generate the class declarations as well, i.e., we need to emit methods twice, we now generate the code in two passes. - The core_target global is renamed to avoid conflict with the "core_target" class. - ctf/tfile targets init_tracefile_ops is replaced by a base class that is inherited by both ctf and tfile. - bsd-uthread The bsd_uthread_ops_hack hack is gone. It's not needed because nothing was extending a target created by bsd_uthread_target. - remote/extended-remote targets This is a first pass, just enough to C++ify target_ops. A later pass will convert more free functions to methods, and make remote_state be truly per remote instance, allowing multiple simultaneous instances of remote targets. - inf-child/"native" is converted to an actual base class (inf_child_target), that is inherited by all native targets. - GNU/Linux The old weird double-target linux_ops mechanism in linux-nat.c, is gone, replaced by adding a few virtual methods to linux-nat.h's target_ops, called low_XXX, that the concrete linux-nat implementations override. Sort of like gdbserver's linux_target_ops, but simpler, for requiring only one target_ops-like hierarchy, which spares implementing the same method twice when we need to forward the method to a low implementation. The low target simply reimplements the target_ops method directly in that case. There are a few remaining linux-nat.c hooks that would be better converted to low_ methods like above too. E.g.: linux_nat_set_new_thread (t, x86_linux_new_thread); linux_nat_set_new_fork (t, x86_linux_new_fork); linux_nat_set_forget_process That'll be done in a follow up patch. - We can no longer use functions like x86_use_watchpoints to install custom methods on an arbitrary base target. The patch replaces instances of such a pattern with template mixins. For example memory_breakpoint_target defined in target.h, or x86_nat_target in x86-nat.h. - linux_trad_target, MIPS and Alpha GNU/Linux The code in the new linux-nat-trad.h/c files which was split off of inf-ptrace.h/c recently, is converted to a C++ base class, and used by the MIPS and Alpha GNU/Linux ports. - BSD targets The $architecture x NetBSD/OpenBSD/FreeBSD support matrix complicates things a bit. There's common BSD target code, and there's common architecture-specific code shared between the different BSDs. Currently, all that is stiched together to form a final target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target functions etc. This introduces new fbsd_nat_target, obsd_nat_target and nbsd_nat_target classes that serve as base/prototype target for the corresponding BSD variant. And introduces generic i386/AMD64 BSD targets, to be used as template mixin to build a final target. Similarly, a generic SPARC target is added, used by both BSD and Linux ports. - bsd_kvm_add_target, BSD libkvm target I considered making bsd_kvm_supply_pcb a virtual method, and then have each port inherit bsd_kvm_target and override that method, but that was resulting in lots of unjustified churn, so I left the function pointer mechanism alone. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> John Baldwin <jhb@freebsd.org> * target.h (enum strata) <debug_stratum>: New. (struct target_ops) <all delegation methods>: Replace by C++ virtual methods, and drop "to_" prefix. All references updated throughout. <to_shortname, to_longname, to_doc, to_data, to_have_steppable_watchpoint, to_have_continuable_watchpoint, to_has_thread_control, to_attach_no_wait>: Delete, replaced by virtual methods. All references updated throughout. <can_attach, supports_terminal_ours, can_create_inferior, get_thread_control_capabilities, attach_no_wait>: New virtual methods. <insert_breakpoint, remove_breakpoint>: Now TARGET_DEFAULT_NORETURN methods. <info_proc>: Now returns bool. <to_magic>: Delete. (OPS_MAGIC): Delete. (current_target): Delete. All references replaced by references to ... (target_stack): ... this. New. (target_shortname, target_longname): Adjust. (target_can_run): Now a function declaration. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (memory_breakpoint_target): New template class. (test_target_ops): Refactor as a C++ class with virtual methods. * make-target-delegates (NAME_PART): Tighten. (POINTER_PART, CP_SYMBOL): New. (SIMPLE_RETURN_PART): Reimplement. (VEC_RETURN_PART): Expect less. (RETURN_PART, VIRTUAL_PART): New. (METHOD): Adjust to C++ virtual methods. (scan_target_h): Remove reference to C99. (dname): Output "target_ops::" prefix. (write_function_header): Adjust to output a C++ class method. (write_declaration): New. (write_delegator): Adjust to output a C++ class method. (tdname): Output "dummy_target::" prefix. (write_tdefault, write_debugmethod): Adjust to output a C++ class method. (tdefault_names, debug_names): Delete. (return_types, tdefaults, styles, argtypes_array): New. (top level): All methods are delegators. (print_class): New. (top level): Print dummy_target and debug_target classes. * target-delegates.c: Regenerate. * target-debug.h (target_debug_print_enum_info_proc_what) (target_debug_print_thread_control_capabilities) (target_debug_print_thread_info_p): New. * target.c (dummy_target): Delete. (the_dummy_target, the_debug_target): New. (target_stack): Now extern. (set_targetdebug): Push/unpush debug target. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (add_target_with_completer): No longer call complete_target_initialization. (target_supports_terminal_ours): Use regular delegation. (update_current_target): Delete. (push_target): No longer check magic number. Don't call update_current_target. (unpush_target): Don't call update_current_target. (target_is_pushed): No longer check magic number. (target_require_runnable): Skip for all stratums over process_stratum. (target_ops::info_proc): New. (target_info_proc): Use find_target_at and find_default_run_target. (target_supports_disable_randomization): Use regular delegation. (target_get_osdata): Use find_target_at. (target_ops::open, target_ops::close, target_ops::can_attach) (target_ops::attach, target_ops::can_create_inferior) (target_ops::create_inferior, target_ops::can_run) (target_can_run): New. (default_fileio_target): Use regular delegation. (target_ops::fileio_open, target_ops::fileio_pwrite) (target_ops::fileio_pread, target_ops::fileio_fstat) (target_ops::fileio_close, target_ops::fileio_unlink) (target_ops::fileio_readlink): New. (target_fileio_open_1, target_fileio_unlink) (target_fileio_readlink): Always call the target method. Handle FILEIO_ENOSYS. (return_zero, return_zero_has_execution): Delete. (init_dummy_target): Delete. (dummy_target::dummy_target, dummy_target::shortname) (dummy_target::longname, dummy_target::doc) (debug_target::debug_target, debug_target::shortname) (debug_target::longname, debug_target::doc): New. (target_supports_delete_record): Use regular delegation. (setup_target_debug): Delete. (maintenance_print_target_stack): Skip debug_stratum. (initialize_targets): Instantiate the_dummy_target and the_debug_target. * auxv.c (target_auxv_parse): Remove 'ops' parameter. Adjust to use target_stack. (target_auxv_search, fprint_target_auxv): Adjust. (info_auxv_command): Adjust to use target_stack. * auxv.h (target_auxv_parse): Remove 'ops' parameter. * exceptions.c (print_flush): Handle a NULL target_stack. * regcache.c (target_ops_no_register): Refactor as class with virtual methods. * exec.c (exec_target): New class. (exec_ops): Now an exec_target. (exec_open, exec_close_1, exec_get_section_table) (exec_xfer_partial, exec_files_info, exec_has_memory) (exec_make_note_section): Refactor as exec_target methods. (exec_file_clear, ignore, exec_remove_breakpoint, init_exec_ops): Delete. (exec_target::find_memory_regions): New. (_initialize_exec): Don't call init_exec_ops. * gdbcore.h (exec_file_clear): Delete. * corefile.c (core_target): Delete. (core_file_command): Adjust. * corelow.c (core_target): New class. (the_core_target): New. (core_close): Remove target_ops parameter. (core_close_cleanup): Adjust. (core_target::close): New. (core_open, core_detach, get_core_registers, core_files_info) (core_xfer_partial, core_thread_alive, core_read_description) (core_pid_to_str, core_thread_name, core_has_memory) (core_has_stack, core_has_registers, core_info_proc): Rework as core_target methods. (ignore, core_remove_breakpoint, init_core_ops): Delete. (_initialize_corelow): Initialize the_core_target. * gdbcore.h (core_target): Delete. (the_core_target): New. * ctf.c: (ctf_target): New class. (ctf_ops): Now a ctf_target. (ctf_open, ctf_close, ctf_files_info, ctf_fetch_registers) (ctf_xfer_partial, ctf_get_trace_state_variable_value) (ctf_trace_find, ctf_traceframe_info): Refactor as ctf_target methods. (init_ctf_ops): Delete. (_initialize_ctf): Don't call it. * tracefile-tfile.c (tfile_target): New class. (tfile_ops): Now a tfile_target. (tfile_open, tfile_close, tfile_files_info) (tfile_get_tracepoint_status, tfile_trace_find) (tfile_fetch_registers, tfile_xfer_partial) (tfile_get_trace_state_variable_value, tfile_traceframe_info): Refactor as tfile_target methods. (tfile_xfer_partial_features): Remove target_ops parameter. (init_tfile_ops): Delete. (_initialize_tracefile_tfile): Don't call it. * tracefile.c (tracefile_has_all_memory, tracefile_has_memory) (tracefile_has_stack, tracefile_has_registers) (tracefile_thread_alive, tracefile_get_trace_status): Refactor as tracefile_target methods. (init_tracefile_ops): Delete. (tracefile_target::tracefile_target): New. * tracefile.h: Include "target.h". (tracefile_target): New class. (init_tracefile_ops): Delete. * spu-multiarch.c (spu_multiarch_target): New class. (spu_ops): Now a spu_multiarch_target. (spu_thread_architecture, spu_region_ok_for_hw_watchpoint) (spu_fetch_registers, spu_store_registers, spu_xfer_partial) (spu_search_memory, spu_mourn_inferior): Refactor as spu_multiarch_target methods. (init_spu_ops): Delete. (_initialize_spu_multiarch): Remove references to init_spu_ops, complete_target_initialization. * ravenscar-thread.c (ravenscar_thread_target): New class. (ravenscar_ops): Now a ravenscar_thread_target. (ravenscar_resume, ravenscar_wait, ravenscar_update_thread_list) (ravenscar_thread_alive, ravenscar_pid_to_str) (ravenscar_fetch_registers, ravenscar_store_registers) (ravenscar_prepare_to_store, ravenscar_stopped_by_sw_breakpoint) (ravenscar_stopped_by_hw_breakpoint) (ravenscar_stopped_by_watchpoint, ravenscar_stopped_data_address) (ravenscar_mourn_inferior, ravenscar_core_of_thread) (ravenscar_get_ada_task_ptid): Refactor as ravenscar_thread_target methods. (init_ravenscar_thread_ops): Delete. (_initialize_ravenscar): Remove references to init_ravenscar_thread_ops and complete_target_initialization. * bsd-uthread.c (bsd_uthread_ops_hack): Delete. (bsd_uthread_target): New class. (bsd_uthread_ops): Now a bsd_uthread_target. (bsd_uthread_activate): Adjust to refer to bsd_uthread_ops. (bsd_uthread_close, bsd_uthread_mourn_inferior) (bsd_uthread_fetch_registers, bsd_uthread_store_registers) (bsd_uthread_wait, bsd_uthread_resume, bsd_uthread_thread_alive) (bsd_uthread_update_thread_list, bsd_uthread_extra_thread_info) (bsd_uthread_pid_to_str): Refactor as bsd_uthread_target methods. (bsd_uthread_target): Delete function. (_initialize_bsd_uthread): Remove reference to complete_target_initialization. * bfd-target.c (target_bfd_data): Delete. Fields folded into ... (target_bfd): ... this new class. (target_bfd_xfer_partial, target_bfd_get_section_table) (target_bfd_close): Refactor as target_bfd methods. (target_bfd::~target_bfd): New. (target_bfd_reopen): Adjust. (target_bfd::close): New. * record-btrace.c (record_btrace_target): New class. (record_btrace_ops): Now a record_btrace_target. (record_btrace_open, record_btrace_stop_recording) (record_btrace_disconnect, record_btrace_close) (record_btrace_async, record_btrace_info) (record_btrace_insn_history, record_btrace_insn_history_range) (record_btrace_insn_history_from, record_btrace_call_history) (record_btrace_call_history_range) (record_btrace_call_history_from, record_btrace_record_method) (record_btrace_is_replaying, record_btrace_will_replay) (record_btrace_xfer_partial, record_btrace_insert_breakpoint) (record_btrace_remove_breakpoint, record_btrace_fetch_registers) (record_btrace_store_registers, record_btrace_prepare_to_store) (record_btrace_to_get_unwinder) (record_btrace_to_get_tailcall_unwinder, record_btrace_resume) (record_btrace_commit_resume, record_btrace_wait) (record_btrace_stop, record_btrace_can_execute_reverse) (record_btrace_stopped_by_sw_breakpoint) (record_btrace_supports_stopped_by_sw_breakpoint) (record_btrace_stopped_by_hw_breakpoint) (record_btrace_supports_stopped_by_hw_breakpoint) (record_btrace_update_thread_list, record_btrace_thread_alive) (record_btrace_goto_begin, record_btrace_goto_end) (record_btrace_goto, record_btrace_stop_replaying_all) (record_btrace_execution_direction) (record_btrace_prepare_to_generate_core) (record_btrace_done_generating_core): Refactor as record_btrace_target methods. (init_record_btrace_ops): Delete. (_initialize_record_btrace): Remove reference to init_record_btrace_ops. * record-full.c (RECORD_FULL_IS_REPLAY): Adjust to always refer to the execution_direction global. (record_full_base_target, record_full_target) (record_full_core_target): New classes. (record_full_ops): Now a record_full_target. (record_full_core_ops): Now a record_full_core_target. (record_full_target::detach, record_full_target::disconnect) (record_full_core_target::disconnect) (record_full_target::mourn_inferior, record_full_target::kill): New. (record_full_open, record_full_close, record_full_async): Refactor as methods of the record_full_base_target class. (record_full_resume, record_full_commit_resume): Refactor as methods of the record_full_target class. (record_full_wait, record_full_stopped_by_watchpoint) (record_full_stopped_data_address) (record_full_stopped_by_sw_breakpoint) (record_full_supports_stopped_by_sw_breakpoint) (record_full_stopped_by_hw_breakpoint) (record_full_supports_stopped_by_hw_breakpoint): Refactor as methods of the record_full_base_target class. (record_full_store_registers, record_full_xfer_partial) (record_full_insert_breakpoint, record_full_remove_breakpoint): Refactor as methods of the record_full_target class. (record_full_can_execute_reverse, record_full_get_bookmark) (record_full_goto_bookmark, record_full_execution_direction) (record_full_record_method, record_full_info, record_full_delete) (record_full_is_replaying, record_full_will_replay) (record_full_goto_begin, record_full_goto_end, record_full_goto) (record_full_stop_replaying): Refactor as methods of the record_full_base_target class. (record_full_core_resume, record_full_core_kill) (record_full_core_fetch_registers) (record_full_core_prepare_to_store) (record_full_core_store_registers, record_full_core_xfer_partial) (record_full_core_insert_breakpoint) (record_full_core_remove_breakpoint) (record_full_core_has_execution): Refactor as methods of the record_full_core_target class. (record_full_base_target::supports_delete_record): New. (init_record_full_ops): Delete. (init_record_full_core_ops): Delete. (record_full_save): Refactor as method of the record_full_base_target class. (_initialize_record_full): Remove references to init_record_full_ops and init_record_full_core_ops. * remote.c (remote_target, extended_remote_target): New classes. (remote_ops): Now a remote_target. (extended_remote_ops): Now an extended_remote_target. (remote_insert_fork_catchpoint, remote_remove_fork_catchpoint) (remote_insert_vfork_catchpoint, remote_remove_vfork_catchpoint) (remote_insert_exec_catchpoint, remote_remove_exec_catchpoint) (remote_pass_signals, remote_set_syscall_catchpoint) (remote_program_signals, ) (remote_thread_always_alive): Remove target_ops parameter. (remote_thread_alive, remote_thread_name) (remote_update_thread_list, remote_threads_extra_info) (remote_static_tracepoint_marker_at) (remote_static_tracepoint_markers_by_strid) (remote_get_ada_task_ptid, remote_close, remote_start_remote) (remote_open): Refactor as methods of remote_target. (extended_remote_open, extended_remote_detach) (extended_remote_attach, extended_remote_post_attach): (extended_remote_supports_disable_randomization) (extended_remote_create_inferior): : Refactor as method of extended_remote_target. (remote_set_permissions, remote_open_1, remote_detach) (remote_follow_fork, remote_follow_exec, remote_disconnect) (remote_resume, remote_commit_resume, remote_stop) (remote_interrupt, remote_pass_ctrlc, remote_terminal_inferior) (remote_terminal_ours, remote_wait, remote_fetch_registers) (remote_prepare_to_store, remote_store_registers) (remote_flash_erase, remote_flash_done, remote_files_info) (remote_kill, remote_mourn, remote_insert_breakpoint) (remote_remove_breakpoint, remote_insert_watchpoint) (remote_watchpoint_addr_within_range) (remote_remove_watchpoint, remote_region_ok_for_hw_watchpoint) (remote_check_watch_resources, remote_stopped_by_sw_breakpoint) (remote_supports_stopped_by_sw_breakpoint) (remote_stopped_by_hw_breakpoint) (remote_supports_stopped_by_hw_breakpoint) (remote_stopped_by_watchpoint, remote_stopped_data_address) (remote_insert_hw_breakpoint, remote_remove_hw_breakpoint) (remote_verify_memory): Refactor as methods of remote_target. (remote_write_qxfer, remote_read_qxfer): Remove target_ops parameter. (remote_xfer_partial, remote_get_memory_xfer_limit) (remote_search_memory, remote_rcmd, remote_memory_map) (remote_pid_to_str, remote_get_thread_local_address) (remote_get_tib_address, remote_read_description): Refactor as methods of remote_target. (remote_target::fileio_open, remote_target::fileio_pwrite) (remote_target::fileio_pread, remote_target::fileio_close): New. (remote_hostio_readlink, remote_hostio_fstat) (remote_filesystem_is_local, remote_can_execute_reverse) (remote_supports_non_stop, remote_supports_disable_randomization) (remote_supports_multi_process, remote_supports_cond_breakpoints) (remote_supports_enable_disable_tracepoint) (remote_supports_string_tracing) (remote_can_run_breakpoint_commands, remote_trace_init) (remote_download_tracepoint, remote_can_download_tracepoint) (remote_download_trace_state_variable, remote_enable_tracepoint) (remote_disable_tracepoint, remote_trace_set_readonly_regions) (remote_trace_start, remote_get_trace_status) (remote_get_tracepoint_status, remote_trace_stop) (remote_trace_find, remote_get_trace_state_variable_value) (remote_save_trace_data, remote_get_raw_trace_data) (remote_set_disconnected_tracing, remote_core_of_thread) (remote_set_circular_trace_buffer, remote_traceframe_info) (remote_get_min_fast_tracepoint_insn_len) (remote_set_trace_buffer_size, remote_set_trace_notes) (remote_use_agent, remote_can_use_agent, remote_enable_btrace) (remote_disable_btrace, remote_teardown_btrace) (remote_read_btrace, remote_btrace_conf) (remote_augmented_libraries_svr4_read, remote_load) (remote_pid_to_exec_file, remote_can_do_single_step) (remote_execution_direction, remote_thread_handle_to_thread_info): Refactor as methods of remote_target. (init_remote_ops, init_extended_remote_ops): Delete. (remote_can_async_p, remote_is_async_p, remote_async) (remote_thread_events, remote_upload_tracepoints) (remote_upload_trace_state_variables): Refactor as methods of remote_target. (_initialize_remote): Remove references to init_remote_ops and init_extended_remote_ops. * remote-sim.c (gdbsim_target): New class. (gdbsim_fetch_register, gdbsim_store_register, gdbsim_kill) (gdbsim_load, gdbsim_create_inferior, gdbsim_open, gdbsim_close) (gdbsim_detach, gdbsim_resume, gdbsim_interrupt) (gdbsim_wait, gdbsim_prepare_to_store, gdbsim_xfer_partial) (gdbsim_files_info, gdbsim_mourn_inferior, gdbsim_thread_alive) (gdbsim_pid_to_str, gdbsim_has_all_memory, gdbsim_has_memory): Refactor as methods of gdbsim_target. (gdbsim_ops): Now a gdbsim_target. (init_gdbsim_ops): Delete. (gdbsim_cntrl_c): Adjust. (_initialize_remote_sim): Remove reference to init_gdbsim_ops. * amd64-linux-nat.c (amd64_linux_nat_target): New class. (the_amd64_linux_nat_target): New. (amd64_linux_fetch_inferior_registers) (amd64_linux_store_inferior_registers): Refactor as methods of amd64_linux_nat_target. (_initialize_amd64_linux_nat): Adjust. Set linux_target. * i386-linux-nat.c: Don't include "linux-nat.h". (i386_linux_nat_target): New class. (the_i386_linux_nat_target): New. (i386_linux_fetch_inferior_registers) (i386_linux_store_inferior_registers, i386_linux_resume): Refactor as methods of i386_linux_nat_target. (_initialize_i386_linux_nat): Adjust. Set linux_target. * inf-child.c (inf_child_ops): Delete. (inf_child_fetch_inferior_registers) (inf_child_store_inferior_registers): Delete. (inf_child_post_attach, inf_child_prepare_to_store): Refactor as methods of inf_child_target. (inf_child_target::supports_terminal_ours) (inf_child_target::terminal_init) (inf_child_target::terminal_inferior) (inf_child_target::terminal_ours_for_output) (inf_child_target::terminal_ours, inf_child_target::interrupt) (inf_child_target::pass_ctrlc, inf_child_target::terminal_info): New. (inf_child_open, inf_child_disconnect, inf_child_close) (inf_child_mourn_inferior, inf_child_maybe_unpush_target) (inf_child_post_startup_inferior, inf_child_can_run) (inf_child_pid_to_exec_file): Refactor as methods of inf_child_target. (inf_child_follow_fork): Delete. (inf_child_target::can_create_inferior) (inf_child_target::can_attach): New. (inf_child_target::has_all_memory, inf_child_target::has_memory) (inf_child_target::has_stack, inf_child_target::has_registers) (inf_child_target::has_execution): New. (inf_child_fileio_open, inf_child_fileio_pwrite) (inf_child_fileio_pread, inf_child_fileio_fstat) (inf_child_fileio_close, inf_child_fileio_unlink) (inf_child_fileio_readlink, inf_child_use_agent) (inf_child_can_use_agent): Refactor as methods of inf_child_target. (return_zero, inf_child_target): Delete. (inf_child_target::inf_child_target): New. * inf-child.h: Include "target.h". (inf_child_target): Delete function prototype. (inf_child_target): New class. (inf_child_open_target, inf_child_mourn_inferior) (inf_child_maybe_unpush_target): Delete. * inf-ptrace.c (inf_ptrace_target::~inf_ptrace_target): New. (inf_ptrace_follow_fork, inf_ptrace_insert_fork_catchpoint) (inf_ptrace_remove_fork_catchpoint, inf_ptrace_create_inferior) (inf_ptrace_post_startup_inferior, inf_ptrace_mourn_inferior) (inf_ptrace_attach, inf_ptrace_post_attach, inf_ptrace_detach) (inf_ptrace_detach_success, inf_ptrace_kill, inf_ptrace_resume) (inf_ptrace_wait, inf_ptrace_xfer_partial) (inf_ptrace_thread_alive, inf_ptrace_files_info) (inf_ptrace_pid_to_str, inf_ptrace_auxv_parse): Refactor as methods of inf_ptrace_target. (inf_ptrace_target): Delete function. * inf-ptrace.h: Include "inf-child.h". (inf_ptrace_target): Delete function declaration. (inf_ptrace_target): New class. (inf_ptrace_trad_target, inf_ptrace_detach_success): Delete. * linux-nat.c (linux_target): New. (linux_ops, linux_ops_saved, super_xfer_partial): Delete. (linux_nat_target::~linux_nat_target): New. (linux_child_post_attach, linux_child_post_startup_inferior) (linux_child_follow_fork, linux_child_insert_fork_catchpoint) (linux_child_remove_fork_catchpoint) (linux_child_insert_vfork_catchpoint) (linux_child_remove_vfork_catchpoint) (linux_child_insert_exec_catchpoint) (linux_child_remove_exec_catchpoint) (linux_child_set_syscall_catchpoint, linux_nat_pass_signals) (linux_nat_create_inferior, linux_nat_attach, linux_nat_detach) (linux_nat_resume, linux_nat_stopped_by_watchpoint) (linux_nat_stopped_data_address) (linux_nat_stopped_by_sw_breakpoint) (linux_nat_supports_stopped_by_sw_breakpoint) (linux_nat_stopped_by_hw_breakpoint) (linux_nat_supports_stopped_by_hw_breakpoint, linux_nat_wait) (linux_nat_kill, linux_nat_mourn_inferior) (linux_nat_xfer_partial, linux_nat_thread_alive) (linux_nat_update_thread_list, linux_nat_pid_to_str) (linux_nat_thread_name, linux_child_pid_to_exec_file) (linux_child_static_tracepoint_markers_by_strid) (linux_nat_is_async_p, linux_nat_can_async_p) (linux_nat_supports_non_stop, linux_nat_always_non_stop_p) (linux_nat_supports_multi_process) (linux_nat_supports_disable_randomization, linux_nat_async) (linux_nat_stop, linux_nat_close, linux_nat_thread_address_space) (linux_nat_core_of_thread, linux_nat_filesystem_is_local) (linux_nat_fileio_open, linux_nat_fileio_readlink) (linux_nat_fileio_unlink, linux_nat_thread_events): Refactor as methods of linux_nat_target. (linux_nat_wait_1, linux_xfer_siginfo, linux_proc_xfer_partial) (linux_proc_xfer_spu, linux_nat_xfer_osdata): Remove target_ops parameter. (check_stopped_by_watchpoint): Adjust. (linux_xfer_partial): Delete. (linux_target_install_ops, linux_target, linux_nat_add_target): Delete. (linux_nat_target::linux_nat_target): New. * linux-nat.h: Include "inf-ptrace.h". (linux_nat_target): New. (linux_target, linux_target_install_ops, linux_nat_add_target): Delete function declarations. (linux_target): Declare global. * linux-thread-db.c (thread_db_target): New. (thread_db_target::thread_db_target): New. (thread_db_ops): Delete. (the_thread_db_target): New. (thread_db_detach, thread_db_wait, thread_db_mourn_inferior) (thread_db_update_thread_list, thread_db_pid_to_str) (thread_db_extra_thread_info) (thread_db_thread_handle_to_thread_info) (thread_db_get_thread_local_address, thread_db_get_ada_task_ptid) (thread_db_resume): Refactor as methods of thread_db_target. (init_thread_db_ops): Delete. (_initialize_thread_db): Remove reference to init_thread_db_ops. * x86-linux-nat.c: Don't include "linux-nat.h". (super_post_startup_inferior): Delete. (x86_linux_nat_target::~x86_linux_nat_target): New. (x86_linux_child_post_startup_inferior) (x86_linux_read_description, x86_linux_enable_btrace) (x86_linux_disable_btrace, x86_linux_teardown_btrace) (x86_linux_read_btrace, x86_linux_btrace_conf): Refactor as methods of x86_linux_nat_target. (x86_linux_create_target): Delete. Bits folded ... (x86_linux_add_target): ... here. Now takes a linux_nat_target pointer. * x86-linux-nat.h: Include "linux-nat.h" and "x86-nat.h". (x86_linux_nat_target): New class. (x86_linux_create_target): Delete. (x86_linux_add_target): Now takes a linux_nat_target pointer. * x86-nat.c (x86_insert_watchpoint, x86_remove_watchpoint) (x86_region_ok_for_watchpoint, x86_stopped_data_address) (x86_stopped_by_watchpoint, x86_insert_hw_breakpoint) (x86_remove_hw_breakpoint, x86_can_use_hw_breakpoint) (x86_stopped_by_hw_breakpoint): Remove target_ops parameter and make extern. (x86_use_watchpoints): Delete. * x86-nat.h: Include "breakpoint.h" and "target.h". (x86_use_watchpoints): Delete. (x86_can_use_hw_breakpoint, x86_region_ok_for_hw_watchpoint) (x86_stopped_by_watchpoint, x86_stopped_data_address) (x86_insert_watchpoint, x86_remove_watchpoint) (x86_insert_hw_breakpoint, x86_remove_hw_breakpoint) (x86_stopped_by_hw_breakpoint): New declarations. (x86_nat_target): New template class. * ppc-linux-nat.c (ppc_linux_nat_target): New class. (the_ppc_linux_nat_target): New. (ppc_linux_fetch_inferior_registers) (ppc_linux_can_use_hw_breakpoint) (ppc_linux_region_ok_for_hw_watchpoint) (ppc_linux_ranged_break_num_registers) (ppc_linux_insert_hw_breakpoint, ppc_linux_remove_hw_breakpoint) (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_can_accel_watchpoint_condition) (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint) (ppc_linux_stopped_data_address, ppc_linux_stopped_by_watchpoint) (ppc_linux_watchpoint_addr_within_range) (ppc_linux_masked_watch_num_registers) (ppc_linux_store_inferior_registers, ppc_linux_auxv_parse) (ppc_linux_read_description): Refactor as methods of ppc_linux_nat_target. (_initialize_ppc_linux_nat): Adjust. Set linux_target. * procfs.c (procfs_xfer_partial): Delete forward declaration. (procfs_target): New class. (the_procfs_target): New. (procfs_target): Delete function. (procfs_auxv_parse, procfs_attach, procfs_detach) (procfs_fetch_registers, procfs_store_registers, procfs_wait) (procfs_xfer_partial, procfs_resume, procfs_pass_signals) (procfs_files_info, procfs_kill_inferior, procfs_mourn_inferior) (procfs_create_inferior, procfs_update_thread_list) (procfs_thread_alive, procfs_pid_to_str) (procfs_can_use_hw_breakpoint, procfs_stopped_by_watchpoint) (procfs_stopped_data_address, procfs_insert_watchpoint) (procfs_remove_watchpoint, procfs_region_ok_for_hw_watchpoint) (proc_find_memory_regions, procfs_info_proc) (procfs_make_note_section): Refactor as methods of procfs_target. (_initialize_procfs): Adjust. * sol-thread.c (sol_thread_target): New class. (sol_thread_ops): Now a sol_thread_target. (sol_thread_detach, sol_thread_resume, sol_thread_wait) (sol_thread_fetch_registers, sol_thread_store_registers) (sol_thread_xfer_partial, sol_thread_mourn_inferior) (sol_thread_alive, solaris_pid_to_str, sol_update_thread_list) (sol_get_ada_task_ptid): Refactor as methods of sol_thread_target. (init_sol_thread_ops): Delete. (_initialize_sol_thread): Adjust. Remove references to init_sol_thread_ops and complete_target_initialization. * windows-nat.c (windows_nat_target): New class. (windows_fetch_inferior_registers) (windows_store_inferior_registers, windows_resume, windows_wait) (windows_attach, windows_detach, windows_pid_to_exec_file) (windows_files_info, windows_create_inferior) (windows_mourn_inferior, windows_interrupt, windows_kill_inferior) (windows_close, windows_pid_to_str, windows_xfer_partial) (windows_get_tib_address, windows_get_ada_task_ptid) (windows_thread_name, windows_thread_alive): Refactor as windows_nat_target methods. (do_initial_windows_stuff): Adjust. (windows_target): Delete function. (_initialize_windows_nat): Adjust. * darwin-nat.c (darwin_resume, darwin_wait_to, darwin_interrupt) (darwin_mourn_inferior, darwin_kill_inferior) (darwin_create_inferior, darwin_attach, darwin_detach) (darwin_pid_to_str, darwin_thread_alive, darwin_xfer_partial) (darwin_pid_to_exec_file, darwin_get_ada_task_ptid) (darwin_supports_multi_process): Refactor as darwin_nat_target methods. (darwin_resume_to, darwin_files_info): Delete. (_initialize_darwin_inferior): Rename to ... (_initialize_darwin_nat): ... this. Adjust to C++ification. * darwin-nat.h: Include "inf-child.h". (darwin_nat_target): New class. (darwin_complete_target): Delete. * i386-darwin-nat.c (i386_darwin_nat_target): New class. (darwin_target): New. (i386_darwin_fetch_inferior_registers) (i386_darwin_store_inferior_registers): Refactor as methods of darwin_nat_target. (darwin_complete_target): Delete, with ... (_initialize_i386_darwin_nat): ... bits factored out here. * alpha-linux-nat.c (alpha_linux_nat_target): New class. (the_alpha_linux_nat_target): New. (alpha_linux_register_u_offset): Refactor as alpha_linux_nat_target method. (_initialize_alpha_linux_nat): Adjust. * linux-nat-trad.c (inf_ptrace_register_u_offset): Delete. (inf_ptrace_fetch_register, inf_ptrace_fetch_registers) (inf_ptrace_store_register, inf_ptrace_store_registers): Refact as methods of linux_nat_trad_target. (linux_trad_target): Delete. * linux-nat-trad.h (linux_trad_target): Delete function. (linux_nat_trad_target): New class. * mips-linux-nat.c (mips_linux_nat_target): New class. (super_fetch_registers, super_store_registers, super_close): Delete. (the_mips_linux_nat_target): New. (mips64_linux_regsets_fetch_registers) (mips64_linux_regsets_store_registers) (mips64_linux_fetch_registers, mips64_linux_store_registers) (mips_linux_register_u_offset, mips_linux_read_description) (mips_linux_can_use_hw_breakpoint) (mips_linux_stopped_by_watchpoint) (mips_linux_stopped_data_address) (mips_linux_region_ok_for_hw_watchpoint) (mips_linux_insert_watchpoint, mips_linux_remove_watchpoint) (mips_linux_close): Refactor as methods of mips_linux_nat. (_initialize_mips_linux_nat): Adjust to C++ification. * aix-thread.c (aix_thread_target): New class. (aix_thread_ops): Now an aix_thread_target. (aix_thread_detach, aix_thread_resume, aix_thread_wait) (aix_thread_fetch_registers, aix_thread_store_registers) (aix_thread_xfer_partial, aix_thread_mourn_inferior) (aix_thread_thread_alive, aix_thread_pid_to_str) (aix_thread_extra_thread_info, aix_thread_get_ada_task_ptid): Refactor as methods of aix_thread_target. (init_aix_thread_ops): Delete. (_initialize_aix_thread): Remove references to init_aix_thread_ops and complete_target_initialization. * rs6000-nat.c (rs6000_xfer_shared_libraries): Delete. (rs6000_nat_target): New class. (the_rs6000_nat_target): New. (rs6000_fetch_inferior_registers, rs6000_store_inferior_registers) (rs6000_xfer_partial, rs6000_wait, rs6000_create_inferior) (rs6000_xfer_shared_libraries): Refactor as rs6000_nat_target methods. (super_create_inferior): Delete. (_initialize_rs6000_nat): Adjust to C++ification. * arm-linux-nat.c (arm_linux_nat_target): New class. (the_arm_linux_nat_target): New. (arm_linux_fetch_inferior_registers) (arm_linux_store_inferior_registers, arm_linux_read_description) (arm_linux_can_use_hw_breakpoint, arm_linux_insert_hw_breakpoint) (arm_linux_remove_hw_breakpoint) (arm_linux_region_ok_for_hw_watchpoint) (arm_linux_insert_watchpoint, arm_linux_remove_watchpoint) (arm_linux_stopped_data_address, arm_linux_stopped_by_watchpoint) (arm_linux_watchpoint_addr_within_range): Refactor as methods of arm_linux_nat_target. (_initialize_arm_linux_nat): Adjust to C++ification. * aarch64-linux-nat.c (aarch64_linux_nat_target): New class. (the_aarch64_linux_nat_target): New. (aarch64_linux_fetch_inferior_registers) (aarch64_linux_store_inferior_registers) (aarch64_linux_child_post_startup_inferior) (aarch64_linux_read_description) (aarch64_linux_can_use_hw_breakpoint) (aarch64_linux_insert_hw_breakpoint) (aarch64_linux_remove_hw_breakpoint) (aarch64_linux_insert_watchpoint, aarch64_linux_remove_watchpoint) (aarch64_linux_region_ok_for_hw_watchpoint) (aarch64_linux_stopped_data_address) (aarch64_linux_stopped_by_watchpoint) (aarch64_linux_watchpoint_addr_within_range) (aarch64_linux_can_do_single_step): Refactor as methods of aarch64_linux_nat_target. (super_post_startup_inferior): Delete. (_initialize_aarch64_linux_nat): Adjust to C++ification. * hppa-linux-nat.c (hppa_linux_nat_target): New class. (the_hppa_linux_nat_target): New. (hppa_linux_fetch_inferior_registers) (hppa_linux_store_inferior_registers): Refactor as methods of hppa_linux_nat_target. (_initialize_hppa_linux_nat): Adjust to C++ification. * ia64-linux-nat.c (ia64_linux_nat_target): New class. (the_ia64_linux_nat_target): New. (ia64_linux_insert_watchpoint, ia64_linux_remove_watchpoint) (ia64_linux_stopped_data_address) (ia64_linux_stopped_by_watchpoint, ia64_linux_fetch_registers) (ia64_linux_store_registers, ia64_linux_xfer_partial): Refactor as ia64_linux_nat_target methods. (super_xfer_partial): Delete. (_initialize_ia64_linux_nat): Adjust to C++ification. * m32r-linux-nat.c (m32r_linux_nat_target): New class. (the_m32r_linux_nat_target): New. (m32r_linux_fetch_inferior_registers) (m32r_linux_store_inferior_registers): Refactor as m32r_linux_nat_target methods. (_initialize_m32r_linux_nat): Adjust to C++ification. * m68k-linux-nat.c (m68k_linux_nat_target): New class. (the_m68k_linux_nat_target): New. (m68k_linux_fetch_inferior_registers) (m68k_linux_store_inferior_registers): Refactor as m68k_linux_nat_target methods. (_initialize_m68k_linux_nat): Adjust to C++ification. * s390-linux-nat.c (s390_linux_nat_target): New class. (the_s390_linux_nat_target): New. (s390_linux_fetch_inferior_registers) (s390_linux_store_inferior_registers, s390_stopped_by_watchpoint) (s390_insert_watchpoint, s390_remove_watchpoint) (s390_can_use_hw_breakpoint, s390_insert_hw_breakpoint) (s390_remove_hw_breakpoint, s390_region_ok_for_hw_watchpoint) (s390_auxv_parse, s390_read_description): Refactor as methods of s390_linux_nat_target. (_initialize_s390_nat): Adjust to C++ification. * sparc-linux-nat.c (sparc_linux_nat_target): New class. (the_sparc_linux_nat_target): New. (_initialize_sparc_linux_nat): Adjust to C++ification. * sparc-nat.c (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc64-linux-nat.c (sparc64_linux_nat_target): New class. (the_sparc64_linux_nat_target): New. (_initialize_sparc64_linux_nat): Adjust to C++ification. * spu-linux-nat.c (spu_linux_nat_target): New class. (the_spu_linux_nat_target): New. (spu_child_post_startup_inferior, spu_child_post_attach) (spu_child_wait, spu_fetch_inferior_registers) (spu_store_inferior_registers, spu_xfer_partial) (spu_can_use_hw_breakpoint): Refactor as spu_linux_nat_target methods. (_initialize_spu_nat): Adjust to C++ification. * tilegx-linux-nat.c (tilegx_linux_nat_target): New class. (the_tilegx_linux_nat_target): New. (fetch_inferior_registers, store_inferior_registers): Refactor as methods. (_initialize_tile_linux_nat): Adjust to C++ification. * xtensa-linux-nat.c (xtensa_linux_nat_target): New class. (the_xtensa_linux_nat_target): New. (xtensa_linux_fetch_inferior_registers) (xtensa_linux_store_inferior_registers): Refactor as xtensa_linux_nat_target methods. (_initialize_xtensa_linux_nat): Adjust to C++ification. * fbsd-nat.c (USE_SIGTRAP_SIGINFO): Delete. (fbsd_pid_to_exec_file, fbsd_find_memory_regions) (fbsd_find_memory_regions, fbsd_info_proc, fbsd_xfer_partial) (fbsd_thread_alive, fbsd_pid_to_str, fbsd_thread_name) (fbsd_update_thread_list, fbsd_resume, fbsd_wait) (fbsd_stopped_by_sw_breakpoint) (fbsd_supports_stopped_by_sw_breakpoint, fbsd_follow_fork) (fbsd_insert_fork_catchpoint, fbsd_remove_fork_catchpoint) (fbsd_insert_vfork_catchpoint, fbsd_remove_vfork_catchpoint) (fbsd_post_startup_inferior, fbsd_post_attach) (fbsd_insert_exec_catchpoint, fbsd_remove_exec_catchpoint) (fbsd_set_syscall_catchpoint) (super_xfer_partial, super_resume, super_wait) (fbsd_supports_stopped_by_hw_breakpoint): Delete. (fbsd_handle_debug_trap): Remove target_ops parameter. (fbsd_nat_add_target): Delete. * fbsd-nat.h: Include "inf-ptrace.h". (fbsd_nat_add_target): Delete. (USE_SIGTRAP_SIGINFO): Define. (fbsd_nat_target): New class. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers) (amd64bsd_store_inferior_registers): Remove target_ops parameter. (amd64bsd_target): Delete. * amd64-bsd-nat.h: New file. * amd64-fbsd-nat.c: Include "amd64-bsd-nat.h" instead of "x86-bsd-nat.h". (amd64_fbsd_nat_target): New class. (the_amd64_fbsd_nat_target): New. (amd64fbsd_read_description): Refactor as method of amd64_fbsd_nat_target. (amd64_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_amd64fbsd_nat): Adjust to C++ification. * amd64-nat.h (amd64bsd_target): Delete function declaration. * i386-bsd-nat.c (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Remove target_ops parameter. (i386bsd_target): Delete. * i386-bsd-nat.h (i386bsd_target): Delete function declaration. (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Declare. (i386_bsd_nat_target): New class. * i386-fbsd-nat.c (i386_fbsd_nat_target): New class. (the_i386_fbsd_nat_target): New. (i386fbsd_resume, i386fbsd_read_description): Refactor as i386_fbsd_nat_target methods. (i386_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_i386fbsd_nat): Adjust to C++ification. * x86-bsd-nat.c (super_mourn_inferior): Delete. (x86bsd_mourn_inferior, x86bsd_target): Delete. (_initialize_x86_bsd_nat): Adjust to C++ification. * x86-bsd-nat.h: Include "x86-nat.h". (x86bsd_target): Delete declaration. (x86bsd_nat_target): New class. * aarch64-fbsd-nat.c (aarch64_fbsd_nat_target): New class. (the_aarch64_fbsd_nat_target): New. (aarch64_fbsd_fetch_inferior_registers) (aarch64_fbsd_store_inferior_registers): Refactor as methods of aarch64_fbsd_nat_target. (_initialize_aarch64_fbsd_nat): Adjust to C++ification. * alpha-bsd-nat.c (alpha_bsd_nat_target): New class. (the_alpha_bsd_nat_target): New. (alphabsd_fetch_inferior_registers) (alphabsd_store_inferior_registers): Refactor as alpha_bsd_nat_target methods. (_initialize_alphabsd_nat): Refactor as methods of alpha_bsd_nat_target. * amd64-nbsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_nbsd_nat_target): New. (_initialize_amd64nbsd_nat): Adjust to C++ification. * amd64-obsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_obsd_nat_target): New. (_initialize_amd64obsd_nat): Adjust to C++ification. * arm-fbsd-nat.c (arm_fbsd_nat_target): New. (the_arm_fbsd_nat_target): New. (arm_fbsd_fetch_inferior_registers) (arm_fbsd_store_inferior_registers, arm_fbsd_read_description): (_initialize_arm_fbsd_nat): Refactor as methods of arm_fbsd_nat_target. (_initialize_arm_fbsd_nat): Adjust to C++ification. * arm-nbsd-nat.c (arm_netbsd_nat_target): New class. (the_arm_netbsd_nat_target): New. (armnbsd_fetch_registers, armnbsd_store_registers): Refactor as arm_netbsd_nat_target. (_initialize_arm_netbsd_nat): Adjust to C++ification. * hppa-nbsd-nat.c (hppa_nbsd_nat_target): New class. (the_hppa_nbsd_nat_target): New. (hppanbsd_fetch_registers, hppanbsd_store_registers): Refactor as hppa_nbsd_nat_target methods. (_initialize_hppanbsd_nat): Adjust to C++ification. * hppa-obsd-nat.c (hppa_obsd_nat_target): New class. (the_hppa_obsd_nat_target): New. (hppaobsd_fetch_registers, hppaobsd_store_registers): Refactor as methods of hppa_obsd_nat_target. (_initialize_hppaobsd_nat): Adjust to C++ification. Use add_target. * i386-nbsd-nat.c (the_i386_nbsd_nat_target): New. (_initialize_i386nbsd_nat): Adjust to C++ification. Use add_target. * i386-obsd-nat.c (the_i386_obsd_nat_target): New. (_initialize_i386obsd_nat): Use add_target. * m68k-bsd-nat.c (m68k_bsd_nat_target): New class. (the_m68k_bsd_nat_target): New. (m68kbsd_fetch_inferior_registers) (m68kbsd_store_inferior_registers): Refactor as methods of m68k_bsd_nat_target. (_initialize_m68kbsd_nat): Adjust to C++ification. * mips-fbsd-nat.c (mips_fbsd_nat_target): New class. (the_mips_fbsd_nat_target): New. (mips_fbsd_fetch_inferior_registers) (mips_fbsd_store_inferior_registers): Refactor as methods of mips_fbsd_nat_target. (_initialize_mips_fbsd_nat): Adjust to C++ification. Use add_target. * mips-nbsd-nat.c (mips_nbsd_nat_target): New class. (the_mips_nbsd_nat_target): New. (mipsnbsd_fetch_inferior_registers) (mipsnbsd_store_inferior_registers): Refactor as methods of mips_nbsd_nat_target. (_initialize_mipsnbsd_nat): Adjust to C++ification. * mips64-obsd-nat.c (mips64_obsd_nat_target): New class. (the_mips64_obsd_nat_target): New. (mips64obsd_fetch_inferior_registers) (mips64obsd_store_inferior_registers): Refactor as methods of mips64_obsd_nat_target. (_initialize_mips64obsd_nat): Adjust to C++ification. Use add_target. * nbsd-nat.c (nbsd_pid_to_exec_file): Refactor as method of nbsd_nat_target. * nbsd-nat.h: Include "inf-ptrace.h". (nbsd_nat_target): New class. * obsd-nat.c (obsd_pid_to_str, obsd_update_thread_list) (obsd_wait): Refactor as methods of obsd_nat_target. (obsd_add_target): Delete. * obsd-nat.h: Include "inf-ptrace.h". (obsd_nat_target): New class. * ppc-fbsd-nat.c (ppc_fbsd_nat_target): New class. (the_ppc_fbsd_nat_target): New. (ppcfbsd_fetch_inferior_registers) (ppcfbsd_store_inferior_registers): Refactor as methods of ppc_fbsd_nat_target. (_initialize_ppcfbsd_nat): Adjust to C++ification. Use add_target. * ppc-nbsd-nat.c (ppc_nbsd_nat_target): New class. (the_ppc_nbsd_nat_target): New. (ppcnbsd_fetch_inferior_registers) (ppcnbsd_store_inferior_registers): Refactor as methods of ppc_nbsd_nat_target. (_initialize_ppcnbsd_nat): Adjust to C++ification. * ppc-obsd-nat.c (ppc_obsd_nat_target): New class. (the_ppc_obsd_nat_target): New. (ppcobsd_fetch_registers, ppcobsd_store_registers): Refactor as methods of ppc_obsd_nat_target. (_initialize_ppcobsd_nat): Adjust to C++ification. Use add_target. * sh-nbsd-nat.c (sh_nbsd_nat_target): New class. (the_sh_nbsd_nat_target): New. (shnbsd_fetch_inferior_registers) (shnbsd_store_inferior_registers): Refactor as methods of sh_nbsd_nat_target. (_initialize_shnbsd_nat): Adjust to C++ification. * sparc-nat.c (sparc_xfer_wcookie): Make extern. (inf_ptrace_xfer_partial): Delete. (sparc_xfer_partial, sparc_target): Delete. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers, sparc_xfer_wcookie): Declare. (sparc_target): Delete function declaration. (sparc_target): New template class. * sparc-nbsd-nat.c (the_sparc_nbsd_nat_target): New. (_initialize_sparcnbsd_nat): Adjust to C++ification. * sparc64-fbsd-nat.c (the_sparc64_fbsd_nat_target): New. (_initialize_sparc64fbsd_nat): Adjust to C++ification. Use add_target. * sparc64-nbsd-nat.c (the_sparc64_nbsd_nat_target): New. (_initialize_sparc64nbsd_nat): Adjust to C++ification. * sparc64-obsd-nat.c (the_sparc64_obsd_nat_target): New. (_initialize_sparc64obsd_nat): Adjust to C++ification. Use add_target. * vax-bsd-nat.c (vax_bsd_nat_target): New class. (the_vax_bsd_nat_target): New. (vaxbsd_fetch_inferior_registers) (vaxbsd_store_inferior_registers): Refactor as vax_bsd_nat_target methods. (_initialize_vaxbsd_nat): Adjust to C++ification. * bsd-kvm.c (bsd_kvm_target): New class. (bsd_kvm_ops): Now a bsd_kvm_target. (bsd_kvm_open, bsd_kvm_close, bsd_kvm_xfer_partial) (bsd_kvm_files_info, bsd_kvm_fetch_registers) (bsd_kvm_thread_alive, bsd_kvm_pid_to_str): Refactor as methods of bsd_kvm_target. (bsd_kvm_return_one): Delete. (bsd_kvm_add_target): Adjust to C++ification. * nto-procfs.c (nto_procfs_target, nto_procfs_target_native) (nto_procfs_target_procfs): New classes. (procfs_open_1, procfs_thread_alive, procfs_update_thread_list) (procfs_files_info, procfs_pid_to_exec_file, procfs_attach) (procfs_post_attach, procfs_wait, procfs_fetch_registers) (procfs_xfer_partial, procfs_detach, procfs_insert_breakpoint) (procfs_remove_breakpoint, procfs_insert_hw_breakpoint) (procfs_remove_hw_breakpoint, procfs_resume) (procfs_mourn_inferior, procfs_create_inferior, procfs_interrupt) (procfs_kill_inferior, procfs_store_registers) (procfs_pass_signals, procfs_pid_to_str, procfs_can_run): Refactor as methods of nto_procfs_target. (nto_procfs_ops): Now an nto_procfs_target_procfs. (nto_native_ops): Delete. (procfs_open, procfs_native_open): Delete. (nto_native_ops): Now an nto_procfs_target_native. (init_procfs_targets): Adjust to C++ification. (procfs_can_use_hw_breakpoint, procfs_remove_hw_watchpoint) (procfs_insert_hw_watchpoint, procfs_stopped_by_watchpoint): Refactor as methods of nto_procfs_target. * go32-nat.c (go32_nat_target): New class. (the_go32_nat_target): New. (go32_attach, go32_resume, go32_wait, go32_fetch_registers) (go32_store_registers, go32_xfer_partial, go32_files_info) (go32_kill_inferior, go32_create_inferior, go32_mourn_inferior) (go32_terminal_init, go32_terminal_info, go32_terminal_inferior) (go32_terminal_ours, go32_pass_ctrlc, go32_thread_alive) (go32_pid_to_str): Refactor as methods of go32_nat_target. (go32_target): Delete. (_initialize_go32_nat): Adjust to C++ification. * gnu-nat.c (gnu_wait, gnu_resume, gnu_kill_inferior) (gnu_mourn_inferior, gnu_create_inferior, gnu_attach, gnu_detach) (gnu_stop, gnu_thread_alive, gnu_xfer_partial) (gnu_find_memory_regions, gnu_pid_to_str): Refactor as methods of gnu_nat_target. (gnu_target): Delete. * gnu-nat.h (gnu_target): Delete. (gnu_nat_target): New class. * i386-gnu-nat.c (gnu_base_target): New. (i386_gnu_nat_target): New class. (the_i386_gnu_nat_target): New. (_initialize_i386gnu_nat): Adjust to C++ification. gdb/testsuite/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * gdb.base/breakpoint-in-ro-region.exp: Adjust to to_resume and to_log_command renames. * gdb.base/sss-bp-on-user-bp-2.exp: Likewise.
2018-05-03 07:37:22 +08:00
void
ppc_linux_nat_target::fetch_registers (struct regcache *regcache, int regno)
{
pid_t tid = get_ptrace_pid (regcache->ptid ());
if (regno == -1)
* target.h (struct regcache): Add forward declaration. (struct target_ops): Add REGCACHE parameter to to_fetch_registers and to_store_registers target operations. (target_fetch_registers, target_store_registers): Update. * regcache.c (regcache_raw_read): Replace register_cached by regcache_valid_p. Pass regcache to target_fetch_registers. (regcache_raw_write): Pass regcache to target_store_registers. * arm-linux-nat.c (store_fpregister, store_fpregs, store_register, store_regs, store_wmmx_regs): Replace register_cached by regcache_valid_p. * bsd-kvm.c (bsd_kvm_open, bsd_kvm_proc_cmd): Pass current_regcache to target_fetch_registers calls. * corelow.c (core_open): Likewise. * linux-nat.c (linux_nat_corefile_thread_callback): Likewise. * proc-service.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * sol-thread.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * win32-nat.c (win32_resume): Likewise. * ia64-tdep.c (ia64_store_return_value): Pass current_regcache to target_store_registers call. * rs6000-tdep.c (rs6000_push_dummy_call): Likewise. * inferior.h (store_inferior_registers): Update prototype. (fetch_inferior_registers): Likewise. * gnu-nat.c (gnu_store_registers, gnu_fetch_registers): Likewise. * mips-linux-nat.c (super_fetch_registers, super_store_registers): Update function pointer signatures. * aix-thread.c (aix_thread_fetch_registers): Add REGCACHE parameter, use it instead of current_regcache, update calls. (aix_thread_store_registers): Likewise. * alphabsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * amd64bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_fpregister, fetch_fpregs, store_fpregister, store_fpregs, fetch_register, fetch_regs, store_register, store_regs, fetch_wmmx_regs, store_wmmx_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * armnbsd-nat.c (fetch_register, fetch_regs, fetch_fp_register, fetch_fp_regs, armnbsd_fetch_registers): Likewise. (store_register, store_regs, store_fp_register, store_fp_regs, armnbsd_store_registers): Likewise. * bsd-kvm.c (bsd_kvm_fetch_pcb, bsd_kvm_fetch_registers): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * corelow.c (get_core_registers): Likewise. * go32-nat.c (fetch_register, go32_fetch_registers, store_register, go32_store_registers): Likewise. * hppabsd-nat.c (hppabsd_fetch_registers): Likewise. (hppabsd_store_registers): Likewise. * hppa-hpux-nat.c (hppa_hpux_fetch_register): Likewise. (hppa_hpux_fetch_inferior_registers): Likewise. (hppa_hpux_store_register): Likewise. (hppa_hpux_store_inferior_registers): Likewise. * hppa-linux-nat.c (fetch_register, store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * hpux-thread.c (hpux_thread_fetch_registers): Likewise. (hpux_thread_store_registers): Likewise. * i386bsd-nat.c (i386bsd_fetch_inferior_registers): Likewise. (i386bsd_store_inferior_registers): Likewise. * i386gnu-nat.c (fetch_fpregs, gnu_fetch_registers, store_fpregs, gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register, store_register, fetch_regs, store_regs, fetch_fpregs, store_fpregs, fetch_fpxregs, store_fpxregs): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_register): Likewise. (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_register): Likewise. (ia64_linux_store_registers): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. (inf_child_store_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register): Likewise. (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_register): Likewise. (inf_ptrace_store_registers): Likewise. * infptrace.c (fetch_register, store_register): Likewise. (fetch_inferior_registers, store_inferior_registers): Likewise. * m32r-linux-nat.c (fetch_regs, store_regs): Likewise. (m32r_linux_fetch_inferior_registers): Likewise. (m32r_linux_store_inferior_registers): Likewise. * m68kbsd-nat.c (m68kbsd_fetch_inferior_registers): Likewise. (m68kbsd_store_inferior_registers): Likewise. * m68klinux-nat.c (fetch_register, old_fetch_inferior_registers, store_register, old_store_inferior_registers, fetch_regs, store_regs, fetch_fpregs, store_fpregs): Likewise. (m68k_linux_fetch_inferior_registers): Likewise. (m68k_linux_store_inferior_registers): Likewise. * m88kbsd-nat.c (m88kbsd_fetch_inferior_registers): Likewise. (m88kbsd_store_inferior_registers): Likewise. * mips64obsd-nat.c (mips64obsd_fetch_inferior_registers): Likewise. (mips64obsd_store_inferior_registers): Likewise. * mips-linux-nat.c (mips64_linux_regsets_fetch_registers): Likewise. (mips64_linux_regsets_store_registers): Likewise. (mips64_linux_fetch_registers): Likewise. (mips64_linux_store_registers): Likewise. * mipsnbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * monitor.c (monitor_fetch_register, monitor_store_register): Likewise. (monitor_fetch_registers, monitor_store_registers): Likewise. * nto-procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register, fetch_register, supply_vrregset, fetch_altivec_registers, fetch_ppc_registers, ppc_linux_fetch_inferior_registers): Likewise. (store_altivec_register, store_spe_register, store_register, fill_vrregset, store_altivec_registers, store_ppc_registers, ppc_linux_store_inferior_registers): Likewise. * ppcnbsd-nat.c (ppcnbsd_fetch_inferior_registers): Likewise. (ppcnbsd_store_inferior_registers): Likewise. * ppcobsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote.c (fetch_register_using_p, process_g_packet, fetch_registers_using_g, remote_fetch_registers): Likewise. (store_register_using_P, store_registers_using_G, remote_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers, m32r_fetch_register, m32r_store_register, m32r_store_register): Likewise. * remote-mips.c (mips_fetch_registers, mips_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * rs6000-nat.c (fetch_register, store_register): Likewise. (rs6000_fetch_inferior_registers): Likewise. (rs6000_store_inferior_registers): Likewise. * s390-nat.c (fetch_regs, store_regs): Likewise. (fetch_fpregs, store_fpregs): Likewise. (s390_linux_fetch_inferior_registers): Likewise. (s390_linux_store_inferior_registers): Likewise. * shnbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sol-thread.c (sol_thread_fetch_registers): Likewise. (sol_thread_store_registers): Likewise. * sparc-nat.c (fetch_inferior_registers): Likewise. (store_inferior_registers): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. (spu_store_inferior_registers): Likewise. * target.c (debug_print_register): Likewise. (debug_to_fetch_registers, debug_to_store_registers): Likewise. * vaxbsd-nat.c (vaxbsd_fetch_inferior_registers): Likewise. (vaxbsd_store_inferior_registers): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers): Likewise. (win32_fetch_inferior_registers): Likewise. (win32_store_inferior_registers): Likewise.
2007-05-06 22:34:38 +08:00
fetch_ppc_registers (regcache, tid);
else
* target.h (struct regcache): Add forward declaration. (struct target_ops): Add REGCACHE parameter to to_fetch_registers and to_store_registers target operations. (target_fetch_registers, target_store_registers): Update. * regcache.c (regcache_raw_read): Replace register_cached by regcache_valid_p. Pass regcache to target_fetch_registers. (regcache_raw_write): Pass regcache to target_store_registers. * arm-linux-nat.c (store_fpregister, store_fpregs, store_register, store_regs, store_wmmx_regs): Replace register_cached by regcache_valid_p. * bsd-kvm.c (bsd_kvm_open, bsd_kvm_proc_cmd): Pass current_regcache to target_fetch_registers calls. * corelow.c (core_open): Likewise. * linux-nat.c (linux_nat_corefile_thread_callback): Likewise. * proc-service.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * sol-thread.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * win32-nat.c (win32_resume): Likewise. * ia64-tdep.c (ia64_store_return_value): Pass current_regcache to target_store_registers call. * rs6000-tdep.c (rs6000_push_dummy_call): Likewise. * inferior.h (store_inferior_registers): Update prototype. (fetch_inferior_registers): Likewise. * gnu-nat.c (gnu_store_registers, gnu_fetch_registers): Likewise. * mips-linux-nat.c (super_fetch_registers, super_store_registers): Update function pointer signatures. * aix-thread.c (aix_thread_fetch_registers): Add REGCACHE parameter, use it instead of current_regcache, update calls. (aix_thread_store_registers): Likewise. * alphabsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * amd64bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_fpregister, fetch_fpregs, store_fpregister, store_fpregs, fetch_register, fetch_regs, store_register, store_regs, fetch_wmmx_regs, store_wmmx_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * armnbsd-nat.c (fetch_register, fetch_regs, fetch_fp_register, fetch_fp_regs, armnbsd_fetch_registers): Likewise. (store_register, store_regs, store_fp_register, store_fp_regs, armnbsd_store_registers): Likewise. * bsd-kvm.c (bsd_kvm_fetch_pcb, bsd_kvm_fetch_registers): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * corelow.c (get_core_registers): Likewise. * go32-nat.c (fetch_register, go32_fetch_registers, store_register, go32_store_registers): Likewise. * hppabsd-nat.c (hppabsd_fetch_registers): Likewise. (hppabsd_store_registers): Likewise. * hppa-hpux-nat.c (hppa_hpux_fetch_register): Likewise. (hppa_hpux_fetch_inferior_registers): Likewise. (hppa_hpux_store_register): Likewise. (hppa_hpux_store_inferior_registers): Likewise. * hppa-linux-nat.c (fetch_register, store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * hpux-thread.c (hpux_thread_fetch_registers): Likewise. (hpux_thread_store_registers): Likewise. * i386bsd-nat.c (i386bsd_fetch_inferior_registers): Likewise. (i386bsd_store_inferior_registers): Likewise. * i386gnu-nat.c (fetch_fpregs, gnu_fetch_registers, store_fpregs, gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register, store_register, fetch_regs, store_regs, fetch_fpregs, store_fpregs, fetch_fpxregs, store_fpxregs): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_register): Likewise. (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_register): Likewise. (ia64_linux_store_registers): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. (inf_child_store_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register): Likewise. (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_register): Likewise. (inf_ptrace_store_registers): Likewise. * infptrace.c (fetch_register, store_register): Likewise. (fetch_inferior_registers, store_inferior_registers): Likewise. * m32r-linux-nat.c (fetch_regs, store_regs): Likewise. (m32r_linux_fetch_inferior_registers): Likewise. (m32r_linux_store_inferior_registers): Likewise. * m68kbsd-nat.c (m68kbsd_fetch_inferior_registers): Likewise. (m68kbsd_store_inferior_registers): Likewise. * m68klinux-nat.c (fetch_register, old_fetch_inferior_registers, store_register, old_store_inferior_registers, fetch_regs, store_regs, fetch_fpregs, store_fpregs): Likewise. (m68k_linux_fetch_inferior_registers): Likewise. (m68k_linux_store_inferior_registers): Likewise. * m88kbsd-nat.c (m88kbsd_fetch_inferior_registers): Likewise. (m88kbsd_store_inferior_registers): Likewise. * mips64obsd-nat.c (mips64obsd_fetch_inferior_registers): Likewise. (mips64obsd_store_inferior_registers): Likewise. * mips-linux-nat.c (mips64_linux_regsets_fetch_registers): Likewise. (mips64_linux_regsets_store_registers): Likewise. (mips64_linux_fetch_registers): Likewise. (mips64_linux_store_registers): Likewise. * mipsnbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * monitor.c (monitor_fetch_register, monitor_store_register): Likewise. (monitor_fetch_registers, monitor_store_registers): Likewise. * nto-procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register, fetch_register, supply_vrregset, fetch_altivec_registers, fetch_ppc_registers, ppc_linux_fetch_inferior_registers): Likewise. (store_altivec_register, store_spe_register, store_register, fill_vrregset, store_altivec_registers, store_ppc_registers, ppc_linux_store_inferior_registers): Likewise. * ppcnbsd-nat.c (ppcnbsd_fetch_inferior_registers): Likewise. (ppcnbsd_store_inferior_registers): Likewise. * ppcobsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote.c (fetch_register_using_p, process_g_packet, fetch_registers_using_g, remote_fetch_registers): Likewise. (store_register_using_P, store_registers_using_G, remote_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers, m32r_fetch_register, m32r_store_register, m32r_store_register): Likewise. * remote-mips.c (mips_fetch_registers, mips_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * rs6000-nat.c (fetch_register, store_register): Likewise. (rs6000_fetch_inferior_registers): Likewise. (rs6000_store_inferior_registers): Likewise. * s390-nat.c (fetch_regs, store_regs): Likewise. (fetch_fpregs, store_fpregs): Likewise. (s390_linux_fetch_inferior_registers): Likewise. (s390_linux_store_inferior_registers): Likewise. * shnbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sol-thread.c (sol_thread_fetch_registers): Likewise. (sol_thread_store_registers): Likewise. * sparc-nat.c (fetch_inferior_registers): Likewise. (store_inferior_registers): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. (spu_store_inferior_registers): Likewise. * target.c (debug_print_register): Likewise. (debug_to_fetch_registers, debug_to_store_registers): Likewise. * vaxbsd-nat.c (vaxbsd_fetch_inferior_registers): Likewise. (vaxbsd_store_inferior_registers): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers): Likewise. (win32_fetch_inferior_registers): Likewise. (win32_store_inferior_registers): Likewise.
2007-05-06 22:34:38 +08:00
fetch_register (regcache, tid, regno);
}
* rs6000-tdep: Include "features/rs6000/powerpc-vsx32.c". Include "features/rs6000/powerpc-vsx64.c". (ppc_supply_vsxregset): New function. (ppc_collect_vsxregset): New function. (IS_VSX_PSEUDOREG): New macro. (IS_EFP_PSEUDOREG): New macro. (vsx_register_p): New function. (ppc_vsx_support_p): New function. (rs6000_builtin_type_vec128): New function. (rs6000_register_name): Hide upper halves of vs0~vs31. Return correct names for VSX registers and EFPR registers. (rs6000_pseudo_register_type): Return correct types for VSX and EFPR registers. (rs6000_pseudo_register_reggroup_p): Return correct group for VSX and EFPR registers. (ppc_pseudo_register_read): Rename to dfp_pseudo_register_read. (ppc_pseudo_register_write): Rename to dfp_pseudo_register_write. (vsx_pseudo_register_read): New function. (vsx_pseudo_register_write): New function. (efpr_pseudo_register_read): New function. (efpr_pseudo_register_write): New function. (rs6000_pseudo_register_read): Call new VSX and EFPR read functions. (rs6000_pseudo_register_write): Call new VSX and EFPR write functions. (rs6000_gdbarch_init): Declare have_vsx. Initialize new upper half VSX registers. Initialize VSX-related and EFPR-related pseudo-registers variables. Adjust the number of pseudo registers accordingly. * ppc-linux-nat.c: Define PTRACE_GETVSXREGS, PTRACE_SETVSXREGS and SIZEOF_VSRREGS. (gdb_vsxregset_t): New type. (have_ptrace_getsetvsxregs): New variable. (fetch_vsx_register): New function. (fetch_register): Handle VSX registers. (fetch_vsx_registers): New function. (fetch_ppc_registers): Handle VSX registers. (store_ppc_registers): Handle VSX registers. (store_vsx_register): New function. (store_register): Handle VSX registers. (store_vsx_registers): New function. (ppc_linux_read_description): Handle VSX-enabled inferiors. (gdb_vsxregset_t): New type. (supply_vsxregset): New function. (fill_vsxregset): New function. * ppc-tdep.h (vsx_register_p): New prototype. (vsx_support_p): New prototype. (ppc_vsr0_regnum): New variable. (ppc_vsr0_upper_regnum): Likewise. (ppc_efpr0_regnum): Likewise. (ppc_builtin_type_vec128): New type. (ppc_num_vsrs): New constant. (ppc_num_vshrs): New constant. (ppc_num_efprs): Likewise. Define POWERPC_VEC_VSX PPC_VSR0_UPPER_REGNUM and PPC_VSR31_UPPER_REGNUM. (ppc_supply_vsxregset): New prototype. (ppc_collect_vsxregset): New prototype. * ppc-linux-tdep.c: Include "features/rs6000/powerpc-vsx32l.c" Include "features/rs6000/powerpc-vsx64l.c". (_initialize_ppc_linux_tdep): Initialize VSX-enabled targets. (ppc_linux_regset_sections): Add new ".reg-ppc-vsx" field. (ppc32_linux_vsxregset): New 32-bit VSX-enabled regset. (ppc_linux_regset_from_core_section): Handle VSX core section. (ppc_linux_core_read_description): Support VSX-enabled core files. * ppc-linux-tdep.h: Declare *tdesc_powerpc_vsx32l Declare tdesc_powerpc_vsx64l * corelow.c (get_core_register_section): Support VSX-enabled core files. * features/rs6000/power-vsx.xml: New VSX descriptions. * features/rs6000/powerpc-vsx32.xml: New file. * features/rs6000/powerpc-vsx32l.xml: New file. * features/rs6000/powerpc-vsx64.xml: New file. * features/rs6000/powerpc-vsx64l.xml: New file. * features/rs6000/powerpc-vsx32.c: New file (generated). * features/rs6000/powerpc-vsx32l.c: New file (generated). * features/rs6000/powerpc-vsx64.c: New file (generated). * features/rs6000/powerpc-vsx64l.c: New file (generated). * features/Makefile: Updated with new descriptions. * regformats/rs6000/powerpc-vsx32l.dat: New file (generated). * regformats/rs6000/powerpc-vsx64l.dat: New file (generated). * testsuite/gdb.arch/vsx-regs.c: New source file. * testsuite/gdb.arch/vsx-regs.exp: New testcase. * testsuite/lib/gdb.exp (skip_vsx_tests): New function.
2008-08-15 23:18:34 +08:00
static void
[PowerPC] Fix VSX registers in linux core files The functions used by the VSX regset to collect and supply registers from core files where incorrect. This patch changes the regset to use the standard regset collect/supply functions to fix this. The native target is also changed to use the same regset. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-linux-tdep.c (ppc_linux_vsxregset): New function. (ppc32_linux_vsxregmap): New global. (ppc32_linux_vsxregset): Initialize with ppc32_linux_vsxregmap, regcache_supply_regset, and regcache_collect_regset. * ppc-linux-tdep.h (ppc_linux_vsxregset): Declare. * ppc-linux-nat.c (supply_vsxregset, fill_vsxregset): Remove. (fetch_vsx_register, store_vsx_register): Remove. (fetch_vsx_registers): Add regno parameter. Get regset using ppc_linux_vsxregset. Use regset to supply registers. (store_vsx_registers): Add regno parameter. Get regset using ppc_linux_vsxregset. Use regset to collect registers. (fetch_register): Call fetch_vsx_registers instead of fetch_vsx_register. (store_register): Call store_vsx_registers instead of store_vsx_register. (fetch_ppc_registers): Call fetch_vsx_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_vsx_registers with -1 for the new regno parameter. * rs6000-tdep.c (ppc_vsx_support_p, ppc_supply_vsxreget) (ppc_collect_vsxregset): Remove. gdb/testsuite/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * gdb.arch/powerpc-vsx-gcore.exp: New file.
2018-05-22 22:09:05 +08:00
store_vsx_registers (const struct regcache *regcache, int tid, int regno)
* rs6000-tdep: Include "features/rs6000/powerpc-vsx32.c". Include "features/rs6000/powerpc-vsx64.c". (ppc_supply_vsxregset): New function. (ppc_collect_vsxregset): New function. (IS_VSX_PSEUDOREG): New macro. (IS_EFP_PSEUDOREG): New macro. (vsx_register_p): New function. (ppc_vsx_support_p): New function. (rs6000_builtin_type_vec128): New function. (rs6000_register_name): Hide upper halves of vs0~vs31. Return correct names for VSX registers and EFPR registers. (rs6000_pseudo_register_type): Return correct types for VSX and EFPR registers. (rs6000_pseudo_register_reggroup_p): Return correct group for VSX and EFPR registers. (ppc_pseudo_register_read): Rename to dfp_pseudo_register_read. (ppc_pseudo_register_write): Rename to dfp_pseudo_register_write. (vsx_pseudo_register_read): New function. (vsx_pseudo_register_write): New function. (efpr_pseudo_register_read): New function. (efpr_pseudo_register_write): New function. (rs6000_pseudo_register_read): Call new VSX and EFPR read functions. (rs6000_pseudo_register_write): Call new VSX and EFPR write functions. (rs6000_gdbarch_init): Declare have_vsx. Initialize new upper half VSX registers. Initialize VSX-related and EFPR-related pseudo-registers variables. Adjust the number of pseudo registers accordingly. * ppc-linux-nat.c: Define PTRACE_GETVSXREGS, PTRACE_SETVSXREGS and SIZEOF_VSRREGS. (gdb_vsxregset_t): New type. (have_ptrace_getsetvsxregs): New variable. (fetch_vsx_register): New function. (fetch_register): Handle VSX registers. (fetch_vsx_registers): New function. (fetch_ppc_registers): Handle VSX registers. (store_ppc_registers): Handle VSX registers. (store_vsx_register): New function. (store_register): Handle VSX registers. (store_vsx_registers): New function. (ppc_linux_read_description): Handle VSX-enabled inferiors. (gdb_vsxregset_t): New type. (supply_vsxregset): New function. (fill_vsxregset): New function. * ppc-tdep.h (vsx_register_p): New prototype. (vsx_support_p): New prototype. (ppc_vsr0_regnum): New variable. (ppc_vsr0_upper_regnum): Likewise. (ppc_efpr0_regnum): Likewise. (ppc_builtin_type_vec128): New type. (ppc_num_vsrs): New constant. (ppc_num_vshrs): New constant. (ppc_num_efprs): Likewise. Define POWERPC_VEC_VSX PPC_VSR0_UPPER_REGNUM and PPC_VSR31_UPPER_REGNUM. (ppc_supply_vsxregset): New prototype. (ppc_collect_vsxregset): New prototype. * ppc-linux-tdep.c: Include "features/rs6000/powerpc-vsx32l.c" Include "features/rs6000/powerpc-vsx64l.c". (_initialize_ppc_linux_tdep): Initialize VSX-enabled targets. (ppc_linux_regset_sections): Add new ".reg-ppc-vsx" field. (ppc32_linux_vsxregset): New 32-bit VSX-enabled regset. (ppc_linux_regset_from_core_section): Handle VSX core section. (ppc_linux_core_read_description): Support VSX-enabled core files. * ppc-linux-tdep.h: Declare *tdesc_powerpc_vsx32l Declare tdesc_powerpc_vsx64l * corelow.c (get_core_register_section): Support VSX-enabled core files. * features/rs6000/power-vsx.xml: New VSX descriptions. * features/rs6000/powerpc-vsx32.xml: New file. * features/rs6000/powerpc-vsx32l.xml: New file. * features/rs6000/powerpc-vsx64.xml: New file. * features/rs6000/powerpc-vsx64l.xml: New file. * features/rs6000/powerpc-vsx32.c: New file (generated). * features/rs6000/powerpc-vsx32l.c: New file (generated). * features/rs6000/powerpc-vsx64.c: New file (generated). * features/rs6000/powerpc-vsx64l.c: New file (generated). * features/Makefile: Updated with new descriptions. * regformats/rs6000/powerpc-vsx32l.dat: New file (generated). * regformats/rs6000/powerpc-vsx64l.dat: New file (generated). * testsuite/gdb.arch/vsx-regs.c: New source file. * testsuite/gdb.arch/vsx-regs.exp: New testcase. * testsuite/lib/gdb.exp (skip_vsx_tests): New function.
2008-08-15 23:18:34 +08:00
{
int ret;
gdb_vsxregset_t regs;
[PowerPC] Fix VSX registers in linux core files The functions used by the VSX regset to collect and supply registers from core files where incorrect. This patch changes the regset to use the standard regset collect/supply functions to fix this. The native target is also changed to use the same regset. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-linux-tdep.c (ppc_linux_vsxregset): New function. (ppc32_linux_vsxregmap): New global. (ppc32_linux_vsxregset): Initialize with ppc32_linux_vsxregmap, regcache_supply_regset, and regcache_collect_regset. * ppc-linux-tdep.h (ppc_linux_vsxregset): Declare. * ppc-linux-nat.c (supply_vsxregset, fill_vsxregset): Remove. (fetch_vsx_register, store_vsx_register): Remove. (fetch_vsx_registers): Add regno parameter. Get regset using ppc_linux_vsxregset. Use regset to supply registers. (store_vsx_registers): Add regno parameter. Get regset using ppc_linux_vsxregset. Use regset to collect registers. (fetch_register): Call fetch_vsx_registers instead of fetch_vsx_register. (store_register): Call store_vsx_registers instead of store_vsx_register. (fetch_ppc_registers): Call fetch_vsx_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_vsx_registers with -1 for the new regno parameter. * rs6000-tdep.c (ppc_vsx_support_p, ppc_supply_vsxreget) (ppc_collect_vsxregset): Remove. gdb/testsuite/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * gdb.arch/powerpc-vsx-gcore.exp: New file.
2018-05-22 22:09:05 +08:00
const struct regset *vsxregset = ppc_linux_vsxregset ();
* rs6000-tdep: Include "features/rs6000/powerpc-vsx32.c". Include "features/rs6000/powerpc-vsx64.c". (ppc_supply_vsxregset): New function. (ppc_collect_vsxregset): New function. (IS_VSX_PSEUDOREG): New macro. (IS_EFP_PSEUDOREG): New macro. (vsx_register_p): New function. (ppc_vsx_support_p): New function. (rs6000_builtin_type_vec128): New function. (rs6000_register_name): Hide upper halves of vs0~vs31. Return correct names for VSX registers and EFPR registers. (rs6000_pseudo_register_type): Return correct types for VSX and EFPR registers. (rs6000_pseudo_register_reggroup_p): Return correct group for VSX and EFPR registers. (ppc_pseudo_register_read): Rename to dfp_pseudo_register_read. (ppc_pseudo_register_write): Rename to dfp_pseudo_register_write. (vsx_pseudo_register_read): New function. (vsx_pseudo_register_write): New function. (efpr_pseudo_register_read): New function. (efpr_pseudo_register_write): New function. (rs6000_pseudo_register_read): Call new VSX and EFPR read functions. (rs6000_pseudo_register_write): Call new VSX and EFPR write functions. (rs6000_gdbarch_init): Declare have_vsx. Initialize new upper half VSX registers. Initialize VSX-related and EFPR-related pseudo-registers variables. Adjust the number of pseudo registers accordingly. * ppc-linux-nat.c: Define PTRACE_GETVSXREGS, PTRACE_SETVSXREGS and SIZEOF_VSRREGS. (gdb_vsxregset_t): New type. (have_ptrace_getsetvsxregs): New variable. (fetch_vsx_register): New function. (fetch_register): Handle VSX registers. (fetch_vsx_registers): New function. (fetch_ppc_registers): Handle VSX registers. (store_ppc_registers): Handle VSX registers. (store_vsx_register): New function. (store_register): Handle VSX registers. (store_vsx_registers): New function. (ppc_linux_read_description): Handle VSX-enabled inferiors. (gdb_vsxregset_t): New type. (supply_vsxregset): New function. (fill_vsxregset): New function. * ppc-tdep.h (vsx_register_p): New prototype. (vsx_support_p): New prototype. (ppc_vsr0_regnum): New variable. (ppc_vsr0_upper_regnum): Likewise. (ppc_efpr0_regnum): Likewise. (ppc_builtin_type_vec128): New type. (ppc_num_vsrs): New constant. (ppc_num_vshrs): New constant. (ppc_num_efprs): Likewise. Define POWERPC_VEC_VSX PPC_VSR0_UPPER_REGNUM and PPC_VSR31_UPPER_REGNUM. (ppc_supply_vsxregset): New prototype. (ppc_collect_vsxregset): New prototype. * ppc-linux-tdep.c: Include "features/rs6000/powerpc-vsx32l.c" Include "features/rs6000/powerpc-vsx64l.c". (_initialize_ppc_linux_tdep): Initialize VSX-enabled targets. (ppc_linux_regset_sections): Add new ".reg-ppc-vsx" field. (ppc32_linux_vsxregset): New 32-bit VSX-enabled regset. (ppc_linux_regset_from_core_section): Handle VSX core section. (ppc_linux_core_read_description): Support VSX-enabled core files. * ppc-linux-tdep.h: Declare *tdesc_powerpc_vsx32l Declare tdesc_powerpc_vsx64l * corelow.c (get_core_register_section): Support VSX-enabled core files. * features/rs6000/power-vsx.xml: New VSX descriptions. * features/rs6000/powerpc-vsx32.xml: New file. * features/rs6000/powerpc-vsx32l.xml: New file. * features/rs6000/powerpc-vsx64.xml: New file. * features/rs6000/powerpc-vsx64l.xml: New file. * features/rs6000/powerpc-vsx32.c: New file (generated). * features/rs6000/powerpc-vsx32l.c: New file (generated). * features/rs6000/powerpc-vsx64.c: New file (generated). * features/rs6000/powerpc-vsx64l.c: New file (generated). * features/Makefile: Updated with new descriptions. * regformats/rs6000/powerpc-vsx32l.dat: New file (generated). * regformats/rs6000/powerpc-vsx64l.dat: New file (generated). * testsuite/gdb.arch/vsx-regs.c: New source file. * testsuite/gdb.arch/vsx-regs.exp: New testcase. * testsuite/lib/gdb.exp (skip_vsx_tests): New function.
2008-08-15 23:18:34 +08:00
ret = ptrace (PTRACE_GETVSXREGS, tid, 0, &regs);
* rs6000-tdep: Include "features/rs6000/powerpc-vsx32.c". Include "features/rs6000/powerpc-vsx64.c". (ppc_supply_vsxregset): New function. (ppc_collect_vsxregset): New function. (IS_VSX_PSEUDOREG): New macro. (IS_EFP_PSEUDOREG): New macro. (vsx_register_p): New function. (ppc_vsx_support_p): New function. (rs6000_builtin_type_vec128): New function. (rs6000_register_name): Hide upper halves of vs0~vs31. Return correct names for VSX registers and EFPR registers. (rs6000_pseudo_register_type): Return correct types for VSX and EFPR registers. (rs6000_pseudo_register_reggroup_p): Return correct group for VSX and EFPR registers. (ppc_pseudo_register_read): Rename to dfp_pseudo_register_read. (ppc_pseudo_register_write): Rename to dfp_pseudo_register_write. (vsx_pseudo_register_read): New function. (vsx_pseudo_register_write): New function. (efpr_pseudo_register_read): New function. (efpr_pseudo_register_write): New function. (rs6000_pseudo_register_read): Call new VSX and EFPR read functions. (rs6000_pseudo_register_write): Call new VSX and EFPR write functions. (rs6000_gdbarch_init): Declare have_vsx. Initialize new upper half VSX registers. Initialize VSX-related and EFPR-related pseudo-registers variables. Adjust the number of pseudo registers accordingly. * ppc-linux-nat.c: Define PTRACE_GETVSXREGS, PTRACE_SETVSXREGS and SIZEOF_VSRREGS. (gdb_vsxregset_t): New type. (have_ptrace_getsetvsxregs): New variable. (fetch_vsx_register): New function. (fetch_register): Handle VSX registers. (fetch_vsx_registers): New function. (fetch_ppc_registers): Handle VSX registers. (store_ppc_registers): Handle VSX registers. (store_vsx_register): New function. (store_register): Handle VSX registers. (store_vsx_registers): New function. (ppc_linux_read_description): Handle VSX-enabled inferiors. (gdb_vsxregset_t): New type. (supply_vsxregset): New function. (fill_vsxregset): New function. * ppc-tdep.h (vsx_register_p): New prototype. (vsx_support_p): New prototype. (ppc_vsr0_regnum): New variable. (ppc_vsr0_upper_regnum): Likewise. (ppc_efpr0_regnum): Likewise. (ppc_builtin_type_vec128): New type. (ppc_num_vsrs): New constant. (ppc_num_vshrs): New constant. (ppc_num_efprs): Likewise. Define POWERPC_VEC_VSX PPC_VSR0_UPPER_REGNUM and PPC_VSR31_UPPER_REGNUM. (ppc_supply_vsxregset): New prototype. (ppc_collect_vsxregset): New prototype. * ppc-linux-tdep.c: Include "features/rs6000/powerpc-vsx32l.c" Include "features/rs6000/powerpc-vsx64l.c". (_initialize_ppc_linux_tdep): Initialize VSX-enabled targets. (ppc_linux_regset_sections): Add new ".reg-ppc-vsx" field. (ppc32_linux_vsxregset): New 32-bit VSX-enabled regset. (ppc_linux_regset_from_core_section): Handle VSX core section. (ppc_linux_core_read_description): Support VSX-enabled core files. * ppc-linux-tdep.h: Declare *tdesc_powerpc_vsx32l Declare tdesc_powerpc_vsx64l * corelow.c (get_core_register_section): Support VSX-enabled core files. * features/rs6000/power-vsx.xml: New VSX descriptions. * features/rs6000/powerpc-vsx32.xml: New file. * features/rs6000/powerpc-vsx32l.xml: New file. * features/rs6000/powerpc-vsx64.xml: New file. * features/rs6000/powerpc-vsx64l.xml: New file. * features/rs6000/powerpc-vsx32.c: New file (generated). * features/rs6000/powerpc-vsx32l.c: New file (generated). * features/rs6000/powerpc-vsx64.c: New file (generated). * features/rs6000/powerpc-vsx64l.c: New file (generated). * features/Makefile: Updated with new descriptions. * regformats/rs6000/powerpc-vsx32l.dat: New file (generated). * regformats/rs6000/powerpc-vsx64l.dat: New file (generated). * testsuite/gdb.arch/vsx-regs.c: New source file. * testsuite/gdb.arch/vsx-regs.exp: New testcase. * testsuite/lib/gdb.exp (skip_vsx_tests): New function.
2008-08-15 23:18:34 +08:00
if (ret < 0)
{
if (errno == EIO)
{
have_ptrace_getsetvsxregs = 0;
return;
}
[PowerPC] Fix VSX registers in linux core files The functions used by the VSX regset to collect and supply registers from core files where incorrect. This patch changes the regset to use the standard regset collect/supply functions to fix this. The native target is also changed to use the same regset. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-linux-tdep.c (ppc_linux_vsxregset): New function. (ppc32_linux_vsxregmap): New global. (ppc32_linux_vsxregset): Initialize with ppc32_linux_vsxregmap, regcache_supply_regset, and regcache_collect_regset. * ppc-linux-tdep.h (ppc_linux_vsxregset): Declare. * ppc-linux-nat.c (supply_vsxregset, fill_vsxregset): Remove. (fetch_vsx_register, store_vsx_register): Remove. (fetch_vsx_registers): Add regno parameter. Get regset using ppc_linux_vsxregset. Use regset to supply registers. (store_vsx_registers): Add regno parameter. Get regset using ppc_linux_vsxregset. Use regset to collect registers. (fetch_register): Call fetch_vsx_registers instead of fetch_vsx_register. (store_register): Call store_vsx_registers instead of store_vsx_register. (fetch_ppc_registers): Call fetch_vsx_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_vsx_registers with -1 for the new regno parameter. * rs6000-tdep.c (ppc_vsx_support_p, ppc_supply_vsxreget) (ppc_collect_vsxregset): Remove. gdb/testsuite/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * gdb.arch/powerpc-vsx-gcore.exp: New file.
2018-05-22 22:09:05 +08:00
perror_with_name (_("Unable to fetch VSX registers"));
* rs6000-tdep: Include "features/rs6000/powerpc-vsx32.c". Include "features/rs6000/powerpc-vsx64.c". (ppc_supply_vsxregset): New function. (ppc_collect_vsxregset): New function. (IS_VSX_PSEUDOREG): New macro. (IS_EFP_PSEUDOREG): New macro. (vsx_register_p): New function. (ppc_vsx_support_p): New function. (rs6000_builtin_type_vec128): New function. (rs6000_register_name): Hide upper halves of vs0~vs31. Return correct names for VSX registers and EFPR registers. (rs6000_pseudo_register_type): Return correct types for VSX and EFPR registers. (rs6000_pseudo_register_reggroup_p): Return correct group for VSX and EFPR registers. (ppc_pseudo_register_read): Rename to dfp_pseudo_register_read. (ppc_pseudo_register_write): Rename to dfp_pseudo_register_write. (vsx_pseudo_register_read): New function. (vsx_pseudo_register_write): New function. (efpr_pseudo_register_read): New function. (efpr_pseudo_register_write): New function. (rs6000_pseudo_register_read): Call new VSX and EFPR read functions. (rs6000_pseudo_register_write): Call new VSX and EFPR write functions. (rs6000_gdbarch_init): Declare have_vsx. Initialize new upper half VSX registers. Initialize VSX-related and EFPR-related pseudo-registers variables. Adjust the number of pseudo registers accordingly. * ppc-linux-nat.c: Define PTRACE_GETVSXREGS, PTRACE_SETVSXREGS and SIZEOF_VSRREGS. (gdb_vsxregset_t): New type. (have_ptrace_getsetvsxregs): New variable. (fetch_vsx_register): New function. (fetch_register): Handle VSX registers. (fetch_vsx_registers): New function. (fetch_ppc_registers): Handle VSX registers. (store_ppc_registers): Handle VSX registers. (store_vsx_register): New function. (store_register): Handle VSX registers. (store_vsx_registers): New function. (ppc_linux_read_description): Handle VSX-enabled inferiors. (gdb_vsxregset_t): New type. (supply_vsxregset): New function. (fill_vsxregset): New function. * ppc-tdep.h (vsx_register_p): New prototype. (vsx_support_p): New prototype. (ppc_vsr0_regnum): New variable. (ppc_vsr0_upper_regnum): Likewise. (ppc_efpr0_regnum): Likewise. (ppc_builtin_type_vec128): New type. (ppc_num_vsrs): New constant. (ppc_num_vshrs): New constant. (ppc_num_efprs): Likewise. Define POWERPC_VEC_VSX PPC_VSR0_UPPER_REGNUM and PPC_VSR31_UPPER_REGNUM. (ppc_supply_vsxregset): New prototype. (ppc_collect_vsxregset): New prototype. * ppc-linux-tdep.c: Include "features/rs6000/powerpc-vsx32l.c" Include "features/rs6000/powerpc-vsx64l.c". (_initialize_ppc_linux_tdep): Initialize VSX-enabled targets. (ppc_linux_regset_sections): Add new ".reg-ppc-vsx" field. (ppc32_linux_vsxregset): New 32-bit VSX-enabled regset. (ppc_linux_regset_from_core_section): Handle VSX core section. (ppc_linux_core_read_description): Support VSX-enabled core files. * ppc-linux-tdep.h: Declare *tdesc_powerpc_vsx32l Declare tdesc_powerpc_vsx64l * corelow.c (get_core_register_section): Support VSX-enabled core files. * features/rs6000/power-vsx.xml: New VSX descriptions. * features/rs6000/powerpc-vsx32.xml: New file. * features/rs6000/powerpc-vsx32l.xml: New file. * features/rs6000/powerpc-vsx64.xml: New file. * features/rs6000/powerpc-vsx64l.xml: New file. * features/rs6000/powerpc-vsx32.c: New file (generated). * features/rs6000/powerpc-vsx32l.c: New file (generated). * features/rs6000/powerpc-vsx64.c: New file (generated). * features/rs6000/powerpc-vsx64l.c: New file (generated). * features/Makefile: Updated with new descriptions. * regformats/rs6000/powerpc-vsx32l.dat: New file (generated). * regformats/rs6000/powerpc-vsx64l.dat: New file (generated). * testsuite/gdb.arch/vsx-regs.c: New source file. * testsuite/gdb.arch/vsx-regs.exp: New testcase. * testsuite/lib/gdb.exp (skip_vsx_tests): New function.
2008-08-15 23:18:34 +08:00
}
[PowerPC] Fix VSX registers in linux core files The functions used by the VSX regset to collect and supply registers from core files where incorrect. This patch changes the regset to use the standard regset collect/supply functions to fix this. The native target is also changed to use the same regset. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-linux-tdep.c (ppc_linux_vsxregset): New function. (ppc32_linux_vsxregmap): New global. (ppc32_linux_vsxregset): Initialize with ppc32_linux_vsxregmap, regcache_supply_regset, and regcache_collect_regset. * ppc-linux-tdep.h (ppc_linux_vsxregset): Declare. * ppc-linux-nat.c (supply_vsxregset, fill_vsxregset): Remove. (fetch_vsx_register, store_vsx_register): Remove. (fetch_vsx_registers): Add regno parameter. Get regset using ppc_linux_vsxregset. Use regset to supply registers. (store_vsx_registers): Add regno parameter. Get regset using ppc_linux_vsxregset. Use regset to collect registers. (fetch_register): Call fetch_vsx_registers instead of fetch_vsx_register. (store_register): Call store_vsx_registers instead of store_vsx_register. (fetch_ppc_registers): Call fetch_vsx_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_vsx_registers with -1 for the new regno parameter. * rs6000-tdep.c (ppc_vsx_support_p, ppc_supply_vsxreget) (ppc_collect_vsxregset): Remove. gdb/testsuite/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * gdb.arch/powerpc-vsx-gcore.exp: New file.
2018-05-22 22:09:05 +08:00
vsxregset->collect_regset (vsxregset, regcache, regno, &regs,
PPC_LINUX_SIZEOF_VSXREGSET);
* rs6000-tdep: Include "features/rs6000/powerpc-vsx32.c". Include "features/rs6000/powerpc-vsx64.c". (ppc_supply_vsxregset): New function. (ppc_collect_vsxregset): New function. (IS_VSX_PSEUDOREG): New macro. (IS_EFP_PSEUDOREG): New macro. (vsx_register_p): New function. (ppc_vsx_support_p): New function. (rs6000_builtin_type_vec128): New function. (rs6000_register_name): Hide upper halves of vs0~vs31. Return correct names for VSX registers and EFPR registers. (rs6000_pseudo_register_type): Return correct types for VSX and EFPR registers. (rs6000_pseudo_register_reggroup_p): Return correct group for VSX and EFPR registers. (ppc_pseudo_register_read): Rename to dfp_pseudo_register_read. (ppc_pseudo_register_write): Rename to dfp_pseudo_register_write. (vsx_pseudo_register_read): New function. (vsx_pseudo_register_write): New function. (efpr_pseudo_register_read): New function. (efpr_pseudo_register_write): New function. (rs6000_pseudo_register_read): Call new VSX and EFPR read functions. (rs6000_pseudo_register_write): Call new VSX and EFPR write functions. (rs6000_gdbarch_init): Declare have_vsx. Initialize new upper half VSX registers. Initialize VSX-related and EFPR-related pseudo-registers variables. Adjust the number of pseudo registers accordingly. * ppc-linux-nat.c: Define PTRACE_GETVSXREGS, PTRACE_SETVSXREGS and SIZEOF_VSRREGS. (gdb_vsxregset_t): New type. (have_ptrace_getsetvsxregs): New variable. (fetch_vsx_register): New function. (fetch_register): Handle VSX registers. (fetch_vsx_registers): New function. (fetch_ppc_registers): Handle VSX registers. (store_ppc_registers): Handle VSX registers. (store_vsx_register): New function. (store_register): Handle VSX registers. (store_vsx_registers): New function. (ppc_linux_read_description): Handle VSX-enabled inferiors. (gdb_vsxregset_t): New type. (supply_vsxregset): New function. (fill_vsxregset): New function. * ppc-tdep.h (vsx_register_p): New prototype. (vsx_support_p): New prototype. (ppc_vsr0_regnum): New variable. (ppc_vsr0_upper_regnum): Likewise. (ppc_efpr0_regnum): Likewise. (ppc_builtin_type_vec128): New type. (ppc_num_vsrs): New constant. (ppc_num_vshrs): New constant. (ppc_num_efprs): Likewise. Define POWERPC_VEC_VSX PPC_VSR0_UPPER_REGNUM and PPC_VSR31_UPPER_REGNUM. (ppc_supply_vsxregset): New prototype. (ppc_collect_vsxregset): New prototype. * ppc-linux-tdep.c: Include "features/rs6000/powerpc-vsx32l.c" Include "features/rs6000/powerpc-vsx64l.c". (_initialize_ppc_linux_tdep): Initialize VSX-enabled targets. (ppc_linux_regset_sections): Add new ".reg-ppc-vsx" field. (ppc32_linux_vsxregset): New 32-bit VSX-enabled regset. (ppc_linux_regset_from_core_section): Handle VSX core section. (ppc_linux_core_read_description): Support VSX-enabled core files. * ppc-linux-tdep.h: Declare *tdesc_powerpc_vsx32l Declare tdesc_powerpc_vsx64l * corelow.c (get_core_register_section): Support VSX-enabled core files. * features/rs6000/power-vsx.xml: New VSX descriptions. * features/rs6000/powerpc-vsx32.xml: New file. * features/rs6000/powerpc-vsx32l.xml: New file. * features/rs6000/powerpc-vsx64.xml: New file. * features/rs6000/powerpc-vsx64l.xml: New file. * features/rs6000/powerpc-vsx32.c: New file (generated). * features/rs6000/powerpc-vsx32l.c: New file (generated). * features/rs6000/powerpc-vsx64.c: New file (generated). * features/rs6000/powerpc-vsx64l.c: New file (generated). * features/Makefile: Updated with new descriptions. * regformats/rs6000/powerpc-vsx32l.dat: New file (generated). * regformats/rs6000/powerpc-vsx64l.dat: New file (generated). * testsuite/gdb.arch/vsx-regs.c: New source file. * testsuite/gdb.arch/vsx-regs.exp: New testcase. * testsuite/lib/gdb.exp (skip_vsx_tests): New function.
2008-08-15 23:18:34 +08:00
ret = ptrace (PTRACE_SETVSXREGS, tid, 0, &regs);
if (ret < 0)
[PowerPC] Fix VSX registers in linux core files The functions used by the VSX regset to collect and supply registers from core files where incorrect. This patch changes the regset to use the standard regset collect/supply functions to fix this. The native target is also changed to use the same regset. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-linux-tdep.c (ppc_linux_vsxregset): New function. (ppc32_linux_vsxregmap): New global. (ppc32_linux_vsxregset): Initialize with ppc32_linux_vsxregmap, regcache_supply_regset, and regcache_collect_regset. * ppc-linux-tdep.h (ppc_linux_vsxregset): Declare. * ppc-linux-nat.c (supply_vsxregset, fill_vsxregset): Remove. (fetch_vsx_register, store_vsx_register): Remove. (fetch_vsx_registers): Add regno parameter. Get regset using ppc_linux_vsxregset. Use regset to supply registers. (store_vsx_registers): Add regno parameter. Get regset using ppc_linux_vsxregset. Use regset to collect registers. (fetch_register): Call fetch_vsx_registers instead of fetch_vsx_register. (store_register): Call store_vsx_registers instead of store_vsx_register. (fetch_ppc_registers): Call fetch_vsx_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_vsx_registers with -1 for the new regno parameter. * rs6000-tdep.c (ppc_vsx_support_p, ppc_supply_vsxreget) (ppc_collect_vsxregset): Remove. gdb/testsuite/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * gdb.arch/powerpc-vsx-gcore.exp: New file.
2018-05-22 22:09:05 +08:00
perror_with_name (_("Unable to store VSX registers"));
* rs6000-tdep: Include "features/rs6000/powerpc-vsx32.c". Include "features/rs6000/powerpc-vsx64.c". (ppc_supply_vsxregset): New function. (ppc_collect_vsxregset): New function. (IS_VSX_PSEUDOREG): New macro. (IS_EFP_PSEUDOREG): New macro. (vsx_register_p): New function. (ppc_vsx_support_p): New function. (rs6000_builtin_type_vec128): New function. (rs6000_register_name): Hide upper halves of vs0~vs31. Return correct names for VSX registers and EFPR registers. (rs6000_pseudo_register_type): Return correct types for VSX and EFPR registers. (rs6000_pseudo_register_reggroup_p): Return correct group for VSX and EFPR registers. (ppc_pseudo_register_read): Rename to dfp_pseudo_register_read. (ppc_pseudo_register_write): Rename to dfp_pseudo_register_write. (vsx_pseudo_register_read): New function. (vsx_pseudo_register_write): New function. (efpr_pseudo_register_read): New function. (efpr_pseudo_register_write): New function. (rs6000_pseudo_register_read): Call new VSX and EFPR read functions. (rs6000_pseudo_register_write): Call new VSX and EFPR write functions. (rs6000_gdbarch_init): Declare have_vsx. Initialize new upper half VSX registers. Initialize VSX-related and EFPR-related pseudo-registers variables. Adjust the number of pseudo registers accordingly. * ppc-linux-nat.c: Define PTRACE_GETVSXREGS, PTRACE_SETVSXREGS and SIZEOF_VSRREGS. (gdb_vsxregset_t): New type. (have_ptrace_getsetvsxregs): New variable. (fetch_vsx_register): New function. (fetch_register): Handle VSX registers. (fetch_vsx_registers): New function. (fetch_ppc_registers): Handle VSX registers. (store_ppc_registers): Handle VSX registers. (store_vsx_register): New function. (store_register): Handle VSX registers. (store_vsx_registers): New function. (ppc_linux_read_description): Handle VSX-enabled inferiors. (gdb_vsxregset_t): New type. (supply_vsxregset): New function. (fill_vsxregset): New function. * ppc-tdep.h (vsx_register_p): New prototype. (vsx_support_p): New prototype. (ppc_vsr0_regnum): New variable. (ppc_vsr0_upper_regnum): Likewise. (ppc_efpr0_regnum): Likewise. (ppc_builtin_type_vec128): New type. (ppc_num_vsrs): New constant. (ppc_num_vshrs): New constant. (ppc_num_efprs): Likewise. Define POWERPC_VEC_VSX PPC_VSR0_UPPER_REGNUM and PPC_VSR31_UPPER_REGNUM. (ppc_supply_vsxregset): New prototype. (ppc_collect_vsxregset): New prototype. * ppc-linux-tdep.c: Include "features/rs6000/powerpc-vsx32l.c" Include "features/rs6000/powerpc-vsx64l.c". (_initialize_ppc_linux_tdep): Initialize VSX-enabled targets. (ppc_linux_regset_sections): Add new ".reg-ppc-vsx" field. (ppc32_linux_vsxregset): New 32-bit VSX-enabled regset. (ppc_linux_regset_from_core_section): Handle VSX core section. (ppc_linux_core_read_description): Support VSX-enabled core files. * ppc-linux-tdep.h: Declare *tdesc_powerpc_vsx32l Declare tdesc_powerpc_vsx64l * corelow.c (get_core_register_section): Support VSX-enabled core files. * features/rs6000/power-vsx.xml: New VSX descriptions. * features/rs6000/powerpc-vsx32.xml: New file. * features/rs6000/powerpc-vsx32l.xml: New file. * features/rs6000/powerpc-vsx64.xml: New file. * features/rs6000/powerpc-vsx64l.xml: New file. * features/rs6000/powerpc-vsx32.c: New file (generated). * features/rs6000/powerpc-vsx32l.c: New file (generated). * features/rs6000/powerpc-vsx64.c: New file (generated). * features/rs6000/powerpc-vsx64l.c: New file (generated). * features/Makefile: Updated with new descriptions. * regformats/rs6000/powerpc-vsx32l.dat: New file (generated). * regformats/rs6000/powerpc-vsx64l.dat: New file (generated). * testsuite/gdb.arch/vsx-regs.c: New source file. * testsuite/gdb.arch/vsx-regs.exp: New testcase. * testsuite/lib/gdb.exp (skip_vsx_tests): New function.
2008-08-15 23:18:34 +08:00
}
static void
[PowerPC] Fix access to VSCR in linux targets The 4-byte VSCR register is found inside a 16-byte field in the regset returned by ptrace and in core files. The position of VSCR depends on the endianess of the target, which was previously assumed to be big-endian for the purpose of getting VSCR. This patch removes this assumption to fix access to VSCR in little-endian mode. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-tdep.h (struct ppc_reg_offsets): Remove vector register offset fields. * ppc-fbsd-tdep.c (ppc32_fbsd_reg_offsets): Remove initializers for vector register offset fields. (ppc64_fbsd_reg_offsets): Likewise. * ppc-nbsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-nat.c (_initialize_ppcobsd_nat): Remove assignment to vector register offset fields. * rs6000-aix-tdep.c (rs6000_aix32_reg_offsets): Remove initializers for vector register offset fields. (rs6000_aix64_reg_offsets): Likewise. * rs6000-tdep.c (ppc_vrreg_offset): Remove. (ppc_supply_vrregset): Remove. (ppc_collect_vrregset): Remove. * ppc-linux-tdep.c (ppc_linux_collect_vrregset): New function. (ppc_linux_vrregset) : New function. (ppc32_le_linux_vrregmap, ppc32_be_linux_vrregmap) (ppc32_le_linux_vrregset, ppc32_be_linux_vrregset): New globals. (ppc32_linux_vrregset): Remove. (ppc_linux_iterate_over_regset_sections): Call ppc_linux_vrregset and use result instead of ppc32_linux_vrregset. (ppc32_linux_reg_offsets): Remove initializers for vector register offset fields. (ppc64_linux_reg_offsets): Likewise. * ppc-linux-tdep.h (ppc_linux_vrregset): New declaration. * ppc-linux-nat.c: Include regset.h. (gdb_vrregset_t): Adjust comment to account for little-endian mode. (supply_vrregset, fill_vrregset): Remove. (fetch_altivec_register, store_altivec_register): Remove. (fetch_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to supply registers. (store_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to collect registers. (fetch_register): Call fetch_altivec_registers instead of fetch_altivec_register. (store_register): Call store_altivec_registers instead of store_altivec_register. (fetch_ppc_registers): Call fetch_altivec_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_altivec_registers with -1 for the new regno parameter. gdb/gdbserver/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * linux-ppc-low.c (ppc_fill_vrregset): Add vscr_offset variable. Set vscr_offset to 0 in little-endian mode and 12 in big-endian mode. Call collect_register_by_name with vscr using vscr_offset. Zero-pad vscr and vrsave fields in collector buffer. (ppc_store_vrregset): Add and set vscr_offset variable as in ppc_fill_vrregset. Call supply_register_by_name with vscr using vscr_offset.
2018-05-22 22:09:05 +08:00
store_altivec_registers (const struct regcache *regcache, int tid,
int regno)
{
int ret;
gdb_vrregset_t regs;
s/get_regcache_arch (regcache)/regcache->arch ()/g This patches removes get_regcache_arch, and use regache->arch () instead. The motivation of this change is that I am going to move some basic stuff into a base class of regcache. I don't need to update "client" code regcache->arch (). On the other hand, this patch shortens the code a little bit. gdb: 2017-10-25 Yao Qi <yao.qi@linaro.org> * aarch32-linux-nat.c (aarch32_gp_regcache_supply): Use regcache->arch () instead get_regcache_arch. * aarch64-fbsd-nat.c (aarch64_fbsd_fetch_inferior_registers): Likewise. (aarch64_fbsd_store_inferior_registers): Likewise. * aarch64-linux-nat.c (fetch_gregs_from_thread): Likewise. (store_gregs_to_thread): Likewise. (fetch_fpregs_from_thread): Likewise. (store_fpregs_to_thread): Likewise. * aarch64-tdep.c (aarch64_extract_return_value): Likewise. (aarch64_store_return_value): Likewise. (aarch64_software_single_step): Likewise. * aix-thread.c (aix_thread_wait): Likewise. (supply_reg32): Likewise. (supply_sprs64): Likewise. (supply_sprs32): Likewise. (fill_gprs64): Likewise. (fill_gprs32): Likewise. (fill_sprs64): Likewise. (fill_sprs32): Likewise. (store_regs_user_thread): Likewise. (store_regs_kernel_thread): Likewise. * alpha-bsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * alpha-tdep.c (alpha_extract_return_value): Likewise. (alpha_store_return_value): Likewise. (alpha_deal_with_atomic_sequence): Likewise. (alpha_next_pc): Likewise. (alpha_software_single_step): Likewise. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * amd64-nat.c (amd64_supply_native_gregset): Likewise. (amd64_collect_native_gregset): Likewise. * amd64-obsd-tdep.c (amd64obsd_supply_uthread): Likewise. (amd64obsd_collect_uthread): Likewise. * amd64-tdep.c (amd64_supply_fpregset): Likewise. (amd64_collect_fpregset): Likewise. (amd64_supply_fxsave): Likewise. (amd64_supply_xsave): Likewise. (amd64_collect_fxsave): Likewise. (amd64_collect_xsave): Likewise. * arc-tdep.c (arc_write_pc): Likewise. * arch-utils.c (default_skip_permanent_breakpoint): Likewise. * arm-fbsd-nat.c (arm_fbsd_fetch_inferior_registers): Likewise. (arm_fbsd_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_vfp_regs): Likewise. (store_vfp_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * arm-linux-tdep.c (arm_linux_supply_gregset): Likewise. (arm_linux_sigreturn_next_pc): Likewise. (arm_linux_get_next_pcs_syscall_next_pc): Likewise. * arm-nbsd-nat.c (arm_supply_gregset): Likewise. (fetch_register): Likewise. (store_register): Likewise. * arm-tdep.c (arm_is_thumb): Likewise. (displaced_in_arm_mode): Likewise. (bx_write_pc): Likewise. (arm_get_next_pcs_addr_bits_remove): Likewise. (arm_software_single_step): Likewise. (arm_extract_return_value): Likewise. (arm_store_return_value): Likewise. (arm_write_pc): Likewise. * bfin-tdep.c (bfin_extract_return_value): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * core-regset.c (fetch_core_registers): Likewise. * corelow.c (get_core_registers): Likewise. * cris-tdep.c (cris_store_return_value): Likewise. (cris_extract_return_value): Likewise. (find_step_target): Likewise. (find_step_target): Likewise. (cris_software_single_step): Likewise. * ctf.c (ctf_fetch_registers): Likewise. * darwin-nat.c (cancel_breakpoint): Likewise. * fbsd-tdep.c (fbsd_collect_thread_registers): Likewise. * frv-tdep.c (frv_extract_return_value): Likewise. * ft32-tdep.c (ft32_store_return_value): Likewise. (ft32_extract_return_value): Likewise. * go32-nat.c (fetch_register): Likewise. (go32_fetch_registers): Likewise. (go32_store_registers): Likewise. (store_register): Likewise. * h8300-tdep.c (h8300_extract_return_value): Likewise. (h8300_store_return_value): Likewise. * hppa-linux-nat.c (fetch_register): Likewise. (store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * i386-darwin-nat.c (i386_darwin_fetch_inferior_registers): Likewise. (i386_darwin_store_inferior_registers): Likewise. * i386-gnu-nat.c (gnu_fetch_registers): Likewise. (gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register): Likewise. (store_register): Likewise. (supply_gregset): Likewise. (fill_gregset): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. (i386_linux_resume): Likewise. * i386-linux-tdep.c (i386_linux_get_syscall_number_from_regcache): Likewise. * i386-nto-tdep.c (i386nto_supply_gregset): Likewise. * i386-obsd-nat.c (i386obsd_supply_pcb): Likewise. * i386-obsd-tdep.c (i386obsd_supply_uthread): Likewise. (i386obsd_collect_uthread): Likewise. * i386-tdep.c (i386_mmx_regnum_to_fp_regnum): Likewise. (i386_supply_gregset): Likewise. (i386_collect_gregset): Likewise. (i386_supply_fpregset): Likewise. (i386_collect_fpregset): Likewise. (i386_mpx_bd_base): Likewise. * i386-v4-nat.c (supply_fpregset): Likewise. (fill_fpregset): Likewise. * i387-tdep.c (i387_supply_fsave): Likewise. (i387_collect_fsave): Likewise. (i387_supply_fxsave): Likewise. (i387_collect_fxsave): Likewise. (i387_supply_xsave): Likewise. (i387_collect_xsave): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_registers): Likewise. * ia64-tdep.c (ia64_access_rse_reg): Likewise. (ia64_extract_return_value): Likewise. (ia64_store_return_value): Likewise. (find_func_descr): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_registers): Likewise. * infrun.c (use_displaced_stepping): Likewise. (displaced_step_prepare_throw): Likewise. (resume): Likewise. (proceed): Likewise. (do_target_wait): Likewise. (adjust_pc_after_break): Likewise. (handle_inferior_event_1): Likewise. (handle_signal_stop): Likewise. (save_infcall_suspend_state): Likewise. (restore_infcall_suspend_state): Likewise. * iq2000-tdep.c (iq2000_extract_return_value): Likewise. * jit.c (jit_frame_prev_register): Likewise. * linux-nat.c (save_stop_reason): Likewise. (linux_nat_wait_1): Likewise. (resume_stopped_resumed_lwps): Likewise. * linux-record.c (record_linux_sockaddr): Likewise. (record_linux_msghdr): Likewise. (record_linux_system_call): Likewise. * linux-tdep.c (linux_collect_thread_registers): Likewise. * lm32-tdep.c (lm32_extract_return_value): Likewise. (lm32_store_return_value): Likewise. * m32c-tdep.c (m32c_read_flg): Likewise. (m32c_pseudo_register_read): Likewise. (m32c_pseudo_register_write): Likewise. * m32r-linux-tdep.c (m32r_linux_supply_gregset): Likewise. (m32r_linux_collect_gregset): Likewise. * m32r-tdep.c (m32r_store_return_value): Likewise. (m32r_extract_return_value): Likewise. * m68k-bsd-nat.c (m68kbsd_supply_fpregset): Likewise. (m68kbsd_collect_fpregset): Likewise. * m68k-bsd-tdep.c (m68kbsd_supply_fpregset): Likewise. * m68k-linux-nat.c (fetch_register): Likewise. (old_fetch_inferior_registers): Likewise. (old_store_inferior_registers): Likewise. (store_regs): Likewise. * m68k-tdep.c (m68k_svr4_extract_return_value): Likewise. (m68k_svr4_store_return_value): Likewise. * m88k-tdep.c (m88k_store_arguments): Likewise. * mi/mi-main.c (mi_cmd_data_list_changed_registers): Likewise. (mi_cmd_data_write_register_values): Likewise. * mips-fbsd-nat.c (mips_fbsd_fetch_inferior_registers): Likewise. (mips_fbsd_store_inferior_registers): Likewise. * mips-fbsd-tdep.c (mips_fbsd_supply_fpregs): Likewise. (mips_fbsd_supply_gregs): Likewise. (mips_fbsd_collect_fpregs): Likewise. (mips_fbsd_collect_gregs): Likewise. (mips_fbsd_supply_fpregset): Likewise. (mips_fbsd_collect_fpregset): Likewise. (mips_fbsd_supply_gregset): Likewise. (mips_fbsd_collect_gregset): Likewise. * mips-linux-nat.c (supply_gregset): Likewise. (fill_gregset): Likewise. (supply_fpregset): Likewise. (fill_fpregset): Likewise. * mips-linux-tdep.c (mips_supply_gregset): Likewise. (mips_fill_gregset): Likewise. (mips_supply_fpregset): Likewise. (mips_fill_fpregset): Likewise. (mips64_supply_gregset): Likewise. (micromips_linux_sigframe_validate): Likewise. * mips-nbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * mips-nbsd-tdep.c (mipsnbsd_supply_fpregset): Likewise. (mipsnbsd_supply_gregset): Likewise. (mipsnbsd_iterate_over_regset_sections): Likewise. (mipsnbsd_supply_reg): Likewise. (mipsnbsd_supply_fpreg): Likewise. * mips-tdep.c (mips_in_frame_stub): Likewise. (mips_dummy_id): Likewise. (is_octeon_bbit_op): Likewise. (micromips_bc1_pc): Likewise. (extended_mips16_next_pc): Likewise. (mips16_next_pc): Likewise. (deal_with_atomic_sequence): Likewise. * moxie-tdep.c (moxie_process_readu): Likewise. * nios2-tdep.c (nios2_get_next_pc): Likewise. * nto-procfs.c (procfs_store_registers): Likewise. * ppc-fbsd-nat.c (ppcfbsd_fetch_inferior_registers): Likewise. (ppcfbsd_store_inferior_registers): Likewise. * ppc-linux-nat.c (fetch_vsx_register): Likewise. (fetch_altivec_register): Likewise. (get_spe_registers): Likewise. (fetch_spe_register): Likewise. (fetch_altivec_registers): Likewise. (fetch_all_gp_regs): Likewise. (fetch_all_fp_regs): Likewise. (store_vsx_register): Likewise. (store_altivec_register): Likewise. (set_spe_registers): Likewise. (store_spe_register): Likewise. (store_altivec_registers): Likewise. (store_all_gp_regs): Likewise. (store_all_fp_regs): Likewise. * ppc-linux-tdep.c (ppc_linux_supply_gregset): Likewise. (ppc_linux_collect_gregset): Likewise. (ppc_canonicalize_syscall): Likewise. (ppc_linux_record_signal): Likewise. (ppu2spu_prev_register): Likewise. * ppc-nbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-obsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * ppc-ravenscar-thread.c (ppc_ravenscar_generic_fetch_registers): Likewise. (ppc_ravenscar_generic_store_registers): Likewise. * procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ravenscar-thread.c (ravenscar_fetch_registers): Likewise. (ravenscar_store_registers): Likewise. (ravenscar_prepare_to_store): Likewise. * record-btrace.c (record_btrace_fetch_registers): Likewise. * record-full.c (record_full_wait_1): Likewise. (record_full_registers_change): Likewise. (record_full_store_registers): Likewise. (record_full_core_fetch_registers): Likewise. (record_full_save): Likewise. (record_full_goto_insn): Likewise. * regcache.c (regcache_register_size): Likewise. (get_regcache_arch): Remove. (regcache_read_pc): Likewise. * regcache.h (get_regcache_arch): Remove. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * remote.c (fetch_register_using_p): Likewise. (send_g_packet): Likewise. (remote_prepare_to_store): Likewise. (store_registers_using_G): Likewise. * reverse.c (save_bookmark_command): Likewise. (goto_bookmark_command): Likewise. * rs6000-aix-tdep.c (branch_dest): Likewise. * rs6000-nat.c (rs6000_ptrace64): Likewise. (fetch_register): Likewise. * rs6000-tdep.c (ppc_supply_reg): Likewise. (ppc_collect_reg): Likewise. (ppc_collect_gregset): Likewise. (ppc_collect_fpregset): Likewise. (ppc_collect_vsxregset): Likewise. (ppc_collect_vrregset): Likewise. (ppc_displaced_step_hw_singlestep): Likewise. (rs6000_pseudo_register_read): Likewise. (rs6000_pseudo_register_write): Likewise. * s390-linux-nat.c (supply_gregset): Likewise. (fill_gregset): Likewise. (s390_linux_fetch_inferior_registers): Likewise. * s390-linux-tdep.c (s390_write_pc): Likewise. (s390_software_single_step): Likewise. (s390_all_but_pc_registers_record): Likewise. (s390_linux_syscall_record): Likewise. * sentinel-frame.c (sentinel_frame_prev_arch): Likewise. * sh-nbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sh-tdep.c (sh_extract_return_value_nofpu): Likewise. (sh_extract_return_value_fpu): Likewise. (sh_store_return_value_nofpu): Likewise. (sh_corefile_supply_regset): Likewise. (sh_corefile_collect_regset): Likewise. * sh64-tdep.c (sh64_extract_return_value): Likewise. (sh64_store_return_value): Likewise. * sparc-linux-tdep.c (sparc32_linux_collect_core_fpregset): Likewise. * sparc-nat.c (sparc_fetch_inferior_registers): Likewise. (sparc_store_inferior_registers): Likewise. * sparc-ravenscar-thread.c (register_in_thread_descriptor_p): Likewise. (sparc_ravenscar_prepare_to_store): Likewise. * sparc-tdep.c (sparc32_store_arguments): Likewise. (sparc_analyze_control_transfer): Likewise. (sparc_step_trap): Likewise. (sparc_software_single_step): Likewise. (sparc32_gdbarch_init): Likewise. (sparc_supply_rwindow): Likewise. (sparc_collect_rwindow): Likewise. * sparc64-linux-tdep.c (sparc64_linux_collect_core_fpregset): Likewise. * sparc64-nbsd-nat.c (sparc64nbsd_supply_gregset): Likewise. (sparc64nbsd_collect_gregset): Likewise. (sparc64nbsd_supply_fpregset): Likewise. (sparc64nbsd_collect_fpregset): Likewise. * sparc64-tdep.c (sparc64_store_arguments): Likewise. (sparc64_supply_gregset): Likewise. (sparc64_collect_gregset): Likewise. (sparc64_supply_fpregset): Likewise. (sparc64_collect_fpregset): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. * spu-tdep.c (spu_unwind_sp): Likewise. (spu2ppu_prev_register): Likewise. (spu_memory_remove_breakpoint): Likewise. * stack.c (return_command): Likewise. * tic6x-tdep.c (tic6x_extract_signed_field): Likewise. * tracefile-tfile.c (tfile_fetch_registers): Likewise. * tracefile.c (trace_save_ctf): Likewise. * windows-nat.c (do_windows_fetch_inferior_registers): Likewise. (do_windows_store_inferior_registers): Likewise. (windows_resume): Likewise. * xtensa-linux-nat.c (fill_gregset): Likewise. (supply_gregset_reg): Likewise. * xtensa-tdep.c (xtensa_register_write_masked): Likewise. (xtensa_register_read_masked): Likewise. (xtensa_supply_gregset): Likewise. (xtensa_extract_return_value): Likewise. (xtensa_store_return_value): Likewise.
2017-10-25 23:37:03 +08:00
struct gdbarch *gdbarch = regcache->arch ();
[PowerPC] Fix access to VSCR in linux targets The 4-byte VSCR register is found inside a 16-byte field in the regset returned by ptrace and in core files. The position of VSCR depends on the endianess of the target, which was previously assumed to be big-endian for the purpose of getting VSCR. This patch removes this assumption to fix access to VSCR in little-endian mode. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-tdep.h (struct ppc_reg_offsets): Remove vector register offset fields. * ppc-fbsd-tdep.c (ppc32_fbsd_reg_offsets): Remove initializers for vector register offset fields. (ppc64_fbsd_reg_offsets): Likewise. * ppc-nbsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-nat.c (_initialize_ppcobsd_nat): Remove assignment to vector register offset fields. * rs6000-aix-tdep.c (rs6000_aix32_reg_offsets): Remove initializers for vector register offset fields. (rs6000_aix64_reg_offsets): Likewise. * rs6000-tdep.c (ppc_vrreg_offset): Remove. (ppc_supply_vrregset): Remove. (ppc_collect_vrregset): Remove. * ppc-linux-tdep.c (ppc_linux_collect_vrregset): New function. (ppc_linux_vrregset) : New function. (ppc32_le_linux_vrregmap, ppc32_be_linux_vrregmap) (ppc32_le_linux_vrregset, ppc32_be_linux_vrregset): New globals. (ppc32_linux_vrregset): Remove. (ppc_linux_iterate_over_regset_sections): Call ppc_linux_vrregset and use result instead of ppc32_linux_vrregset. (ppc32_linux_reg_offsets): Remove initializers for vector register offset fields. (ppc64_linux_reg_offsets): Likewise. * ppc-linux-tdep.h (ppc_linux_vrregset): New declaration. * ppc-linux-nat.c: Include regset.h. (gdb_vrregset_t): Adjust comment to account for little-endian mode. (supply_vrregset, fill_vrregset): Remove. (fetch_altivec_register, store_altivec_register): Remove. (fetch_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to supply registers. (store_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to collect registers. (fetch_register): Call fetch_altivec_registers instead of fetch_altivec_register. (store_register): Call store_altivec_registers instead of store_altivec_register. (fetch_ppc_registers): Call fetch_altivec_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_altivec_registers with -1 for the new regno parameter. gdb/gdbserver/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * linux-ppc-low.c (ppc_fill_vrregset): Add vscr_offset variable. Set vscr_offset to 0 in little-endian mode and 12 in big-endian mode. Call collect_register_by_name with vscr using vscr_offset. Zero-pad vscr and vrsave fields in collector buffer. (ppc_store_vrregset): Add and set vscr_offset variable as in ppc_fill_vrregset. Call supply_register_by_name with vscr using vscr_offset.
2018-05-22 22:09:05 +08:00
const struct regset *vrregset = ppc_linux_vrregset (gdbarch);
ret = ptrace (PTRACE_GETVRREGS, tid, 0, &regs);
if (ret < 0)
{
if (errno == EIO)
{
have_ptrace_getvrregs = 0;
return;
}
[PowerPC] Fix access to VSCR in linux targets The 4-byte VSCR register is found inside a 16-byte field in the regset returned by ptrace and in core files. The position of VSCR depends on the endianess of the target, which was previously assumed to be big-endian for the purpose of getting VSCR. This patch removes this assumption to fix access to VSCR in little-endian mode. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-tdep.h (struct ppc_reg_offsets): Remove vector register offset fields. * ppc-fbsd-tdep.c (ppc32_fbsd_reg_offsets): Remove initializers for vector register offset fields. (ppc64_fbsd_reg_offsets): Likewise. * ppc-nbsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-nat.c (_initialize_ppcobsd_nat): Remove assignment to vector register offset fields. * rs6000-aix-tdep.c (rs6000_aix32_reg_offsets): Remove initializers for vector register offset fields. (rs6000_aix64_reg_offsets): Likewise. * rs6000-tdep.c (ppc_vrreg_offset): Remove. (ppc_supply_vrregset): Remove. (ppc_collect_vrregset): Remove. * ppc-linux-tdep.c (ppc_linux_collect_vrregset): New function. (ppc_linux_vrregset) : New function. (ppc32_le_linux_vrregmap, ppc32_be_linux_vrregmap) (ppc32_le_linux_vrregset, ppc32_be_linux_vrregset): New globals. (ppc32_linux_vrregset): Remove. (ppc_linux_iterate_over_regset_sections): Call ppc_linux_vrregset and use result instead of ppc32_linux_vrregset. (ppc32_linux_reg_offsets): Remove initializers for vector register offset fields. (ppc64_linux_reg_offsets): Likewise. * ppc-linux-tdep.h (ppc_linux_vrregset): New declaration. * ppc-linux-nat.c: Include regset.h. (gdb_vrregset_t): Adjust comment to account for little-endian mode. (supply_vrregset, fill_vrregset): Remove. (fetch_altivec_register, store_altivec_register): Remove. (fetch_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to supply registers. (store_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to collect registers. (fetch_register): Call fetch_altivec_registers instead of fetch_altivec_register. (store_register): Call store_altivec_registers instead of store_altivec_register. (fetch_ppc_registers): Call fetch_altivec_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_altivec_registers with -1 for the new regno parameter. gdb/gdbserver/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * linux-ppc-low.c (ppc_fill_vrregset): Add vscr_offset variable. Set vscr_offset to 0 in little-endian mode and 12 in big-endian mode. Call collect_register_by_name with vscr using vscr_offset. Zero-pad vscr and vrsave fields in collector buffer. (ppc_store_vrregset): Add and set vscr_offset variable as in ppc_fill_vrregset. Call supply_register_by_name with vscr using vscr_offset.
2018-05-22 22:09:05 +08:00
perror_with_name (_("Unable to fetch AltiVec registers"));
}
[PowerPC] Fix access to VSCR in linux targets The 4-byte VSCR register is found inside a 16-byte field in the regset returned by ptrace and in core files. The position of VSCR depends on the endianess of the target, which was previously assumed to be big-endian for the purpose of getting VSCR. This patch removes this assumption to fix access to VSCR in little-endian mode. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-tdep.h (struct ppc_reg_offsets): Remove vector register offset fields. * ppc-fbsd-tdep.c (ppc32_fbsd_reg_offsets): Remove initializers for vector register offset fields. (ppc64_fbsd_reg_offsets): Likewise. * ppc-nbsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-nat.c (_initialize_ppcobsd_nat): Remove assignment to vector register offset fields. * rs6000-aix-tdep.c (rs6000_aix32_reg_offsets): Remove initializers for vector register offset fields. (rs6000_aix64_reg_offsets): Likewise. * rs6000-tdep.c (ppc_vrreg_offset): Remove. (ppc_supply_vrregset): Remove. (ppc_collect_vrregset): Remove. * ppc-linux-tdep.c (ppc_linux_collect_vrregset): New function. (ppc_linux_vrregset) : New function. (ppc32_le_linux_vrregmap, ppc32_be_linux_vrregmap) (ppc32_le_linux_vrregset, ppc32_be_linux_vrregset): New globals. (ppc32_linux_vrregset): Remove. (ppc_linux_iterate_over_regset_sections): Call ppc_linux_vrregset and use result instead of ppc32_linux_vrregset. (ppc32_linux_reg_offsets): Remove initializers for vector register offset fields. (ppc64_linux_reg_offsets): Likewise. * ppc-linux-tdep.h (ppc_linux_vrregset): New declaration. * ppc-linux-nat.c: Include regset.h. (gdb_vrregset_t): Adjust comment to account for little-endian mode. (supply_vrregset, fill_vrregset): Remove. (fetch_altivec_register, store_altivec_register): Remove. (fetch_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to supply registers. (store_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to collect registers. (fetch_register): Call fetch_altivec_registers instead of fetch_altivec_register. (store_register): Call store_altivec_registers instead of store_altivec_register. (fetch_ppc_registers): Call fetch_altivec_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_altivec_registers with -1 for the new regno parameter. gdb/gdbserver/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * linux-ppc-low.c (ppc_fill_vrregset): Add vscr_offset variable. Set vscr_offset to 0 in little-endian mode and 12 in big-endian mode. Call collect_register_by_name with vscr using vscr_offset. Zero-pad vscr and vrsave fields in collector buffer. (ppc_store_vrregset): Add and set vscr_offset variable as in ppc_fill_vrregset. Call supply_register_by_name with vscr using vscr_offset.
2018-05-22 22:09:05 +08:00
vrregset->collect_regset (vrregset, regcache, regno, &regs,
PPC_LINUX_SIZEOF_VRREGSET);
ret = ptrace (PTRACE_SETVRREGS, tid, 0, &regs);
if (ret < 0)
[PowerPC] Fix access to VSCR in linux targets The 4-byte VSCR register is found inside a 16-byte field in the regset returned by ptrace and in core files. The position of VSCR depends on the endianess of the target, which was previously assumed to be big-endian for the purpose of getting VSCR. This patch removes this assumption to fix access to VSCR in little-endian mode. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-tdep.h (struct ppc_reg_offsets): Remove vector register offset fields. * ppc-fbsd-tdep.c (ppc32_fbsd_reg_offsets): Remove initializers for vector register offset fields. (ppc64_fbsd_reg_offsets): Likewise. * ppc-nbsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-nat.c (_initialize_ppcobsd_nat): Remove assignment to vector register offset fields. * rs6000-aix-tdep.c (rs6000_aix32_reg_offsets): Remove initializers for vector register offset fields. (rs6000_aix64_reg_offsets): Likewise. * rs6000-tdep.c (ppc_vrreg_offset): Remove. (ppc_supply_vrregset): Remove. (ppc_collect_vrregset): Remove. * ppc-linux-tdep.c (ppc_linux_collect_vrregset): New function. (ppc_linux_vrregset) : New function. (ppc32_le_linux_vrregmap, ppc32_be_linux_vrregmap) (ppc32_le_linux_vrregset, ppc32_be_linux_vrregset): New globals. (ppc32_linux_vrregset): Remove. (ppc_linux_iterate_over_regset_sections): Call ppc_linux_vrregset and use result instead of ppc32_linux_vrregset. (ppc32_linux_reg_offsets): Remove initializers for vector register offset fields. (ppc64_linux_reg_offsets): Likewise. * ppc-linux-tdep.h (ppc_linux_vrregset): New declaration. * ppc-linux-nat.c: Include regset.h. (gdb_vrregset_t): Adjust comment to account for little-endian mode. (supply_vrregset, fill_vrregset): Remove. (fetch_altivec_register, store_altivec_register): Remove. (fetch_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to supply registers. (store_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to collect registers. (fetch_register): Call fetch_altivec_registers instead of fetch_altivec_register. (store_register): Call store_altivec_registers instead of store_altivec_register. (fetch_ppc_registers): Call fetch_altivec_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_altivec_registers with -1 for the new regno parameter. gdb/gdbserver/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * linux-ppc-low.c (ppc_fill_vrregset): Add vscr_offset variable. Set vscr_offset to 0 in little-endian mode and 12 in big-endian mode. Call collect_register_by_name with vscr using vscr_offset. Zero-pad vscr and vrsave fields in collector buffer. (ppc_store_vrregset): Add and set vscr_offset variable as in ppc_fill_vrregset. Call supply_register_by_name with vscr using vscr_offset.
2018-05-22 22:09:05 +08:00
perror_with_name (_("Unable to store AltiVec registers"));
}
[gdb] Fix more typos in comments Fix typos in comments. NFC. Tested on x86_64-linux. gdb/ChangeLog: 2019-10-18 Tom de Vries <tdevries@suse.de> * aarch64-tdep.c: Fix typos in comments. * ada-lang.c: Same. * ada-tasks.c: Same. * alpha-tdep.c: Same. * alpha-tdep.h: Same. * amd64-nat.c: Same. * amd64-windows-tdep.c: Same. * arc-tdep.c: Same. * arc-tdep.h: Same. * arch-utils.c: Same. * arm-nbsd-tdep.c: Same. * arm-tdep.c: Same. * ax-gdb.c: Same. * blockframe.c: Same. * btrace.c: Same. * c-varobj.c: Same. * coff-pe-read.c: Same. * coffread.c: Same. * cris-tdep.c: Same. * darwin-nat.c: Same. * dbxread.c: Same. * dcache.c: Same. * disasm.c: Same. * dtrace-probe.c: Same. * dwarf-index-write.c: Same. * dwarf2-frame-tailcall.c: Same. * dwarf2-frame.c: Same. * dwarf2read.c: Same. * eval.c: Same. * exceptions.c: Same. * fbsd-tdep.c: Same. * findvar.c: Same. * frame.c: Same. * frv-tdep.c: Same. * gnu-v3-abi.c: Same. * go32-nat.c: Same. * h8300-tdep.c: Same. * hppa-tdep.c: Same. * i386-linux-tdep.c: Same. * i386-tdep.c: Same. * ia64-libunwind-tdep.c: Same. * ia64-tdep.c: Same. * infcmd.c: Same. * infrun.c: Same. * linespec.c: Same. * linux-nat.c: Same. * linux-thread-db.c: Same. * machoread.c: Same. * mdebugread.c: Same. * mep-tdep.c: Same. * mn10300-tdep.c: Same. * namespace.c: Same. * objfiles.c: Same. * opencl-lang.c: Same. * or1k-tdep.c: Same. * osabi.c: Same. * ppc-linux-nat.c: Same. * ppc-linux-tdep.c: Same. * ppc-sysv-tdep.c: Same. * printcmd.c: Same. * procfs.c: Same. * record-btrace.c: Same. * record-full.c: Same. * remote-fileio.c: Same. * remote.c: Same. * rs6000-tdep.c: Same. * s12z-tdep.c: Same. * score-tdep.c: Same. * ser-base.c: Same. * ser-go32.c: Same. * skip.c: Same. * sol-thread.c: Same. * solib-svr4.c: Same. * solib.c: Same. * source.c: Same. * sparc-nat.c: Same. * sparc-sol2-tdep.c: Same. * sparc-tdep.c: Same. * sparc64-tdep.c: Same. * stabsread.c: Same. * stack.c: Same. * symfile.c: Same. * symtab.c: Same. * target-descriptions.c: Same. * target-float.c: Same. * thread.c: Same. * utils.c: Same. * valops.c: Same. * valprint.c: Same. * value.c: Same. * varobj.c: Same. * windows-nat.c: Same. * xcoffread.c: Same. * xstormy16-tdep.c: Same. * xtensa-tdep.c: Same. Change-Id: I5175f1b107bfa4e1cdd4a3361ccb4739e53c75c4
2019-10-18 08:48:08 +08:00
/* Assuming TID refers to an SPE process, set the top halves of TID's
general-purpose registers and its SPE-specific registers to the
values in EVRREGSET. If we don't support PTRACE_SETEVRREGS, do
nothing.
All the logic to deal with whether or not the PTRACE_GETEVRREGS and
PTRACE_SETEVRREGS requests are supported is isolated here, and in
get_spe_registers. */
static void
set_spe_registers (int tid, struct gdb_evrregset_t *evrregset)
{
if (have_ptrace_getsetevrregs)
{
if (ptrace (PTRACE_SETEVRREGS, tid, 0, evrregset) >= 0)
return;
else
{
/* EIO means that the PTRACE_SETEVRREGS request isn't
supported; we fail silently, and don't try the call
again. */
if (errno == EIO)
have_ptrace_getsetevrregs = 0;
else
/* Anything else needs to be reported. */
2005-02-11 Andrew Cagney <cagney@gnu.org> Mark up error_no_arg, query, perror_with_name, complaint, and internal_error. * breakpoint.c, cp-abi.c, cp-namespace.c, cp-support.c: Update. * cris-tdep.c, dbxread.c, dictionary.c, dsrec.c: Update. * dummy-frame.c, dve3900-rom.c, dwarf2-frame.c, dwarf2expr.c: Update. * dwarf2read.c, dwarfread.c, elfread.c, event-loop.c: Update. * exceptions.c, exec.c, f-lang.c, findvar.c, fork-child.c: Update. * frame-unwind.c, frame.c, frv-linux-tdep.c, frv-tdep.c: Update. * gdb_assert.h, gdbarch.c, gdbtypes.c, gnu-nat.c: Update. * go32-nat.c, hppa-tdep.c, hppabsd-nat.c, hpread.c: Update. * i386-linux-nat.c, i386-nat.c, i386-tdep.c, i386bsd-nat.c: Update. * i386fbsd-nat.c, inf-ptrace.c, inf-ttrace.c, infcall.c: Update. * infcmd.c, inflow.c, infptrace.c, infrun.c, inftarg.c: Update. * interps.c, language.c, linespec.c, linux-nat.c: Update. * m32r-linux-nat.c, m68k-tdep.c, m68kbsd-nat.c: Update. * m68klinux-nat.c, m88kbsd-nat.c, macroexp.c, macroscope.c: Update. * macrotab.c, maint.c, mdebugread.c, memattr.c: Update. * mips-linux-tdep.c, mips-tdep.c, mips64obsd-nat.c: Update. * mipsnbsd-nat.c, mn10300-tdep.c, monitor.c, nto-procfs.c: Update. * objc-lang.c, objfiles.c, objfiles.h, ocd.c, osabi.c: Update. * parse.c, ppc-bdm.c, ppc-linux-nat.c, ppc-sysv-tdep.c: Update. * ppcnbsd-nat.c, ppcobsd-nat.c, printcmd.c, procfs.c: Update. * regcache.c, reggroups.c, remote-e7000.c, remote-mips.c: Update. * remote-rdp.c, remote-sds.c, remote-sim.c, remote-st.c: Update. * remote-utils.c, remote.c, rs6000-nat.c, rs6000-tdep.c: Update. * s390-nat.c, s390-tdep.c, sentinel-frame.c, serial.c: Update. * sh-tdep.c, sh3-rom.c, sh64-tdep.c, shnbsd-nat.c: Update. * solib-aix5.c, solib-svr4.c, solib.c, source.c: Update. * sparc-nat.c, stabsread.c, stack.c, symfile.c, symtab.c: Update. * symtab.h, target.c, tracepoint.c, ui-file.c, ui-out.c: Update. * utils.c, valops.c, valprint.c, vax-nat.c, vaxbsd-nat.c: Update. * win32-nat.c, xcoffread.c, xstormy16-tdep.c: Update. * cli/cli-cmds.c, cli/cli-logging.c, cli/cli-script.c: Update. * cli/cli-setshow.c, mi/mi-cmd-break.c, mi/mi-cmds.c: Update. * mi/mi-console.c, mi/mi-getopt.c, mi/mi-out.c: Update. * tui/tui-file.c, tui/tui-interp.c: Update.
2005-02-12 02:13:55 +08:00
perror_with_name (_("Unable to set SPE registers"));
}
}
}
Change the layout of the PowerPC E500 raw register cache to allow the lower 32-bit halves of the GPRS to be their own raw registers, not pseudoregisters. * ppc-tdep.h (struct gdbarch_tdep): Remove ppc_gprs_pseudo_p flag; add ppc_ev0_upper_regnum flag. * rs6000-tdep.c: #include "reggroups.h". (spe_register_p): Recognize the ev upper half registers as SPE registers. (init_sim_regno_table): Build gdb->sim mappings for the upper-half registers. (e500_move_ev_register): New function. (e500_pseudo_register_read, e500_pseudo_register_write): The 'ev' vector registers are the pseudo-registers now, formed by splicing together the gprs and the upper-half registers. (e500_register_reggroup_p): New function. (P): Macro deleted. (P8, A4): New macro. (PPC_EV_REGS, PPC_GPRS_PSEUDO_REGS): Macros deleted. (PPC_SPE_GP_REGS, PPC_SPE_UPPER_GP_REGS, PPC_EV_PSEUDO_REGS): New macros. (registers_e500): Rearrange register set so that the raw register set contains 32-bit GPRs and upper-half registers, and the SPE vector registers become pseudo-registers. (rs6000_gdbarch_init): Don't initialize tdep->ppc_gprs_pseudo_p; it has been deleted. Initialize ppc_ev0_upper_regnum. Many other register numbers are now the same for the E500 as they are for other PowerPC variants. Register e500_register_reggroup_p as the register group function for the E500. * Makefile.in (rs6000-tdep.o): Update dependencies. Adapt PPC E500 native support to the new raw regcache layout. * ppc-linux-nat.c (struct gdb_evrregset_t): Doc fixes. (read_spliced_spe_reg, write_spliced_spe_reg): Deleted. (fetch_spe_register, store_spe_register): Handle fetching/storing all the SPE registers at once, if regno == -1. These now take over the job of fetch_spe_registers and store_spe_registers. (fetch_spe_registers, store_spe_registers): Deleted. (fetch_ppc_registers, store_ppc_registers): Fetch/store gprs unconditionally; they're always raw. Fetch/store SPE upper half registers, if present, instead of ev registers. (fetch_register, store_register): Remove sanity checks: gprs are never pseudo-registers now, so we never need to even mention any registers that are ever pseudoregisters.
2004-08-05 01:17:55 +08:00
/* Write GDB's value for the SPE-specific raw register REGNO to TID.
If REGNO is -1, write the values of all the SPE-specific
registers. */
static void
* target.h (struct regcache): Add forward declaration. (struct target_ops): Add REGCACHE parameter to to_fetch_registers and to_store_registers target operations. (target_fetch_registers, target_store_registers): Update. * regcache.c (regcache_raw_read): Replace register_cached by regcache_valid_p. Pass regcache to target_fetch_registers. (regcache_raw_write): Pass regcache to target_store_registers. * arm-linux-nat.c (store_fpregister, store_fpregs, store_register, store_regs, store_wmmx_regs): Replace register_cached by regcache_valid_p. * bsd-kvm.c (bsd_kvm_open, bsd_kvm_proc_cmd): Pass current_regcache to target_fetch_registers calls. * corelow.c (core_open): Likewise. * linux-nat.c (linux_nat_corefile_thread_callback): Likewise. * proc-service.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * sol-thread.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * win32-nat.c (win32_resume): Likewise. * ia64-tdep.c (ia64_store_return_value): Pass current_regcache to target_store_registers call. * rs6000-tdep.c (rs6000_push_dummy_call): Likewise. * inferior.h (store_inferior_registers): Update prototype. (fetch_inferior_registers): Likewise. * gnu-nat.c (gnu_store_registers, gnu_fetch_registers): Likewise. * mips-linux-nat.c (super_fetch_registers, super_store_registers): Update function pointer signatures. * aix-thread.c (aix_thread_fetch_registers): Add REGCACHE parameter, use it instead of current_regcache, update calls. (aix_thread_store_registers): Likewise. * alphabsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * amd64bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_fpregister, fetch_fpregs, store_fpregister, store_fpregs, fetch_register, fetch_regs, store_register, store_regs, fetch_wmmx_regs, store_wmmx_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * armnbsd-nat.c (fetch_register, fetch_regs, fetch_fp_register, fetch_fp_regs, armnbsd_fetch_registers): Likewise. (store_register, store_regs, store_fp_register, store_fp_regs, armnbsd_store_registers): Likewise. * bsd-kvm.c (bsd_kvm_fetch_pcb, bsd_kvm_fetch_registers): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * corelow.c (get_core_registers): Likewise. * go32-nat.c (fetch_register, go32_fetch_registers, store_register, go32_store_registers): Likewise. * hppabsd-nat.c (hppabsd_fetch_registers): Likewise. (hppabsd_store_registers): Likewise. * hppa-hpux-nat.c (hppa_hpux_fetch_register): Likewise. (hppa_hpux_fetch_inferior_registers): Likewise. (hppa_hpux_store_register): Likewise. (hppa_hpux_store_inferior_registers): Likewise. * hppa-linux-nat.c (fetch_register, store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * hpux-thread.c (hpux_thread_fetch_registers): Likewise. (hpux_thread_store_registers): Likewise. * i386bsd-nat.c (i386bsd_fetch_inferior_registers): Likewise. (i386bsd_store_inferior_registers): Likewise. * i386gnu-nat.c (fetch_fpregs, gnu_fetch_registers, store_fpregs, gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register, store_register, fetch_regs, store_regs, fetch_fpregs, store_fpregs, fetch_fpxregs, store_fpxregs): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_register): Likewise. (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_register): Likewise. (ia64_linux_store_registers): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. (inf_child_store_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register): Likewise. (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_register): Likewise. (inf_ptrace_store_registers): Likewise. * infptrace.c (fetch_register, store_register): Likewise. (fetch_inferior_registers, store_inferior_registers): Likewise. * m32r-linux-nat.c (fetch_regs, store_regs): Likewise. (m32r_linux_fetch_inferior_registers): Likewise. (m32r_linux_store_inferior_registers): Likewise. * m68kbsd-nat.c (m68kbsd_fetch_inferior_registers): Likewise. (m68kbsd_store_inferior_registers): Likewise. * m68klinux-nat.c (fetch_register, old_fetch_inferior_registers, store_register, old_store_inferior_registers, fetch_regs, store_regs, fetch_fpregs, store_fpregs): Likewise. (m68k_linux_fetch_inferior_registers): Likewise. (m68k_linux_store_inferior_registers): Likewise. * m88kbsd-nat.c (m88kbsd_fetch_inferior_registers): Likewise. (m88kbsd_store_inferior_registers): Likewise. * mips64obsd-nat.c (mips64obsd_fetch_inferior_registers): Likewise. (mips64obsd_store_inferior_registers): Likewise. * mips-linux-nat.c (mips64_linux_regsets_fetch_registers): Likewise. (mips64_linux_regsets_store_registers): Likewise. (mips64_linux_fetch_registers): Likewise. (mips64_linux_store_registers): Likewise. * mipsnbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * monitor.c (monitor_fetch_register, monitor_store_register): Likewise. (monitor_fetch_registers, monitor_store_registers): Likewise. * nto-procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register, fetch_register, supply_vrregset, fetch_altivec_registers, fetch_ppc_registers, ppc_linux_fetch_inferior_registers): Likewise. (store_altivec_register, store_spe_register, store_register, fill_vrregset, store_altivec_registers, store_ppc_registers, ppc_linux_store_inferior_registers): Likewise. * ppcnbsd-nat.c (ppcnbsd_fetch_inferior_registers): Likewise. (ppcnbsd_store_inferior_registers): Likewise. * ppcobsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote.c (fetch_register_using_p, process_g_packet, fetch_registers_using_g, remote_fetch_registers): Likewise. (store_register_using_P, store_registers_using_G, remote_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers, m32r_fetch_register, m32r_store_register, m32r_store_register): Likewise. * remote-mips.c (mips_fetch_registers, mips_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * rs6000-nat.c (fetch_register, store_register): Likewise. (rs6000_fetch_inferior_registers): Likewise. (rs6000_store_inferior_registers): Likewise. * s390-nat.c (fetch_regs, store_regs): Likewise. (fetch_fpregs, store_fpregs): Likewise. (s390_linux_fetch_inferior_registers): Likewise. (s390_linux_store_inferior_registers): Likewise. * shnbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sol-thread.c (sol_thread_fetch_registers): Likewise. (sol_thread_store_registers): Likewise. * sparc-nat.c (fetch_inferior_registers): Likewise. (store_inferior_registers): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. (spu_store_inferior_registers): Likewise. * target.c (debug_print_register): Likewise. (debug_to_fetch_registers, debug_to_store_registers): Likewise. * vaxbsd-nat.c (vaxbsd_fetch_inferior_registers): Likewise. (vaxbsd_store_inferior_registers): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers): Likewise. (win32_fetch_inferior_registers): Likewise. (win32_store_inferior_registers): Likewise.
2007-05-06 22:34:38 +08:00
store_spe_register (const struct regcache *regcache, int tid, int regno)
{
s/get_regcache_arch (regcache)/regcache->arch ()/g This patches removes get_regcache_arch, and use regache->arch () instead. The motivation of this change is that I am going to move some basic stuff into a base class of regcache. I don't need to update "client" code regcache->arch (). On the other hand, this patch shortens the code a little bit. gdb: 2017-10-25 Yao Qi <yao.qi@linaro.org> * aarch32-linux-nat.c (aarch32_gp_regcache_supply): Use regcache->arch () instead get_regcache_arch. * aarch64-fbsd-nat.c (aarch64_fbsd_fetch_inferior_registers): Likewise. (aarch64_fbsd_store_inferior_registers): Likewise. * aarch64-linux-nat.c (fetch_gregs_from_thread): Likewise. (store_gregs_to_thread): Likewise. (fetch_fpregs_from_thread): Likewise. (store_fpregs_to_thread): Likewise. * aarch64-tdep.c (aarch64_extract_return_value): Likewise. (aarch64_store_return_value): Likewise. (aarch64_software_single_step): Likewise. * aix-thread.c (aix_thread_wait): Likewise. (supply_reg32): Likewise. (supply_sprs64): Likewise. (supply_sprs32): Likewise. (fill_gprs64): Likewise. (fill_gprs32): Likewise. (fill_sprs64): Likewise. (fill_sprs32): Likewise. (store_regs_user_thread): Likewise. (store_regs_kernel_thread): Likewise. * alpha-bsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * alpha-tdep.c (alpha_extract_return_value): Likewise. (alpha_store_return_value): Likewise. (alpha_deal_with_atomic_sequence): Likewise. (alpha_next_pc): Likewise. (alpha_software_single_step): Likewise. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * amd64-nat.c (amd64_supply_native_gregset): Likewise. (amd64_collect_native_gregset): Likewise. * amd64-obsd-tdep.c (amd64obsd_supply_uthread): Likewise. (amd64obsd_collect_uthread): Likewise. * amd64-tdep.c (amd64_supply_fpregset): Likewise. (amd64_collect_fpregset): Likewise. (amd64_supply_fxsave): Likewise. (amd64_supply_xsave): Likewise. (amd64_collect_fxsave): Likewise. (amd64_collect_xsave): Likewise. * arc-tdep.c (arc_write_pc): Likewise. * arch-utils.c (default_skip_permanent_breakpoint): Likewise. * arm-fbsd-nat.c (arm_fbsd_fetch_inferior_registers): Likewise. (arm_fbsd_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_vfp_regs): Likewise. (store_vfp_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * arm-linux-tdep.c (arm_linux_supply_gregset): Likewise. (arm_linux_sigreturn_next_pc): Likewise. (arm_linux_get_next_pcs_syscall_next_pc): Likewise. * arm-nbsd-nat.c (arm_supply_gregset): Likewise. (fetch_register): Likewise. (store_register): Likewise. * arm-tdep.c (arm_is_thumb): Likewise. (displaced_in_arm_mode): Likewise. (bx_write_pc): Likewise. (arm_get_next_pcs_addr_bits_remove): Likewise. (arm_software_single_step): Likewise. (arm_extract_return_value): Likewise. (arm_store_return_value): Likewise. (arm_write_pc): Likewise. * bfin-tdep.c (bfin_extract_return_value): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * core-regset.c (fetch_core_registers): Likewise. * corelow.c (get_core_registers): Likewise. * cris-tdep.c (cris_store_return_value): Likewise. (cris_extract_return_value): Likewise. (find_step_target): Likewise. (find_step_target): Likewise. (cris_software_single_step): Likewise. * ctf.c (ctf_fetch_registers): Likewise. * darwin-nat.c (cancel_breakpoint): Likewise. * fbsd-tdep.c (fbsd_collect_thread_registers): Likewise. * frv-tdep.c (frv_extract_return_value): Likewise. * ft32-tdep.c (ft32_store_return_value): Likewise. (ft32_extract_return_value): Likewise. * go32-nat.c (fetch_register): Likewise. (go32_fetch_registers): Likewise. (go32_store_registers): Likewise. (store_register): Likewise. * h8300-tdep.c (h8300_extract_return_value): Likewise. (h8300_store_return_value): Likewise. * hppa-linux-nat.c (fetch_register): Likewise. (store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * i386-darwin-nat.c (i386_darwin_fetch_inferior_registers): Likewise. (i386_darwin_store_inferior_registers): Likewise. * i386-gnu-nat.c (gnu_fetch_registers): Likewise. (gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register): Likewise. (store_register): Likewise. (supply_gregset): Likewise. (fill_gregset): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. (i386_linux_resume): Likewise. * i386-linux-tdep.c (i386_linux_get_syscall_number_from_regcache): Likewise. * i386-nto-tdep.c (i386nto_supply_gregset): Likewise. * i386-obsd-nat.c (i386obsd_supply_pcb): Likewise. * i386-obsd-tdep.c (i386obsd_supply_uthread): Likewise. (i386obsd_collect_uthread): Likewise. * i386-tdep.c (i386_mmx_regnum_to_fp_regnum): Likewise. (i386_supply_gregset): Likewise. (i386_collect_gregset): Likewise. (i386_supply_fpregset): Likewise. (i386_collect_fpregset): Likewise. (i386_mpx_bd_base): Likewise. * i386-v4-nat.c (supply_fpregset): Likewise. (fill_fpregset): Likewise. * i387-tdep.c (i387_supply_fsave): Likewise. (i387_collect_fsave): Likewise. (i387_supply_fxsave): Likewise. (i387_collect_fxsave): Likewise. (i387_supply_xsave): Likewise. (i387_collect_xsave): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_registers): Likewise. * ia64-tdep.c (ia64_access_rse_reg): Likewise. (ia64_extract_return_value): Likewise. (ia64_store_return_value): Likewise. (find_func_descr): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_registers): Likewise. * infrun.c (use_displaced_stepping): Likewise. (displaced_step_prepare_throw): Likewise. (resume): Likewise. (proceed): Likewise. (do_target_wait): Likewise. (adjust_pc_after_break): Likewise. (handle_inferior_event_1): Likewise. (handle_signal_stop): Likewise. (save_infcall_suspend_state): Likewise. (restore_infcall_suspend_state): Likewise. * iq2000-tdep.c (iq2000_extract_return_value): Likewise. * jit.c (jit_frame_prev_register): Likewise. * linux-nat.c (save_stop_reason): Likewise. (linux_nat_wait_1): Likewise. (resume_stopped_resumed_lwps): Likewise. * linux-record.c (record_linux_sockaddr): Likewise. (record_linux_msghdr): Likewise. (record_linux_system_call): Likewise. * linux-tdep.c (linux_collect_thread_registers): Likewise. * lm32-tdep.c (lm32_extract_return_value): Likewise. (lm32_store_return_value): Likewise. * m32c-tdep.c (m32c_read_flg): Likewise. (m32c_pseudo_register_read): Likewise. (m32c_pseudo_register_write): Likewise. * m32r-linux-tdep.c (m32r_linux_supply_gregset): Likewise. (m32r_linux_collect_gregset): Likewise. * m32r-tdep.c (m32r_store_return_value): Likewise. (m32r_extract_return_value): Likewise. * m68k-bsd-nat.c (m68kbsd_supply_fpregset): Likewise. (m68kbsd_collect_fpregset): Likewise. * m68k-bsd-tdep.c (m68kbsd_supply_fpregset): Likewise. * m68k-linux-nat.c (fetch_register): Likewise. (old_fetch_inferior_registers): Likewise. (old_store_inferior_registers): Likewise. (store_regs): Likewise. * m68k-tdep.c (m68k_svr4_extract_return_value): Likewise. (m68k_svr4_store_return_value): Likewise. * m88k-tdep.c (m88k_store_arguments): Likewise. * mi/mi-main.c (mi_cmd_data_list_changed_registers): Likewise. (mi_cmd_data_write_register_values): Likewise. * mips-fbsd-nat.c (mips_fbsd_fetch_inferior_registers): Likewise. (mips_fbsd_store_inferior_registers): Likewise. * mips-fbsd-tdep.c (mips_fbsd_supply_fpregs): Likewise. (mips_fbsd_supply_gregs): Likewise. (mips_fbsd_collect_fpregs): Likewise. (mips_fbsd_collect_gregs): Likewise. (mips_fbsd_supply_fpregset): Likewise. (mips_fbsd_collect_fpregset): Likewise. (mips_fbsd_supply_gregset): Likewise. (mips_fbsd_collect_gregset): Likewise. * mips-linux-nat.c (supply_gregset): Likewise. (fill_gregset): Likewise. (supply_fpregset): Likewise. (fill_fpregset): Likewise. * mips-linux-tdep.c (mips_supply_gregset): Likewise. (mips_fill_gregset): Likewise. (mips_supply_fpregset): Likewise. (mips_fill_fpregset): Likewise. (mips64_supply_gregset): Likewise. (micromips_linux_sigframe_validate): Likewise. * mips-nbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * mips-nbsd-tdep.c (mipsnbsd_supply_fpregset): Likewise. (mipsnbsd_supply_gregset): Likewise. (mipsnbsd_iterate_over_regset_sections): Likewise. (mipsnbsd_supply_reg): Likewise. (mipsnbsd_supply_fpreg): Likewise. * mips-tdep.c (mips_in_frame_stub): Likewise. (mips_dummy_id): Likewise. (is_octeon_bbit_op): Likewise. (micromips_bc1_pc): Likewise. (extended_mips16_next_pc): Likewise. (mips16_next_pc): Likewise. (deal_with_atomic_sequence): Likewise. * moxie-tdep.c (moxie_process_readu): Likewise. * nios2-tdep.c (nios2_get_next_pc): Likewise. * nto-procfs.c (procfs_store_registers): Likewise. * ppc-fbsd-nat.c (ppcfbsd_fetch_inferior_registers): Likewise. (ppcfbsd_store_inferior_registers): Likewise. * ppc-linux-nat.c (fetch_vsx_register): Likewise. (fetch_altivec_register): Likewise. (get_spe_registers): Likewise. (fetch_spe_register): Likewise. (fetch_altivec_registers): Likewise. (fetch_all_gp_regs): Likewise. (fetch_all_fp_regs): Likewise. (store_vsx_register): Likewise. (store_altivec_register): Likewise. (set_spe_registers): Likewise. (store_spe_register): Likewise. (store_altivec_registers): Likewise. (store_all_gp_regs): Likewise. (store_all_fp_regs): Likewise. * ppc-linux-tdep.c (ppc_linux_supply_gregset): Likewise. (ppc_linux_collect_gregset): Likewise. (ppc_canonicalize_syscall): Likewise. (ppc_linux_record_signal): Likewise. (ppu2spu_prev_register): Likewise. * ppc-nbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-obsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * ppc-ravenscar-thread.c (ppc_ravenscar_generic_fetch_registers): Likewise. (ppc_ravenscar_generic_store_registers): Likewise. * procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ravenscar-thread.c (ravenscar_fetch_registers): Likewise. (ravenscar_store_registers): Likewise. (ravenscar_prepare_to_store): Likewise. * record-btrace.c (record_btrace_fetch_registers): Likewise. * record-full.c (record_full_wait_1): Likewise. (record_full_registers_change): Likewise. (record_full_store_registers): Likewise. (record_full_core_fetch_registers): Likewise. (record_full_save): Likewise. (record_full_goto_insn): Likewise. * regcache.c (regcache_register_size): Likewise. (get_regcache_arch): Remove. (regcache_read_pc): Likewise. * regcache.h (get_regcache_arch): Remove. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * remote.c (fetch_register_using_p): Likewise. (send_g_packet): Likewise. (remote_prepare_to_store): Likewise. (store_registers_using_G): Likewise. * reverse.c (save_bookmark_command): Likewise. (goto_bookmark_command): Likewise. * rs6000-aix-tdep.c (branch_dest): Likewise. * rs6000-nat.c (rs6000_ptrace64): Likewise. (fetch_register): Likewise. * rs6000-tdep.c (ppc_supply_reg): Likewise. (ppc_collect_reg): Likewise. (ppc_collect_gregset): Likewise. (ppc_collect_fpregset): Likewise. (ppc_collect_vsxregset): Likewise. (ppc_collect_vrregset): Likewise. (ppc_displaced_step_hw_singlestep): Likewise. (rs6000_pseudo_register_read): Likewise. (rs6000_pseudo_register_write): Likewise. * s390-linux-nat.c (supply_gregset): Likewise. (fill_gregset): Likewise. (s390_linux_fetch_inferior_registers): Likewise. * s390-linux-tdep.c (s390_write_pc): Likewise. (s390_software_single_step): Likewise. (s390_all_but_pc_registers_record): Likewise. (s390_linux_syscall_record): Likewise. * sentinel-frame.c (sentinel_frame_prev_arch): Likewise. * sh-nbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sh-tdep.c (sh_extract_return_value_nofpu): Likewise. (sh_extract_return_value_fpu): Likewise. (sh_store_return_value_nofpu): Likewise. (sh_corefile_supply_regset): Likewise. (sh_corefile_collect_regset): Likewise. * sh64-tdep.c (sh64_extract_return_value): Likewise. (sh64_store_return_value): Likewise. * sparc-linux-tdep.c (sparc32_linux_collect_core_fpregset): Likewise. * sparc-nat.c (sparc_fetch_inferior_registers): Likewise. (sparc_store_inferior_registers): Likewise. * sparc-ravenscar-thread.c (register_in_thread_descriptor_p): Likewise. (sparc_ravenscar_prepare_to_store): Likewise. * sparc-tdep.c (sparc32_store_arguments): Likewise. (sparc_analyze_control_transfer): Likewise. (sparc_step_trap): Likewise. (sparc_software_single_step): Likewise. (sparc32_gdbarch_init): Likewise. (sparc_supply_rwindow): Likewise. (sparc_collect_rwindow): Likewise. * sparc64-linux-tdep.c (sparc64_linux_collect_core_fpregset): Likewise. * sparc64-nbsd-nat.c (sparc64nbsd_supply_gregset): Likewise. (sparc64nbsd_collect_gregset): Likewise. (sparc64nbsd_supply_fpregset): Likewise. (sparc64nbsd_collect_fpregset): Likewise. * sparc64-tdep.c (sparc64_store_arguments): Likewise. (sparc64_supply_gregset): Likewise. (sparc64_collect_gregset): Likewise. (sparc64_supply_fpregset): Likewise. (sparc64_collect_fpregset): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. * spu-tdep.c (spu_unwind_sp): Likewise. (spu2ppu_prev_register): Likewise. (spu_memory_remove_breakpoint): Likewise. * stack.c (return_command): Likewise. * tic6x-tdep.c (tic6x_extract_signed_field): Likewise. * tracefile-tfile.c (tfile_fetch_registers): Likewise. * tracefile.c (trace_save_ctf): Likewise. * windows-nat.c (do_windows_fetch_inferior_registers): Likewise. (do_windows_store_inferior_registers): Likewise. (windows_resume): Likewise. * xtensa-linux-nat.c (fill_gregset): Likewise. (supply_gregset_reg): Likewise. * xtensa-tdep.c (xtensa_register_write_masked): Likewise. (xtensa_register_read_masked): Likewise. (xtensa_supply_gregset): Likewise. (xtensa_extract_return_value): Likewise. (xtensa_store_return_value): Likewise.
2017-10-25 23:37:03 +08:00
struct gdbarch *gdbarch = regcache->arch ();
2007-11-16 Markus Deuling <deuling@de.ibm.com> * m32r-rom.c (m32r_supply_register): Use get_regcache_arch to get at the current architecture by regcache. * ppcnbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register) (fetch_register, supply_vrregset, fetch_ppc_registers) (store_altivec_register, store_spe_register, store_register) (fill_vrregset, store_ppc_registers): Likewise. * ppcobsd-nat.c (ppcobsd_supply_pcb): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers) (do_win32_store_inferior_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers) (m32r_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register, gdbsim_store_register): Likewise. * trad-frame.c (trad_frame_alloc_saved_regs): Replace current_gdbarch by gdbarch. * user-regs.c (user_reg_map_name_to_regnum): Likewise. * ppc-sysv-tdep.c (ppc_sysv_abi_push_dummy_call) (do_ppc_sysv_return_value, ppc64_sysv_abi_push_dummy_call) (ppc64_sysv_abi_return_value): Likewise. * m32c-tdep.c (m32c_register_reggroup_p): Likewise. * m2-lang.c (build_m2_types): Likewise. * ppc-linux-tdep.c (ppc_linux_sigtramp_cache * ppcnbsd-tdep.c (ppcnbsd_sigtramp_cache_init): Likewise. * ppcobsd-tdep.c (ppcobsd_sigtramp_frame_cache): Likewise. * rs6000-tdep.c (ppc_dwarf2_frame_init_reg): Likewise. * m68hc11-tdep.c (m68hc11_frame_unwind_cache): Use get_frame_arch to get at the current architecture by frame_info. * gcore.c (derive_stack_segment): Likewise. * shnbsd-nat.c (GETREGS_SUPPLIES): Add gdbarch parameter. (shnbsd_fetch_inferior_registers, shnbsd_store_inferior_registers): Add gdbarch to GETREGS_SUPPLIES call.
2007-11-16 12:53:46 +08:00
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
struct gdb_evrregset_t evrregs;
Change the layout of the PowerPC E500 raw register cache to allow the lower 32-bit halves of the GPRS to be their own raw registers, not pseudoregisters. * ppc-tdep.h (struct gdbarch_tdep): Remove ppc_gprs_pseudo_p flag; add ppc_ev0_upper_regnum flag. * rs6000-tdep.c: #include "reggroups.h". (spe_register_p): Recognize the ev upper half registers as SPE registers. (init_sim_regno_table): Build gdb->sim mappings for the upper-half registers. (e500_move_ev_register): New function. (e500_pseudo_register_read, e500_pseudo_register_write): The 'ev' vector registers are the pseudo-registers now, formed by splicing together the gprs and the upper-half registers. (e500_register_reggroup_p): New function. (P): Macro deleted. (P8, A4): New macro. (PPC_EV_REGS, PPC_GPRS_PSEUDO_REGS): Macros deleted. (PPC_SPE_GP_REGS, PPC_SPE_UPPER_GP_REGS, PPC_EV_PSEUDO_REGS): New macros. (registers_e500): Rearrange register set so that the raw register set contains 32-bit GPRs and upper-half registers, and the SPE vector registers become pseudo-registers. (rs6000_gdbarch_init): Don't initialize tdep->ppc_gprs_pseudo_p; it has been deleted. Initialize ppc_ev0_upper_regnum. Many other register numbers are now the same for the E500 as they are for other PowerPC variants. Register e500_register_reggroup_p as the register group function for the E500. * Makefile.in (rs6000-tdep.o): Update dependencies. Adapt PPC E500 native support to the new raw regcache layout. * ppc-linux-nat.c (struct gdb_evrregset_t): Doc fixes. (read_spliced_spe_reg, write_spliced_spe_reg): Deleted. (fetch_spe_register, store_spe_register): Handle fetching/storing all the SPE registers at once, if regno == -1. These now take over the job of fetch_spe_registers and store_spe_registers. (fetch_spe_registers, store_spe_registers): Deleted. (fetch_ppc_registers, store_ppc_registers): Fetch/store gprs unconditionally; they're always raw. Fetch/store SPE upper half registers, if present, instead of ev registers. (fetch_register, store_register): Remove sanity checks: gprs are never pseudo-registers now, so we never need to even mention any registers that are ever pseudoregisters.
2004-08-05 01:17:55 +08:00
gdb_assert (sizeof (evrregs.evr[0])
2007-11-16 Markus Deuling <deuling@de.ibm.com> * m32r-rom.c (m32r_supply_register): Use get_regcache_arch to get at the current architecture by regcache. * ppcnbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register) (fetch_register, supply_vrregset, fetch_ppc_registers) (store_altivec_register, store_spe_register, store_register) (fill_vrregset, store_ppc_registers): Likewise. * ppcobsd-nat.c (ppcobsd_supply_pcb): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers) (do_win32_store_inferior_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers) (m32r_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register, gdbsim_store_register): Likewise. * trad-frame.c (trad_frame_alloc_saved_regs): Replace current_gdbarch by gdbarch. * user-regs.c (user_reg_map_name_to_regnum): Likewise. * ppc-sysv-tdep.c (ppc_sysv_abi_push_dummy_call) (do_ppc_sysv_return_value, ppc64_sysv_abi_push_dummy_call) (ppc64_sysv_abi_return_value): Likewise. * m32c-tdep.c (m32c_register_reggroup_p): Likewise. * m2-lang.c (build_m2_types): Likewise. * ppc-linux-tdep.c (ppc_linux_sigtramp_cache * ppcnbsd-tdep.c (ppcnbsd_sigtramp_cache_init): Likewise. * ppcobsd-tdep.c (ppcobsd_sigtramp_frame_cache): Likewise. * rs6000-tdep.c (ppc_dwarf2_frame_init_reg): Likewise. * m68hc11-tdep.c (m68hc11_frame_unwind_cache): Use get_frame_arch to get at the current architecture by frame_info. * gcore.c (derive_stack_segment): Likewise. * shnbsd-nat.c (GETREGS_SUPPLIES): Add gdbarch parameter. (shnbsd_fetch_inferior_registers, shnbsd_store_inferior_registers): Add gdbarch to GETREGS_SUPPLIES call.
2007-11-16 12:53:46 +08:00
== register_size (gdbarch, tdep->ppc_ev0_upper_regnum));
Change the layout of the PowerPC E500 raw register cache to allow the lower 32-bit halves of the GPRS to be their own raw registers, not pseudoregisters. * ppc-tdep.h (struct gdbarch_tdep): Remove ppc_gprs_pseudo_p flag; add ppc_ev0_upper_regnum flag. * rs6000-tdep.c: #include "reggroups.h". (spe_register_p): Recognize the ev upper half registers as SPE registers. (init_sim_regno_table): Build gdb->sim mappings for the upper-half registers. (e500_move_ev_register): New function. (e500_pseudo_register_read, e500_pseudo_register_write): The 'ev' vector registers are the pseudo-registers now, formed by splicing together the gprs and the upper-half registers. (e500_register_reggroup_p): New function. (P): Macro deleted. (P8, A4): New macro. (PPC_EV_REGS, PPC_GPRS_PSEUDO_REGS): Macros deleted. (PPC_SPE_GP_REGS, PPC_SPE_UPPER_GP_REGS, PPC_EV_PSEUDO_REGS): New macros. (registers_e500): Rearrange register set so that the raw register set contains 32-bit GPRs and upper-half registers, and the SPE vector registers become pseudo-registers. (rs6000_gdbarch_init): Don't initialize tdep->ppc_gprs_pseudo_p; it has been deleted. Initialize ppc_ev0_upper_regnum. Many other register numbers are now the same for the E500 as they are for other PowerPC variants. Register e500_register_reggroup_p as the register group function for the E500. * Makefile.in (rs6000-tdep.o): Update dependencies. Adapt PPC E500 native support to the new raw regcache layout. * ppc-linux-nat.c (struct gdb_evrregset_t): Doc fixes. (read_spliced_spe_reg, write_spliced_spe_reg): Deleted. (fetch_spe_register, store_spe_register): Handle fetching/storing all the SPE registers at once, if regno == -1. These now take over the job of fetch_spe_registers and store_spe_registers. (fetch_spe_registers, store_spe_registers): Deleted. (fetch_ppc_registers, store_ppc_registers): Fetch/store gprs unconditionally; they're always raw. Fetch/store SPE upper half registers, if present, instead of ev registers. (fetch_register, store_register): Remove sanity checks: gprs are never pseudo-registers now, so we never need to even mention any registers that are ever pseudoregisters.
2004-08-05 01:17:55 +08:00
gdb_assert (sizeof (evrregs.acc)
2007-11-16 Markus Deuling <deuling@de.ibm.com> * m32r-rom.c (m32r_supply_register): Use get_regcache_arch to get at the current architecture by regcache. * ppcnbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register) (fetch_register, supply_vrregset, fetch_ppc_registers) (store_altivec_register, store_spe_register, store_register) (fill_vrregset, store_ppc_registers): Likewise. * ppcobsd-nat.c (ppcobsd_supply_pcb): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers) (do_win32_store_inferior_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers) (m32r_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register, gdbsim_store_register): Likewise. * trad-frame.c (trad_frame_alloc_saved_regs): Replace current_gdbarch by gdbarch. * user-regs.c (user_reg_map_name_to_regnum): Likewise. * ppc-sysv-tdep.c (ppc_sysv_abi_push_dummy_call) (do_ppc_sysv_return_value, ppc64_sysv_abi_push_dummy_call) (ppc64_sysv_abi_return_value): Likewise. * m32c-tdep.c (m32c_register_reggroup_p): Likewise. * m2-lang.c (build_m2_types): Likewise. * ppc-linux-tdep.c (ppc_linux_sigtramp_cache * ppcnbsd-tdep.c (ppcnbsd_sigtramp_cache_init): Likewise. * ppcobsd-tdep.c (ppcobsd_sigtramp_frame_cache): Likewise. * rs6000-tdep.c (ppc_dwarf2_frame_init_reg): Likewise. * m68hc11-tdep.c (m68hc11_frame_unwind_cache): Use get_frame_arch to get at the current architecture by frame_info. * gcore.c (derive_stack_segment): Likewise. * shnbsd-nat.c (GETREGS_SUPPLIES): Add gdbarch parameter. (shnbsd_fetch_inferior_registers, shnbsd_store_inferior_registers): Add gdbarch to GETREGS_SUPPLIES call.
2007-11-16 12:53:46 +08:00
== register_size (gdbarch, tdep->ppc_acc_regnum));
Change the layout of the PowerPC E500 raw register cache to allow the lower 32-bit halves of the GPRS to be their own raw registers, not pseudoregisters. * ppc-tdep.h (struct gdbarch_tdep): Remove ppc_gprs_pseudo_p flag; add ppc_ev0_upper_regnum flag. * rs6000-tdep.c: #include "reggroups.h". (spe_register_p): Recognize the ev upper half registers as SPE registers. (init_sim_regno_table): Build gdb->sim mappings for the upper-half registers. (e500_move_ev_register): New function. (e500_pseudo_register_read, e500_pseudo_register_write): The 'ev' vector registers are the pseudo-registers now, formed by splicing together the gprs and the upper-half registers. (e500_register_reggroup_p): New function. (P): Macro deleted. (P8, A4): New macro. (PPC_EV_REGS, PPC_GPRS_PSEUDO_REGS): Macros deleted. (PPC_SPE_GP_REGS, PPC_SPE_UPPER_GP_REGS, PPC_EV_PSEUDO_REGS): New macros. (registers_e500): Rearrange register set so that the raw register set contains 32-bit GPRs and upper-half registers, and the SPE vector registers become pseudo-registers. (rs6000_gdbarch_init): Don't initialize tdep->ppc_gprs_pseudo_p; it has been deleted. Initialize ppc_ev0_upper_regnum. Many other register numbers are now the same for the E500 as they are for other PowerPC variants. Register e500_register_reggroup_p as the register group function for the E500. * Makefile.in (rs6000-tdep.o): Update dependencies. Adapt PPC E500 native support to the new raw regcache layout. * ppc-linux-nat.c (struct gdb_evrregset_t): Doc fixes. (read_spliced_spe_reg, write_spliced_spe_reg): Deleted. (fetch_spe_register, store_spe_register): Handle fetching/storing all the SPE registers at once, if regno == -1. These now take over the job of fetch_spe_registers and store_spe_registers. (fetch_spe_registers, store_spe_registers): Deleted. (fetch_ppc_registers, store_ppc_registers): Fetch/store gprs unconditionally; they're always raw. Fetch/store SPE upper half registers, if present, instead of ev registers. (fetch_register, store_register): Remove sanity checks: gprs are never pseudo-registers now, so we never need to even mention any registers that are ever pseudoregisters.
2004-08-05 01:17:55 +08:00
gdb_assert (sizeof (evrregs.spefscr)
2007-11-16 Markus Deuling <deuling@de.ibm.com> * m32r-rom.c (m32r_supply_register): Use get_regcache_arch to get at the current architecture by regcache. * ppcnbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register) (fetch_register, supply_vrregset, fetch_ppc_registers) (store_altivec_register, store_spe_register, store_register) (fill_vrregset, store_ppc_registers): Likewise. * ppcobsd-nat.c (ppcobsd_supply_pcb): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers) (do_win32_store_inferior_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers) (m32r_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register, gdbsim_store_register): Likewise. * trad-frame.c (trad_frame_alloc_saved_regs): Replace current_gdbarch by gdbarch. * user-regs.c (user_reg_map_name_to_regnum): Likewise. * ppc-sysv-tdep.c (ppc_sysv_abi_push_dummy_call) (do_ppc_sysv_return_value, ppc64_sysv_abi_push_dummy_call) (ppc64_sysv_abi_return_value): Likewise. * m32c-tdep.c (m32c_register_reggroup_p): Likewise. * m2-lang.c (build_m2_types): Likewise. * ppc-linux-tdep.c (ppc_linux_sigtramp_cache * ppcnbsd-tdep.c (ppcnbsd_sigtramp_cache_init): Likewise. * ppcobsd-tdep.c (ppcobsd_sigtramp_frame_cache): Likewise. * rs6000-tdep.c (ppc_dwarf2_frame_init_reg): Likewise. * m68hc11-tdep.c (m68hc11_frame_unwind_cache): Use get_frame_arch to get at the current architecture by frame_info. * gcore.c (derive_stack_segment): Likewise. * shnbsd-nat.c (GETREGS_SUPPLIES): Add gdbarch parameter. (shnbsd_fetch_inferior_registers, shnbsd_store_inferior_registers): Add gdbarch to GETREGS_SUPPLIES call.
2007-11-16 12:53:46 +08:00
== register_size (gdbarch, tdep->ppc_spefscr_regnum));
Change the layout of the PowerPC E500 raw register cache to allow the lower 32-bit halves of the GPRS to be their own raw registers, not pseudoregisters. * ppc-tdep.h (struct gdbarch_tdep): Remove ppc_gprs_pseudo_p flag; add ppc_ev0_upper_regnum flag. * rs6000-tdep.c: #include "reggroups.h". (spe_register_p): Recognize the ev upper half registers as SPE registers. (init_sim_regno_table): Build gdb->sim mappings for the upper-half registers. (e500_move_ev_register): New function. (e500_pseudo_register_read, e500_pseudo_register_write): The 'ev' vector registers are the pseudo-registers now, formed by splicing together the gprs and the upper-half registers. (e500_register_reggroup_p): New function. (P): Macro deleted. (P8, A4): New macro. (PPC_EV_REGS, PPC_GPRS_PSEUDO_REGS): Macros deleted. (PPC_SPE_GP_REGS, PPC_SPE_UPPER_GP_REGS, PPC_EV_PSEUDO_REGS): New macros. (registers_e500): Rearrange register set so that the raw register set contains 32-bit GPRs and upper-half registers, and the SPE vector registers become pseudo-registers. (rs6000_gdbarch_init): Don't initialize tdep->ppc_gprs_pseudo_p; it has been deleted. Initialize ppc_ev0_upper_regnum. Many other register numbers are now the same for the E500 as they are for other PowerPC variants. Register e500_register_reggroup_p as the register group function for the E500. * Makefile.in (rs6000-tdep.o): Update dependencies. Adapt PPC E500 native support to the new raw regcache layout. * ppc-linux-nat.c (struct gdb_evrregset_t): Doc fixes. (read_spliced_spe_reg, write_spliced_spe_reg): Deleted. (fetch_spe_register, store_spe_register): Handle fetching/storing all the SPE registers at once, if regno == -1. These now take over the job of fetch_spe_registers and store_spe_registers. (fetch_spe_registers, store_spe_registers): Deleted. (fetch_ppc_registers, store_ppc_registers): Fetch/store gprs unconditionally; they're always raw. Fetch/store SPE upper half registers, if present, instead of ev registers. (fetch_register, store_register): Remove sanity checks: gprs are never pseudo-registers now, so we never need to even mention any registers that are ever pseudoregisters.
2004-08-05 01:17:55 +08:00
if (regno == -1)
/* Since we're going to write out every register, the code below
should store to every field of evrregs; if that doesn't happen,
make it obvious by initializing it with suspicious values. */
memset (&evrregs, 42, sizeof (evrregs));
else
/* We can only read and write the entire EVR register set at a
time, so to write just a single register, we do a
read-modify-write maneuver. */
get_spe_registers (tid, &evrregs);
if (regno == -1)
{
Change the layout of the PowerPC E500 raw register cache to allow the lower 32-bit halves of the GPRS to be their own raw registers, not pseudoregisters. * ppc-tdep.h (struct gdbarch_tdep): Remove ppc_gprs_pseudo_p flag; add ppc_ev0_upper_regnum flag. * rs6000-tdep.c: #include "reggroups.h". (spe_register_p): Recognize the ev upper half registers as SPE registers. (init_sim_regno_table): Build gdb->sim mappings for the upper-half registers. (e500_move_ev_register): New function. (e500_pseudo_register_read, e500_pseudo_register_write): The 'ev' vector registers are the pseudo-registers now, formed by splicing together the gprs and the upper-half registers. (e500_register_reggroup_p): New function. (P): Macro deleted. (P8, A4): New macro. (PPC_EV_REGS, PPC_GPRS_PSEUDO_REGS): Macros deleted. (PPC_SPE_GP_REGS, PPC_SPE_UPPER_GP_REGS, PPC_EV_PSEUDO_REGS): New macros. (registers_e500): Rearrange register set so that the raw register set contains 32-bit GPRs and upper-half registers, and the SPE vector registers become pseudo-registers. (rs6000_gdbarch_init): Don't initialize tdep->ppc_gprs_pseudo_p; it has been deleted. Initialize ppc_ev0_upper_regnum. Many other register numbers are now the same for the E500 as they are for other PowerPC variants. Register e500_register_reggroup_p as the register group function for the E500. * Makefile.in (rs6000-tdep.o): Update dependencies. Adapt PPC E500 native support to the new raw regcache layout. * ppc-linux-nat.c (struct gdb_evrregset_t): Doc fixes. (read_spliced_spe_reg, write_spliced_spe_reg): Deleted. (fetch_spe_register, store_spe_register): Handle fetching/storing all the SPE registers at once, if regno == -1. These now take over the job of fetch_spe_registers and store_spe_registers. (fetch_spe_registers, store_spe_registers): Deleted. (fetch_ppc_registers, store_ppc_registers): Fetch/store gprs unconditionally; they're always raw. Fetch/store SPE upper half registers, if present, instead of ev registers. (fetch_register, store_register): Remove sanity checks: gprs are never pseudo-registers now, so we never need to even mention any registers that are ever pseudoregisters.
2004-08-05 01:17:55 +08:00
int i;
for (i = 0; i < ppc_num_gprs; i++)
regcache->raw_collect (tdep->ppc_ev0_upper_regnum + i,
&evrregs.evr[i]);
}
Change the layout of the PowerPC E500 raw register cache to allow the lower 32-bit halves of the GPRS to be their own raw registers, not pseudoregisters. * ppc-tdep.h (struct gdbarch_tdep): Remove ppc_gprs_pseudo_p flag; add ppc_ev0_upper_regnum flag. * rs6000-tdep.c: #include "reggroups.h". (spe_register_p): Recognize the ev upper half registers as SPE registers. (init_sim_regno_table): Build gdb->sim mappings for the upper-half registers. (e500_move_ev_register): New function. (e500_pseudo_register_read, e500_pseudo_register_write): The 'ev' vector registers are the pseudo-registers now, formed by splicing together the gprs and the upper-half registers. (e500_register_reggroup_p): New function. (P): Macro deleted. (P8, A4): New macro. (PPC_EV_REGS, PPC_GPRS_PSEUDO_REGS): Macros deleted. (PPC_SPE_GP_REGS, PPC_SPE_UPPER_GP_REGS, PPC_EV_PSEUDO_REGS): New macros. (registers_e500): Rearrange register set so that the raw register set contains 32-bit GPRs and upper-half registers, and the SPE vector registers become pseudo-registers. (rs6000_gdbarch_init): Don't initialize tdep->ppc_gprs_pseudo_p; it has been deleted. Initialize ppc_ev0_upper_regnum. Many other register numbers are now the same for the E500 as they are for other PowerPC variants. Register e500_register_reggroup_p as the register group function for the E500. * Makefile.in (rs6000-tdep.o): Update dependencies. Adapt PPC E500 native support to the new raw regcache layout. * ppc-linux-nat.c (struct gdb_evrregset_t): Doc fixes. (read_spliced_spe_reg, write_spliced_spe_reg): Deleted. (fetch_spe_register, store_spe_register): Handle fetching/storing all the SPE registers at once, if regno == -1. These now take over the job of fetch_spe_registers and store_spe_registers. (fetch_spe_registers, store_spe_registers): Deleted. (fetch_ppc_registers, store_ppc_registers): Fetch/store gprs unconditionally; they're always raw. Fetch/store SPE upper half registers, if present, instead of ev registers. (fetch_register, store_register): Remove sanity checks: gprs are never pseudo-registers now, so we never need to even mention any registers that are ever pseudoregisters.
2004-08-05 01:17:55 +08:00
else if (tdep->ppc_ev0_upper_regnum <= regno
&& regno < tdep->ppc_ev0_upper_regnum + ppc_num_gprs)
regcache->raw_collect (regno,
&evrregs.evr[regno - tdep->ppc_ev0_upper_regnum]);
Change the layout of the PowerPC E500 raw register cache to allow the lower 32-bit halves of the GPRS to be their own raw registers, not pseudoregisters. * ppc-tdep.h (struct gdbarch_tdep): Remove ppc_gprs_pseudo_p flag; add ppc_ev0_upper_regnum flag. * rs6000-tdep.c: #include "reggroups.h". (spe_register_p): Recognize the ev upper half registers as SPE registers. (init_sim_regno_table): Build gdb->sim mappings for the upper-half registers. (e500_move_ev_register): New function. (e500_pseudo_register_read, e500_pseudo_register_write): The 'ev' vector registers are the pseudo-registers now, formed by splicing together the gprs and the upper-half registers. (e500_register_reggroup_p): New function. (P): Macro deleted. (P8, A4): New macro. (PPC_EV_REGS, PPC_GPRS_PSEUDO_REGS): Macros deleted. (PPC_SPE_GP_REGS, PPC_SPE_UPPER_GP_REGS, PPC_EV_PSEUDO_REGS): New macros. (registers_e500): Rearrange register set so that the raw register set contains 32-bit GPRs and upper-half registers, and the SPE vector registers become pseudo-registers. (rs6000_gdbarch_init): Don't initialize tdep->ppc_gprs_pseudo_p; it has been deleted. Initialize ppc_ev0_upper_regnum. Many other register numbers are now the same for the E500 as they are for other PowerPC variants. Register e500_register_reggroup_p as the register group function for the E500. * Makefile.in (rs6000-tdep.o): Update dependencies. Adapt PPC E500 native support to the new raw regcache layout. * ppc-linux-nat.c (struct gdb_evrregset_t): Doc fixes. (read_spliced_spe_reg, write_spliced_spe_reg): Deleted. (fetch_spe_register, store_spe_register): Handle fetching/storing all the SPE registers at once, if regno == -1. These now take over the job of fetch_spe_registers and store_spe_registers. (fetch_spe_registers, store_spe_registers): Deleted. (fetch_ppc_registers, store_ppc_registers): Fetch/store gprs unconditionally; they're always raw. Fetch/store SPE upper half registers, if present, instead of ev registers. (fetch_register, store_register): Remove sanity checks: gprs are never pseudo-registers now, so we never need to even mention any registers that are ever pseudoregisters.
2004-08-05 01:17:55 +08:00
if (regno == -1
|| regno == tdep->ppc_acc_regnum)
regcache->raw_collect (tdep->ppc_acc_regnum,
&evrregs.acc);
Change the layout of the PowerPC E500 raw register cache to allow the lower 32-bit halves of the GPRS to be their own raw registers, not pseudoregisters. * ppc-tdep.h (struct gdbarch_tdep): Remove ppc_gprs_pseudo_p flag; add ppc_ev0_upper_regnum flag. * rs6000-tdep.c: #include "reggroups.h". (spe_register_p): Recognize the ev upper half registers as SPE registers. (init_sim_regno_table): Build gdb->sim mappings for the upper-half registers. (e500_move_ev_register): New function. (e500_pseudo_register_read, e500_pseudo_register_write): The 'ev' vector registers are the pseudo-registers now, formed by splicing together the gprs and the upper-half registers. (e500_register_reggroup_p): New function. (P): Macro deleted. (P8, A4): New macro. (PPC_EV_REGS, PPC_GPRS_PSEUDO_REGS): Macros deleted. (PPC_SPE_GP_REGS, PPC_SPE_UPPER_GP_REGS, PPC_EV_PSEUDO_REGS): New macros. (registers_e500): Rearrange register set so that the raw register set contains 32-bit GPRs and upper-half registers, and the SPE vector registers become pseudo-registers. (rs6000_gdbarch_init): Don't initialize tdep->ppc_gprs_pseudo_p; it has been deleted. Initialize ppc_ev0_upper_regnum. Many other register numbers are now the same for the E500 as they are for other PowerPC variants. Register e500_register_reggroup_p as the register group function for the E500. * Makefile.in (rs6000-tdep.o): Update dependencies. Adapt PPC E500 native support to the new raw regcache layout. * ppc-linux-nat.c (struct gdb_evrregset_t): Doc fixes. (read_spliced_spe_reg, write_spliced_spe_reg): Deleted. (fetch_spe_register, store_spe_register): Handle fetching/storing all the SPE registers at once, if regno == -1. These now take over the job of fetch_spe_registers and store_spe_registers. (fetch_spe_registers, store_spe_registers): Deleted. (fetch_ppc_registers, store_ppc_registers): Fetch/store gprs unconditionally; they're always raw. Fetch/store SPE upper half registers, if present, instead of ev registers. (fetch_register, store_register): Remove sanity checks: gprs are never pseudo-registers now, so we never need to even mention any registers that are ever pseudoregisters.
2004-08-05 01:17:55 +08:00
if (regno == -1
|| regno == tdep->ppc_spefscr_regnum)
regcache->raw_collect (tdep->ppc_spefscr_regnum,
&evrregs.spefscr);
/* Write back the modified register set. */
set_spe_registers (tid, &evrregs);
}
static void
* target.h (struct regcache): Add forward declaration. (struct target_ops): Add REGCACHE parameter to to_fetch_registers and to_store_registers target operations. (target_fetch_registers, target_store_registers): Update. * regcache.c (regcache_raw_read): Replace register_cached by regcache_valid_p. Pass regcache to target_fetch_registers. (regcache_raw_write): Pass regcache to target_store_registers. * arm-linux-nat.c (store_fpregister, store_fpregs, store_register, store_regs, store_wmmx_regs): Replace register_cached by regcache_valid_p. * bsd-kvm.c (bsd_kvm_open, bsd_kvm_proc_cmd): Pass current_regcache to target_fetch_registers calls. * corelow.c (core_open): Likewise. * linux-nat.c (linux_nat_corefile_thread_callback): Likewise. * proc-service.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * sol-thread.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * win32-nat.c (win32_resume): Likewise. * ia64-tdep.c (ia64_store_return_value): Pass current_regcache to target_store_registers call. * rs6000-tdep.c (rs6000_push_dummy_call): Likewise. * inferior.h (store_inferior_registers): Update prototype. (fetch_inferior_registers): Likewise. * gnu-nat.c (gnu_store_registers, gnu_fetch_registers): Likewise. * mips-linux-nat.c (super_fetch_registers, super_store_registers): Update function pointer signatures. * aix-thread.c (aix_thread_fetch_registers): Add REGCACHE parameter, use it instead of current_regcache, update calls. (aix_thread_store_registers): Likewise. * alphabsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * amd64bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_fpregister, fetch_fpregs, store_fpregister, store_fpregs, fetch_register, fetch_regs, store_register, store_regs, fetch_wmmx_regs, store_wmmx_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * armnbsd-nat.c (fetch_register, fetch_regs, fetch_fp_register, fetch_fp_regs, armnbsd_fetch_registers): Likewise. (store_register, store_regs, store_fp_register, store_fp_regs, armnbsd_store_registers): Likewise. * bsd-kvm.c (bsd_kvm_fetch_pcb, bsd_kvm_fetch_registers): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * corelow.c (get_core_registers): Likewise. * go32-nat.c (fetch_register, go32_fetch_registers, store_register, go32_store_registers): Likewise. * hppabsd-nat.c (hppabsd_fetch_registers): Likewise. (hppabsd_store_registers): Likewise. * hppa-hpux-nat.c (hppa_hpux_fetch_register): Likewise. (hppa_hpux_fetch_inferior_registers): Likewise. (hppa_hpux_store_register): Likewise. (hppa_hpux_store_inferior_registers): Likewise. * hppa-linux-nat.c (fetch_register, store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * hpux-thread.c (hpux_thread_fetch_registers): Likewise. (hpux_thread_store_registers): Likewise. * i386bsd-nat.c (i386bsd_fetch_inferior_registers): Likewise. (i386bsd_store_inferior_registers): Likewise. * i386gnu-nat.c (fetch_fpregs, gnu_fetch_registers, store_fpregs, gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register, store_register, fetch_regs, store_regs, fetch_fpregs, store_fpregs, fetch_fpxregs, store_fpxregs): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_register): Likewise. (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_register): Likewise. (ia64_linux_store_registers): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. (inf_child_store_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register): Likewise. (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_register): Likewise. (inf_ptrace_store_registers): Likewise. * infptrace.c (fetch_register, store_register): Likewise. (fetch_inferior_registers, store_inferior_registers): Likewise. * m32r-linux-nat.c (fetch_regs, store_regs): Likewise. (m32r_linux_fetch_inferior_registers): Likewise. (m32r_linux_store_inferior_registers): Likewise. * m68kbsd-nat.c (m68kbsd_fetch_inferior_registers): Likewise. (m68kbsd_store_inferior_registers): Likewise. * m68klinux-nat.c (fetch_register, old_fetch_inferior_registers, store_register, old_store_inferior_registers, fetch_regs, store_regs, fetch_fpregs, store_fpregs): Likewise. (m68k_linux_fetch_inferior_registers): Likewise. (m68k_linux_store_inferior_registers): Likewise. * m88kbsd-nat.c (m88kbsd_fetch_inferior_registers): Likewise. (m88kbsd_store_inferior_registers): Likewise. * mips64obsd-nat.c (mips64obsd_fetch_inferior_registers): Likewise. (mips64obsd_store_inferior_registers): Likewise. * mips-linux-nat.c (mips64_linux_regsets_fetch_registers): Likewise. (mips64_linux_regsets_store_registers): Likewise. (mips64_linux_fetch_registers): Likewise. (mips64_linux_store_registers): Likewise. * mipsnbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * monitor.c (monitor_fetch_register, monitor_store_register): Likewise. (monitor_fetch_registers, monitor_store_registers): Likewise. * nto-procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register, fetch_register, supply_vrregset, fetch_altivec_registers, fetch_ppc_registers, ppc_linux_fetch_inferior_registers): Likewise. (store_altivec_register, store_spe_register, store_register, fill_vrregset, store_altivec_registers, store_ppc_registers, ppc_linux_store_inferior_registers): Likewise. * ppcnbsd-nat.c (ppcnbsd_fetch_inferior_registers): Likewise. (ppcnbsd_store_inferior_registers): Likewise. * ppcobsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote.c (fetch_register_using_p, process_g_packet, fetch_registers_using_g, remote_fetch_registers): Likewise. (store_register_using_P, store_registers_using_G, remote_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers, m32r_fetch_register, m32r_store_register, m32r_store_register): Likewise. * remote-mips.c (mips_fetch_registers, mips_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * rs6000-nat.c (fetch_register, store_register): Likewise. (rs6000_fetch_inferior_registers): Likewise. (rs6000_store_inferior_registers): Likewise. * s390-nat.c (fetch_regs, store_regs): Likewise. (fetch_fpregs, store_fpregs): Likewise. (s390_linux_fetch_inferior_registers): Likewise. (s390_linux_store_inferior_registers): Likewise. * shnbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sol-thread.c (sol_thread_fetch_registers): Likewise. (sol_thread_store_registers): Likewise. * sparc-nat.c (fetch_inferior_registers): Likewise. (store_inferior_registers): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. (spu_store_inferior_registers): Likewise. * target.c (debug_print_register): Likewise. (debug_to_fetch_registers, debug_to_store_registers): Likewise. * vaxbsd-nat.c (vaxbsd_fetch_inferior_registers): Likewise. (vaxbsd_store_inferior_registers): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers): Likewise. (win32_fetch_inferior_registers): Likewise. (win32_store_inferior_registers): Likewise.
2007-05-06 22:34:38 +08:00
store_register (const struct regcache *regcache, int tid, int regno)
{
s/get_regcache_arch (regcache)/regcache->arch ()/g This patches removes get_regcache_arch, and use regache->arch () instead. The motivation of this change is that I am going to move some basic stuff into a base class of regcache. I don't need to update "client" code regcache->arch (). On the other hand, this patch shortens the code a little bit. gdb: 2017-10-25 Yao Qi <yao.qi@linaro.org> * aarch32-linux-nat.c (aarch32_gp_regcache_supply): Use regcache->arch () instead get_regcache_arch. * aarch64-fbsd-nat.c (aarch64_fbsd_fetch_inferior_registers): Likewise. (aarch64_fbsd_store_inferior_registers): Likewise. * aarch64-linux-nat.c (fetch_gregs_from_thread): Likewise. (store_gregs_to_thread): Likewise. (fetch_fpregs_from_thread): Likewise. (store_fpregs_to_thread): Likewise. * aarch64-tdep.c (aarch64_extract_return_value): Likewise. (aarch64_store_return_value): Likewise. (aarch64_software_single_step): Likewise. * aix-thread.c (aix_thread_wait): Likewise. (supply_reg32): Likewise. (supply_sprs64): Likewise. (supply_sprs32): Likewise. (fill_gprs64): Likewise. (fill_gprs32): Likewise. (fill_sprs64): Likewise. (fill_sprs32): Likewise. (store_regs_user_thread): Likewise. (store_regs_kernel_thread): Likewise. * alpha-bsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * alpha-tdep.c (alpha_extract_return_value): Likewise. (alpha_store_return_value): Likewise. (alpha_deal_with_atomic_sequence): Likewise. (alpha_next_pc): Likewise. (alpha_software_single_step): Likewise. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * amd64-nat.c (amd64_supply_native_gregset): Likewise. (amd64_collect_native_gregset): Likewise. * amd64-obsd-tdep.c (amd64obsd_supply_uthread): Likewise. (amd64obsd_collect_uthread): Likewise. * amd64-tdep.c (amd64_supply_fpregset): Likewise. (amd64_collect_fpregset): Likewise. (amd64_supply_fxsave): Likewise. (amd64_supply_xsave): Likewise. (amd64_collect_fxsave): Likewise. (amd64_collect_xsave): Likewise. * arc-tdep.c (arc_write_pc): Likewise. * arch-utils.c (default_skip_permanent_breakpoint): Likewise. * arm-fbsd-nat.c (arm_fbsd_fetch_inferior_registers): Likewise. (arm_fbsd_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_vfp_regs): Likewise. (store_vfp_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * arm-linux-tdep.c (arm_linux_supply_gregset): Likewise. (arm_linux_sigreturn_next_pc): Likewise. (arm_linux_get_next_pcs_syscall_next_pc): Likewise. * arm-nbsd-nat.c (arm_supply_gregset): Likewise. (fetch_register): Likewise. (store_register): Likewise. * arm-tdep.c (arm_is_thumb): Likewise. (displaced_in_arm_mode): Likewise. (bx_write_pc): Likewise. (arm_get_next_pcs_addr_bits_remove): Likewise. (arm_software_single_step): Likewise. (arm_extract_return_value): Likewise. (arm_store_return_value): Likewise. (arm_write_pc): Likewise. * bfin-tdep.c (bfin_extract_return_value): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * core-regset.c (fetch_core_registers): Likewise. * corelow.c (get_core_registers): Likewise. * cris-tdep.c (cris_store_return_value): Likewise. (cris_extract_return_value): Likewise. (find_step_target): Likewise. (find_step_target): Likewise. (cris_software_single_step): Likewise. * ctf.c (ctf_fetch_registers): Likewise. * darwin-nat.c (cancel_breakpoint): Likewise. * fbsd-tdep.c (fbsd_collect_thread_registers): Likewise. * frv-tdep.c (frv_extract_return_value): Likewise. * ft32-tdep.c (ft32_store_return_value): Likewise. (ft32_extract_return_value): Likewise. * go32-nat.c (fetch_register): Likewise. (go32_fetch_registers): Likewise. (go32_store_registers): Likewise. (store_register): Likewise. * h8300-tdep.c (h8300_extract_return_value): Likewise. (h8300_store_return_value): Likewise. * hppa-linux-nat.c (fetch_register): Likewise. (store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * i386-darwin-nat.c (i386_darwin_fetch_inferior_registers): Likewise. (i386_darwin_store_inferior_registers): Likewise. * i386-gnu-nat.c (gnu_fetch_registers): Likewise. (gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register): Likewise. (store_register): Likewise. (supply_gregset): Likewise. (fill_gregset): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. (i386_linux_resume): Likewise. * i386-linux-tdep.c (i386_linux_get_syscall_number_from_regcache): Likewise. * i386-nto-tdep.c (i386nto_supply_gregset): Likewise. * i386-obsd-nat.c (i386obsd_supply_pcb): Likewise. * i386-obsd-tdep.c (i386obsd_supply_uthread): Likewise. (i386obsd_collect_uthread): Likewise. * i386-tdep.c (i386_mmx_regnum_to_fp_regnum): Likewise. (i386_supply_gregset): Likewise. (i386_collect_gregset): Likewise. (i386_supply_fpregset): Likewise. (i386_collect_fpregset): Likewise. (i386_mpx_bd_base): Likewise. * i386-v4-nat.c (supply_fpregset): Likewise. (fill_fpregset): Likewise. * i387-tdep.c (i387_supply_fsave): Likewise. (i387_collect_fsave): Likewise. (i387_supply_fxsave): Likewise. (i387_collect_fxsave): Likewise. (i387_supply_xsave): Likewise. (i387_collect_xsave): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_registers): Likewise. * ia64-tdep.c (ia64_access_rse_reg): Likewise. (ia64_extract_return_value): Likewise. (ia64_store_return_value): Likewise. (find_func_descr): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_registers): Likewise. * infrun.c (use_displaced_stepping): Likewise. (displaced_step_prepare_throw): Likewise. (resume): Likewise. (proceed): Likewise. (do_target_wait): Likewise. (adjust_pc_after_break): Likewise. (handle_inferior_event_1): Likewise. (handle_signal_stop): Likewise. (save_infcall_suspend_state): Likewise. (restore_infcall_suspend_state): Likewise. * iq2000-tdep.c (iq2000_extract_return_value): Likewise. * jit.c (jit_frame_prev_register): Likewise. * linux-nat.c (save_stop_reason): Likewise. (linux_nat_wait_1): Likewise. (resume_stopped_resumed_lwps): Likewise. * linux-record.c (record_linux_sockaddr): Likewise. (record_linux_msghdr): Likewise. (record_linux_system_call): Likewise. * linux-tdep.c (linux_collect_thread_registers): Likewise. * lm32-tdep.c (lm32_extract_return_value): Likewise. (lm32_store_return_value): Likewise. * m32c-tdep.c (m32c_read_flg): Likewise. (m32c_pseudo_register_read): Likewise. (m32c_pseudo_register_write): Likewise. * m32r-linux-tdep.c (m32r_linux_supply_gregset): Likewise. (m32r_linux_collect_gregset): Likewise. * m32r-tdep.c (m32r_store_return_value): Likewise. (m32r_extract_return_value): Likewise. * m68k-bsd-nat.c (m68kbsd_supply_fpregset): Likewise. (m68kbsd_collect_fpregset): Likewise. * m68k-bsd-tdep.c (m68kbsd_supply_fpregset): Likewise. * m68k-linux-nat.c (fetch_register): Likewise. (old_fetch_inferior_registers): Likewise. (old_store_inferior_registers): Likewise. (store_regs): Likewise. * m68k-tdep.c (m68k_svr4_extract_return_value): Likewise. (m68k_svr4_store_return_value): Likewise. * m88k-tdep.c (m88k_store_arguments): Likewise. * mi/mi-main.c (mi_cmd_data_list_changed_registers): Likewise. (mi_cmd_data_write_register_values): Likewise. * mips-fbsd-nat.c (mips_fbsd_fetch_inferior_registers): Likewise. (mips_fbsd_store_inferior_registers): Likewise. * mips-fbsd-tdep.c (mips_fbsd_supply_fpregs): Likewise. (mips_fbsd_supply_gregs): Likewise. (mips_fbsd_collect_fpregs): Likewise. (mips_fbsd_collect_gregs): Likewise. (mips_fbsd_supply_fpregset): Likewise. (mips_fbsd_collect_fpregset): Likewise. (mips_fbsd_supply_gregset): Likewise. (mips_fbsd_collect_gregset): Likewise. * mips-linux-nat.c (supply_gregset): Likewise. (fill_gregset): Likewise. (supply_fpregset): Likewise. (fill_fpregset): Likewise. * mips-linux-tdep.c (mips_supply_gregset): Likewise. (mips_fill_gregset): Likewise. (mips_supply_fpregset): Likewise. (mips_fill_fpregset): Likewise. (mips64_supply_gregset): Likewise. (micromips_linux_sigframe_validate): Likewise. * mips-nbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * mips-nbsd-tdep.c (mipsnbsd_supply_fpregset): Likewise. (mipsnbsd_supply_gregset): Likewise. (mipsnbsd_iterate_over_regset_sections): Likewise. (mipsnbsd_supply_reg): Likewise. (mipsnbsd_supply_fpreg): Likewise. * mips-tdep.c (mips_in_frame_stub): Likewise. (mips_dummy_id): Likewise. (is_octeon_bbit_op): Likewise. (micromips_bc1_pc): Likewise. (extended_mips16_next_pc): Likewise. (mips16_next_pc): Likewise. (deal_with_atomic_sequence): Likewise. * moxie-tdep.c (moxie_process_readu): Likewise. * nios2-tdep.c (nios2_get_next_pc): Likewise. * nto-procfs.c (procfs_store_registers): Likewise. * ppc-fbsd-nat.c (ppcfbsd_fetch_inferior_registers): Likewise. (ppcfbsd_store_inferior_registers): Likewise. * ppc-linux-nat.c (fetch_vsx_register): Likewise. (fetch_altivec_register): Likewise. (get_spe_registers): Likewise. (fetch_spe_register): Likewise. (fetch_altivec_registers): Likewise. (fetch_all_gp_regs): Likewise. (fetch_all_fp_regs): Likewise. (store_vsx_register): Likewise. (store_altivec_register): Likewise. (set_spe_registers): Likewise. (store_spe_register): Likewise. (store_altivec_registers): Likewise. (store_all_gp_regs): Likewise. (store_all_fp_regs): Likewise. * ppc-linux-tdep.c (ppc_linux_supply_gregset): Likewise. (ppc_linux_collect_gregset): Likewise. (ppc_canonicalize_syscall): Likewise. (ppc_linux_record_signal): Likewise. (ppu2spu_prev_register): Likewise. * ppc-nbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-obsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * ppc-ravenscar-thread.c (ppc_ravenscar_generic_fetch_registers): Likewise. (ppc_ravenscar_generic_store_registers): Likewise. * procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ravenscar-thread.c (ravenscar_fetch_registers): Likewise. (ravenscar_store_registers): Likewise. (ravenscar_prepare_to_store): Likewise. * record-btrace.c (record_btrace_fetch_registers): Likewise. * record-full.c (record_full_wait_1): Likewise. (record_full_registers_change): Likewise. (record_full_store_registers): Likewise. (record_full_core_fetch_registers): Likewise. (record_full_save): Likewise. (record_full_goto_insn): Likewise. * regcache.c (regcache_register_size): Likewise. (get_regcache_arch): Remove. (regcache_read_pc): Likewise. * regcache.h (get_regcache_arch): Remove. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * remote.c (fetch_register_using_p): Likewise. (send_g_packet): Likewise. (remote_prepare_to_store): Likewise. (store_registers_using_G): Likewise. * reverse.c (save_bookmark_command): Likewise. (goto_bookmark_command): Likewise. * rs6000-aix-tdep.c (branch_dest): Likewise. * rs6000-nat.c (rs6000_ptrace64): Likewise. (fetch_register): Likewise. * rs6000-tdep.c (ppc_supply_reg): Likewise. (ppc_collect_reg): Likewise. (ppc_collect_gregset): Likewise. (ppc_collect_fpregset): Likewise. (ppc_collect_vsxregset): Likewise. (ppc_collect_vrregset): Likewise. (ppc_displaced_step_hw_singlestep): Likewise. (rs6000_pseudo_register_read): Likewise. (rs6000_pseudo_register_write): Likewise. * s390-linux-nat.c (supply_gregset): Likewise. (fill_gregset): Likewise. (s390_linux_fetch_inferior_registers): Likewise. * s390-linux-tdep.c (s390_write_pc): Likewise. (s390_software_single_step): Likewise. (s390_all_but_pc_registers_record): Likewise. (s390_linux_syscall_record): Likewise. * sentinel-frame.c (sentinel_frame_prev_arch): Likewise. * sh-nbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sh-tdep.c (sh_extract_return_value_nofpu): Likewise. (sh_extract_return_value_fpu): Likewise. (sh_store_return_value_nofpu): Likewise. (sh_corefile_supply_regset): Likewise. (sh_corefile_collect_regset): Likewise. * sh64-tdep.c (sh64_extract_return_value): Likewise. (sh64_store_return_value): Likewise. * sparc-linux-tdep.c (sparc32_linux_collect_core_fpregset): Likewise. * sparc-nat.c (sparc_fetch_inferior_registers): Likewise. (sparc_store_inferior_registers): Likewise. * sparc-ravenscar-thread.c (register_in_thread_descriptor_p): Likewise. (sparc_ravenscar_prepare_to_store): Likewise. * sparc-tdep.c (sparc32_store_arguments): Likewise. (sparc_analyze_control_transfer): Likewise. (sparc_step_trap): Likewise. (sparc_software_single_step): Likewise. (sparc32_gdbarch_init): Likewise. (sparc_supply_rwindow): Likewise. (sparc_collect_rwindow): Likewise. * sparc64-linux-tdep.c (sparc64_linux_collect_core_fpregset): Likewise. * sparc64-nbsd-nat.c (sparc64nbsd_supply_gregset): Likewise. (sparc64nbsd_collect_gregset): Likewise. (sparc64nbsd_supply_fpregset): Likewise. (sparc64nbsd_collect_fpregset): Likewise. * sparc64-tdep.c (sparc64_store_arguments): Likewise. (sparc64_supply_gregset): Likewise. (sparc64_collect_gregset): Likewise. (sparc64_supply_fpregset): Likewise. (sparc64_collect_fpregset): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. * spu-tdep.c (spu_unwind_sp): Likewise. (spu2ppu_prev_register): Likewise. (spu_memory_remove_breakpoint): Likewise. * stack.c (return_command): Likewise. * tic6x-tdep.c (tic6x_extract_signed_field): Likewise. * tracefile-tfile.c (tfile_fetch_registers): Likewise. * tracefile.c (trace_save_ctf): Likewise. * windows-nat.c (do_windows_fetch_inferior_registers): Likewise. (do_windows_store_inferior_registers): Likewise. (windows_resume): Likewise. * xtensa-linux-nat.c (fill_gregset): Likewise. (supply_gregset_reg): Likewise. * xtensa-tdep.c (xtensa_register_write_masked): Likewise. (xtensa_register_read_masked): Likewise. (xtensa_supply_gregset): Likewise. (xtensa_extract_return_value): Likewise. (xtensa_store_return_value): Likewise.
2017-10-25 23:37:03 +08:00
struct gdbarch *gdbarch = regcache->arch ();
2007-11-16 Markus Deuling <deuling@de.ibm.com> * m32r-rom.c (m32r_supply_register): Use get_regcache_arch to get at the current architecture by regcache. * ppcnbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register) (fetch_register, supply_vrregset, fetch_ppc_registers) (store_altivec_register, store_spe_register, store_register) (fill_vrregset, store_ppc_registers): Likewise. * ppcobsd-nat.c (ppcobsd_supply_pcb): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers) (do_win32_store_inferior_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers) (m32r_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register, gdbsim_store_register): Likewise. * trad-frame.c (trad_frame_alloc_saved_regs): Replace current_gdbarch by gdbarch. * user-regs.c (user_reg_map_name_to_regnum): Likewise. * ppc-sysv-tdep.c (ppc_sysv_abi_push_dummy_call) (do_ppc_sysv_return_value, ppc64_sysv_abi_push_dummy_call) (ppc64_sysv_abi_return_value): Likewise. * m32c-tdep.c (m32c_register_reggroup_p): Likewise. * m2-lang.c (build_m2_types): Likewise. * ppc-linux-tdep.c (ppc_linux_sigtramp_cache * ppcnbsd-tdep.c (ppcnbsd_sigtramp_cache_init): Likewise. * ppcobsd-tdep.c (ppcobsd_sigtramp_frame_cache): Likewise. * rs6000-tdep.c (ppc_dwarf2_frame_init_reg): Likewise. * m68hc11-tdep.c (m68hc11_frame_unwind_cache): Use get_frame_arch to get at the current architecture by frame_info. * gcore.c (derive_stack_segment): Likewise. * shnbsd-nat.c (GETREGS_SUPPLIES): Add gdbarch parameter. (shnbsd_fetch_inferior_registers, shnbsd_store_inferior_registers): Add gdbarch to GETREGS_SUPPLIES call.
2007-11-16 12:53:46 +08:00
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
/* This isn't really an address. But ptrace thinks of it as one. */
CORE_ADDR regaddr = ppc_register_u_addr (gdbarch, regno);
int i;
size_t bytes_to_transfer;
gdb_byte buf[PPC_MAX_REGISTER_SIZE];
* alpha-tdep.c (alpha_heuristic_proc_start) (alpha_sigtramp_register_address): Add gdbarch as parameter. Replace current_gdbarch by gdbarch. (alpha_heuristic_frame_unwind_cache): Use get_frame_arch to get at the current architecture by frame_info. Update alpha_heuristic_proc_start call. (alpha_sigtramp_frame_this_id, alpha_sigtramp_frame_prev_register): Use get_frame_arch to get at the current architecture by frame_info. Update alpha_sigtramp_register_address call. * arm-tdep.c (thumb_scan_prologue): Add gdbarch as parameter and replace current_gdbarch by gdbarch. Update caller. (convert_to_extended, convert_from_extended): Add endianess parameter for comparison. Update caller. (arm_extract_return_value, arm_store_return_value): Use get_regcache_arch to get at the current architecture. * cris-tdep.c (cris_register_size): Add gdbarch as parameter. Replace current_gdbarch by gdbarch. Update caller. (cris_gdb_func, move_to_preg_op, none_reg_mode_move_from_preg_op): Add gdbarch as parameter. Update caller. Replace current_gdbarch by gdbarch. * h8300-tdep.c (E_PSEUDO_CCR_REGNUM, E_PSEUDO_EXR_REGNUM, BINWORD): Add gdbarch as parameter. Update caller. (h8300_init_frame_cache): Add gdbarch as parameter. Replace current_gdbarch by gdbarch. Update caller. * hppa-tdep.c (skip_prologue_hard_way): Add gdbarch as parameter and update caller. Replace current_gdbarch by gdbarch. * m32c-tdep.c (m32c_skip_trampoline_code): Use get_frame_arch to get at the current architecture. Replace current_gdbarch by gdbarch. * m68hc11-tdep.c (m68hc11_frame_unwind_cache): Likewise. (STACK_CORRECTION, USE_PAGE_REGISTER): Replace M6811_TDEP by its expression. Add gdbarch as parameter and replace current_gdbarch with it. Update caller. (M6811_TDEP): Remove. (m68hc11_frame_prev_register): Use get_frame_arch to get at the current architecture. (m68hc11_scan_prologue): Add gdbarch as parameter. Replace current_gdbarch by gdbarch. Update caller. * m68k-tdep.c (m68k_analyze_prologue): Add gdbarch as parameter and update caller. (m68k_analyze_register_saves): Likewise. Also replace current_gdbarch by gdbarch. * rs6000-tdep.c (skip_prologue): Add gdbarch as parameter and update caller. Relace current_gdbarch by gdbarch. (altivec_register_p, spe_register_p): Likewise. * ppc-tdep.h (altivec_register_p, spe_register_p): Add gdbarch as parameter. * ppc-linux-nat.c (fetch_register, store_register): Update caller of altivec_register_p and spe_register_p. * score-tdep.c (score_fetch_inst): Add gdbarch as parameter. Update caller. Replace current_gdbarch by gdbarch. (score_analyze_prologue): use get_frame_arch to get at the current architecture. * sparc-tdep.h (sparc_analyze_prologue): Add gdbarch as parameter. * sparc-tdep.c (sparc_analyze_prologue): Likewise. Replace current_gdbarch by gdbarch. Update caller. (sparc_frame_cache): Use get_frame_arch to get at the current architecture. * sparce64-tdep.c (sparc64_skip_prologue): Update call of sparc_analyze_prologue. * mn10300-tdep.c (mn10300_dwarf2_reg_to_regnum): Add gdbarch as parameter.
2008-01-11 22:43:15 +08:00
if (altivec_register_p (gdbarch, regno))
{
[PowerPC] Fix access to VSCR in linux targets The 4-byte VSCR register is found inside a 16-byte field in the regset returned by ptrace and in core files. The position of VSCR depends on the endianess of the target, which was previously assumed to be big-endian for the purpose of getting VSCR. This patch removes this assumption to fix access to VSCR in little-endian mode. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-tdep.h (struct ppc_reg_offsets): Remove vector register offset fields. * ppc-fbsd-tdep.c (ppc32_fbsd_reg_offsets): Remove initializers for vector register offset fields. (ppc64_fbsd_reg_offsets): Likewise. * ppc-nbsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-nat.c (_initialize_ppcobsd_nat): Remove assignment to vector register offset fields. * rs6000-aix-tdep.c (rs6000_aix32_reg_offsets): Remove initializers for vector register offset fields. (rs6000_aix64_reg_offsets): Likewise. * rs6000-tdep.c (ppc_vrreg_offset): Remove. (ppc_supply_vrregset): Remove. (ppc_collect_vrregset): Remove. * ppc-linux-tdep.c (ppc_linux_collect_vrregset): New function. (ppc_linux_vrregset) : New function. (ppc32_le_linux_vrregmap, ppc32_be_linux_vrregmap) (ppc32_le_linux_vrregset, ppc32_be_linux_vrregset): New globals. (ppc32_linux_vrregset): Remove. (ppc_linux_iterate_over_regset_sections): Call ppc_linux_vrregset and use result instead of ppc32_linux_vrregset. (ppc32_linux_reg_offsets): Remove initializers for vector register offset fields. (ppc64_linux_reg_offsets): Likewise. * ppc-linux-tdep.h (ppc_linux_vrregset): New declaration. * ppc-linux-nat.c: Include regset.h. (gdb_vrregset_t): Adjust comment to account for little-endian mode. (supply_vrregset, fill_vrregset): Remove. (fetch_altivec_register, store_altivec_register): Remove. (fetch_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to supply registers. (store_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to collect registers. (fetch_register): Call fetch_altivec_registers instead of fetch_altivec_register. (store_register): Call store_altivec_registers instead of store_altivec_register. (fetch_ppc_registers): Call fetch_altivec_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_altivec_registers with -1 for the new regno parameter. gdb/gdbserver/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * linux-ppc-low.c (ppc_fill_vrregset): Add vscr_offset variable. Set vscr_offset to 0 in little-endian mode and 12 in big-endian mode. Call collect_register_by_name with vscr using vscr_offset. Zero-pad vscr and vrsave fields in collector buffer. (ppc_store_vrregset): Add and set vscr_offset variable as in ppc_fill_vrregset. Call supply_register_by_name with vscr using vscr_offset.
2018-05-22 22:09:05 +08:00
store_altivec_registers (regcache, tid, regno);
return;
}
else if (vsx_register_p (gdbarch, regno))
* rs6000-tdep: Include "features/rs6000/powerpc-vsx32.c". Include "features/rs6000/powerpc-vsx64.c". (ppc_supply_vsxregset): New function. (ppc_collect_vsxregset): New function. (IS_VSX_PSEUDOREG): New macro. (IS_EFP_PSEUDOREG): New macro. (vsx_register_p): New function. (ppc_vsx_support_p): New function. (rs6000_builtin_type_vec128): New function. (rs6000_register_name): Hide upper halves of vs0~vs31. Return correct names for VSX registers and EFPR registers. (rs6000_pseudo_register_type): Return correct types for VSX and EFPR registers. (rs6000_pseudo_register_reggroup_p): Return correct group for VSX and EFPR registers. (ppc_pseudo_register_read): Rename to dfp_pseudo_register_read. (ppc_pseudo_register_write): Rename to dfp_pseudo_register_write. (vsx_pseudo_register_read): New function. (vsx_pseudo_register_write): New function. (efpr_pseudo_register_read): New function. (efpr_pseudo_register_write): New function. (rs6000_pseudo_register_read): Call new VSX and EFPR read functions. (rs6000_pseudo_register_write): Call new VSX and EFPR write functions. (rs6000_gdbarch_init): Declare have_vsx. Initialize new upper half VSX registers. Initialize VSX-related and EFPR-related pseudo-registers variables. Adjust the number of pseudo registers accordingly. * ppc-linux-nat.c: Define PTRACE_GETVSXREGS, PTRACE_SETVSXREGS and SIZEOF_VSRREGS. (gdb_vsxregset_t): New type. (have_ptrace_getsetvsxregs): New variable. (fetch_vsx_register): New function. (fetch_register): Handle VSX registers. (fetch_vsx_registers): New function. (fetch_ppc_registers): Handle VSX registers. (store_ppc_registers): Handle VSX registers. (store_vsx_register): New function. (store_register): Handle VSX registers. (store_vsx_registers): New function. (ppc_linux_read_description): Handle VSX-enabled inferiors. (gdb_vsxregset_t): New type. (supply_vsxregset): New function. (fill_vsxregset): New function. * ppc-tdep.h (vsx_register_p): New prototype. (vsx_support_p): New prototype. (ppc_vsr0_regnum): New variable. (ppc_vsr0_upper_regnum): Likewise. (ppc_efpr0_regnum): Likewise. (ppc_builtin_type_vec128): New type. (ppc_num_vsrs): New constant. (ppc_num_vshrs): New constant. (ppc_num_efprs): Likewise. Define POWERPC_VEC_VSX PPC_VSR0_UPPER_REGNUM and PPC_VSR31_UPPER_REGNUM. (ppc_supply_vsxregset): New prototype. (ppc_collect_vsxregset): New prototype. * ppc-linux-tdep.c: Include "features/rs6000/powerpc-vsx32l.c" Include "features/rs6000/powerpc-vsx64l.c". (_initialize_ppc_linux_tdep): Initialize VSX-enabled targets. (ppc_linux_regset_sections): Add new ".reg-ppc-vsx" field. (ppc32_linux_vsxregset): New 32-bit VSX-enabled regset. (ppc_linux_regset_from_core_section): Handle VSX core section. (ppc_linux_core_read_description): Support VSX-enabled core files. * ppc-linux-tdep.h: Declare *tdesc_powerpc_vsx32l Declare tdesc_powerpc_vsx64l * corelow.c (get_core_register_section): Support VSX-enabled core files. * features/rs6000/power-vsx.xml: New VSX descriptions. * features/rs6000/powerpc-vsx32.xml: New file. * features/rs6000/powerpc-vsx32l.xml: New file. * features/rs6000/powerpc-vsx64.xml: New file. * features/rs6000/powerpc-vsx64l.xml: New file. * features/rs6000/powerpc-vsx32.c: New file (generated). * features/rs6000/powerpc-vsx32l.c: New file (generated). * features/rs6000/powerpc-vsx64.c: New file (generated). * features/rs6000/powerpc-vsx64l.c: New file (generated). * features/Makefile: Updated with new descriptions. * regformats/rs6000/powerpc-vsx32l.dat: New file (generated). * regformats/rs6000/powerpc-vsx64l.dat: New file (generated). * testsuite/gdb.arch/vsx-regs.c: New source file. * testsuite/gdb.arch/vsx-regs.exp: New testcase. * testsuite/lib/gdb.exp (skip_vsx_tests): New function.
2008-08-15 23:18:34 +08:00
{
[PowerPC] Fix VSX registers in linux core files The functions used by the VSX regset to collect and supply registers from core files where incorrect. This patch changes the regset to use the standard regset collect/supply functions to fix this. The native target is also changed to use the same regset. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-linux-tdep.c (ppc_linux_vsxregset): New function. (ppc32_linux_vsxregmap): New global. (ppc32_linux_vsxregset): Initialize with ppc32_linux_vsxregmap, regcache_supply_regset, and regcache_collect_regset. * ppc-linux-tdep.h (ppc_linux_vsxregset): Declare. * ppc-linux-nat.c (supply_vsxregset, fill_vsxregset): Remove. (fetch_vsx_register, store_vsx_register): Remove. (fetch_vsx_registers): Add regno parameter. Get regset using ppc_linux_vsxregset. Use regset to supply registers. (store_vsx_registers): Add regno parameter. Get regset using ppc_linux_vsxregset. Use regset to collect registers. (fetch_register): Call fetch_vsx_registers instead of fetch_vsx_register. (store_register): Call store_vsx_registers instead of store_vsx_register. (fetch_ppc_registers): Call fetch_vsx_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_vsx_registers with -1 for the new regno parameter. * rs6000-tdep.c (ppc_vsx_support_p, ppc_supply_vsxreget) (ppc_collect_vsxregset): Remove. gdb/testsuite/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * gdb.arch/powerpc-vsx-gcore.exp: New file.
2018-05-22 22:09:05 +08:00
store_vsx_registers (regcache, tid, regno);
* rs6000-tdep: Include "features/rs6000/powerpc-vsx32.c". Include "features/rs6000/powerpc-vsx64.c". (ppc_supply_vsxregset): New function. (ppc_collect_vsxregset): New function. (IS_VSX_PSEUDOREG): New macro. (IS_EFP_PSEUDOREG): New macro. (vsx_register_p): New function. (ppc_vsx_support_p): New function. (rs6000_builtin_type_vec128): New function. (rs6000_register_name): Hide upper halves of vs0~vs31. Return correct names for VSX registers and EFPR registers. (rs6000_pseudo_register_type): Return correct types for VSX and EFPR registers. (rs6000_pseudo_register_reggroup_p): Return correct group for VSX and EFPR registers. (ppc_pseudo_register_read): Rename to dfp_pseudo_register_read. (ppc_pseudo_register_write): Rename to dfp_pseudo_register_write. (vsx_pseudo_register_read): New function. (vsx_pseudo_register_write): New function. (efpr_pseudo_register_read): New function. (efpr_pseudo_register_write): New function. (rs6000_pseudo_register_read): Call new VSX and EFPR read functions. (rs6000_pseudo_register_write): Call new VSX and EFPR write functions. (rs6000_gdbarch_init): Declare have_vsx. Initialize new upper half VSX registers. Initialize VSX-related and EFPR-related pseudo-registers variables. Adjust the number of pseudo registers accordingly. * ppc-linux-nat.c: Define PTRACE_GETVSXREGS, PTRACE_SETVSXREGS and SIZEOF_VSRREGS. (gdb_vsxregset_t): New type. (have_ptrace_getsetvsxregs): New variable. (fetch_vsx_register): New function. (fetch_register): Handle VSX registers. (fetch_vsx_registers): New function. (fetch_ppc_registers): Handle VSX registers. (store_ppc_registers): Handle VSX registers. (store_vsx_register): New function. (store_register): Handle VSX registers. (store_vsx_registers): New function. (ppc_linux_read_description): Handle VSX-enabled inferiors. (gdb_vsxregset_t): New type. (supply_vsxregset): New function. (fill_vsxregset): New function. * ppc-tdep.h (vsx_register_p): New prototype. (vsx_support_p): New prototype. (ppc_vsr0_regnum): New variable. (ppc_vsr0_upper_regnum): Likewise. (ppc_efpr0_regnum): Likewise. (ppc_builtin_type_vec128): New type. (ppc_num_vsrs): New constant. (ppc_num_vshrs): New constant. (ppc_num_efprs): Likewise. Define POWERPC_VEC_VSX PPC_VSR0_UPPER_REGNUM and PPC_VSR31_UPPER_REGNUM. (ppc_supply_vsxregset): New prototype. (ppc_collect_vsxregset): New prototype. * ppc-linux-tdep.c: Include "features/rs6000/powerpc-vsx32l.c" Include "features/rs6000/powerpc-vsx64l.c". (_initialize_ppc_linux_tdep): Initialize VSX-enabled targets. (ppc_linux_regset_sections): Add new ".reg-ppc-vsx" field. (ppc32_linux_vsxregset): New 32-bit VSX-enabled regset. (ppc_linux_regset_from_core_section): Handle VSX core section. (ppc_linux_core_read_description): Support VSX-enabled core files. * ppc-linux-tdep.h: Declare *tdesc_powerpc_vsx32l Declare tdesc_powerpc_vsx64l * corelow.c (get_core_register_section): Support VSX-enabled core files. * features/rs6000/power-vsx.xml: New VSX descriptions. * features/rs6000/powerpc-vsx32.xml: New file. * features/rs6000/powerpc-vsx32l.xml: New file. * features/rs6000/powerpc-vsx64.xml: New file. * features/rs6000/powerpc-vsx64l.xml: New file. * features/rs6000/powerpc-vsx32.c: New file (generated). * features/rs6000/powerpc-vsx32l.c: New file (generated). * features/rs6000/powerpc-vsx64.c: New file (generated). * features/rs6000/powerpc-vsx64l.c: New file (generated). * features/Makefile: Updated with new descriptions. * regformats/rs6000/powerpc-vsx32l.dat: New file (generated). * regformats/rs6000/powerpc-vsx64l.dat: New file (generated). * testsuite/gdb.arch/vsx-regs.c: New source file. * testsuite/gdb.arch/vsx-regs.exp: New testcase. * testsuite/lib/gdb.exp (skip_vsx_tests): New function.
2008-08-15 23:18:34 +08:00
return;
}
* alpha-tdep.c (alpha_heuristic_proc_start) (alpha_sigtramp_register_address): Add gdbarch as parameter. Replace current_gdbarch by gdbarch. (alpha_heuristic_frame_unwind_cache): Use get_frame_arch to get at the current architecture by frame_info. Update alpha_heuristic_proc_start call. (alpha_sigtramp_frame_this_id, alpha_sigtramp_frame_prev_register): Use get_frame_arch to get at the current architecture by frame_info. Update alpha_sigtramp_register_address call. * arm-tdep.c (thumb_scan_prologue): Add gdbarch as parameter and replace current_gdbarch by gdbarch. Update caller. (convert_to_extended, convert_from_extended): Add endianess parameter for comparison. Update caller. (arm_extract_return_value, arm_store_return_value): Use get_regcache_arch to get at the current architecture. * cris-tdep.c (cris_register_size): Add gdbarch as parameter. Replace current_gdbarch by gdbarch. Update caller. (cris_gdb_func, move_to_preg_op, none_reg_mode_move_from_preg_op): Add gdbarch as parameter. Update caller. Replace current_gdbarch by gdbarch. * h8300-tdep.c (E_PSEUDO_CCR_REGNUM, E_PSEUDO_EXR_REGNUM, BINWORD): Add gdbarch as parameter. Update caller. (h8300_init_frame_cache): Add gdbarch as parameter. Replace current_gdbarch by gdbarch. Update caller. * hppa-tdep.c (skip_prologue_hard_way): Add gdbarch as parameter and update caller. Replace current_gdbarch by gdbarch. * m32c-tdep.c (m32c_skip_trampoline_code): Use get_frame_arch to get at the current architecture. Replace current_gdbarch by gdbarch. * m68hc11-tdep.c (m68hc11_frame_unwind_cache): Likewise. (STACK_CORRECTION, USE_PAGE_REGISTER): Replace M6811_TDEP by its expression. Add gdbarch as parameter and replace current_gdbarch with it. Update caller. (M6811_TDEP): Remove. (m68hc11_frame_prev_register): Use get_frame_arch to get at the current architecture. (m68hc11_scan_prologue): Add gdbarch as parameter. Replace current_gdbarch by gdbarch. Update caller. * m68k-tdep.c (m68k_analyze_prologue): Add gdbarch as parameter and update caller. (m68k_analyze_register_saves): Likewise. Also replace current_gdbarch by gdbarch. * rs6000-tdep.c (skip_prologue): Add gdbarch as parameter and update caller. Relace current_gdbarch by gdbarch. (altivec_register_p, spe_register_p): Likewise. * ppc-tdep.h (altivec_register_p, spe_register_p): Add gdbarch as parameter. * ppc-linux-nat.c (fetch_register, store_register): Update caller of altivec_register_p and spe_register_p. * score-tdep.c (score_fetch_inst): Add gdbarch as parameter. Update caller. Replace current_gdbarch by gdbarch. (score_analyze_prologue): use get_frame_arch to get at the current architecture. * sparc-tdep.h (sparc_analyze_prologue): Add gdbarch as parameter. * sparc-tdep.c (sparc_analyze_prologue): Likewise. Replace current_gdbarch by gdbarch. Update caller. (sparc_frame_cache): Use get_frame_arch to get at the current architecture. * sparce64-tdep.c (sparc64_skip_prologue): Update call of sparc_analyze_prologue. * mn10300-tdep.c (mn10300_dwarf2_reg_to_regnum): Add gdbarch as parameter.
2008-01-11 22:43:15 +08:00
else if (spe_register_p (gdbarch, regno))
{
* target.h (struct regcache): Add forward declaration. (struct target_ops): Add REGCACHE parameter to to_fetch_registers and to_store_registers target operations. (target_fetch_registers, target_store_registers): Update. * regcache.c (regcache_raw_read): Replace register_cached by regcache_valid_p. Pass regcache to target_fetch_registers. (regcache_raw_write): Pass regcache to target_store_registers. * arm-linux-nat.c (store_fpregister, store_fpregs, store_register, store_regs, store_wmmx_regs): Replace register_cached by regcache_valid_p. * bsd-kvm.c (bsd_kvm_open, bsd_kvm_proc_cmd): Pass current_regcache to target_fetch_registers calls. * corelow.c (core_open): Likewise. * linux-nat.c (linux_nat_corefile_thread_callback): Likewise. * proc-service.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * sol-thread.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * win32-nat.c (win32_resume): Likewise. * ia64-tdep.c (ia64_store_return_value): Pass current_regcache to target_store_registers call. * rs6000-tdep.c (rs6000_push_dummy_call): Likewise. * inferior.h (store_inferior_registers): Update prototype. (fetch_inferior_registers): Likewise. * gnu-nat.c (gnu_store_registers, gnu_fetch_registers): Likewise. * mips-linux-nat.c (super_fetch_registers, super_store_registers): Update function pointer signatures. * aix-thread.c (aix_thread_fetch_registers): Add REGCACHE parameter, use it instead of current_regcache, update calls. (aix_thread_store_registers): Likewise. * alphabsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * amd64bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_fpregister, fetch_fpregs, store_fpregister, store_fpregs, fetch_register, fetch_regs, store_register, store_regs, fetch_wmmx_regs, store_wmmx_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * armnbsd-nat.c (fetch_register, fetch_regs, fetch_fp_register, fetch_fp_regs, armnbsd_fetch_registers): Likewise. (store_register, store_regs, store_fp_register, store_fp_regs, armnbsd_store_registers): Likewise. * bsd-kvm.c (bsd_kvm_fetch_pcb, bsd_kvm_fetch_registers): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * corelow.c (get_core_registers): Likewise. * go32-nat.c (fetch_register, go32_fetch_registers, store_register, go32_store_registers): Likewise. * hppabsd-nat.c (hppabsd_fetch_registers): Likewise. (hppabsd_store_registers): Likewise. * hppa-hpux-nat.c (hppa_hpux_fetch_register): Likewise. (hppa_hpux_fetch_inferior_registers): Likewise. (hppa_hpux_store_register): Likewise. (hppa_hpux_store_inferior_registers): Likewise. * hppa-linux-nat.c (fetch_register, store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * hpux-thread.c (hpux_thread_fetch_registers): Likewise. (hpux_thread_store_registers): Likewise. * i386bsd-nat.c (i386bsd_fetch_inferior_registers): Likewise. (i386bsd_store_inferior_registers): Likewise. * i386gnu-nat.c (fetch_fpregs, gnu_fetch_registers, store_fpregs, gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register, store_register, fetch_regs, store_regs, fetch_fpregs, store_fpregs, fetch_fpxregs, store_fpxregs): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_register): Likewise. (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_register): Likewise. (ia64_linux_store_registers): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. (inf_child_store_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register): Likewise. (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_register): Likewise. (inf_ptrace_store_registers): Likewise. * infptrace.c (fetch_register, store_register): Likewise. (fetch_inferior_registers, store_inferior_registers): Likewise. * m32r-linux-nat.c (fetch_regs, store_regs): Likewise. (m32r_linux_fetch_inferior_registers): Likewise. (m32r_linux_store_inferior_registers): Likewise. * m68kbsd-nat.c (m68kbsd_fetch_inferior_registers): Likewise. (m68kbsd_store_inferior_registers): Likewise. * m68klinux-nat.c (fetch_register, old_fetch_inferior_registers, store_register, old_store_inferior_registers, fetch_regs, store_regs, fetch_fpregs, store_fpregs): Likewise. (m68k_linux_fetch_inferior_registers): Likewise. (m68k_linux_store_inferior_registers): Likewise. * m88kbsd-nat.c (m88kbsd_fetch_inferior_registers): Likewise. (m88kbsd_store_inferior_registers): Likewise. * mips64obsd-nat.c (mips64obsd_fetch_inferior_registers): Likewise. (mips64obsd_store_inferior_registers): Likewise. * mips-linux-nat.c (mips64_linux_regsets_fetch_registers): Likewise. (mips64_linux_regsets_store_registers): Likewise. (mips64_linux_fetch_registers): Likewise. (mips64_linux_store_registers): Likewise. * mipsnbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * monitor.c (monitor_fetch_register, monitor_store_register): Likewise. (monitor_fetch_registers, monitor_store_registers): Likewise. * nto-procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register, fetch_register, supply_vrregset, fetch_altivec_registers, fetch_ppc_registers, ppc_linux_fetch_inferior_registers): Likewise. (store_altivec_register, store_spe_register, store_register, fill_vrregset, store_altivec_registers, store_ppc_registers, ppc_linux_store_inferior_registers): Likewise. * ppcnbsd-nat.c (ppcnbsd_fetch_inferior_registers): Likewise. (ppcnbsd_store_inferior_registers): Likewise. * ppcobsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote.c (fetch_register_using_p, process_g_packet, fetch_registers_using_g, remote_fetch_registers): Likewise. (store_register_using_P, store_registers_using_G, remote_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers, m32r_fetch_register, m32r_store_register, m32r_store_register): Likewise. * remote-mips.c (mips_fetch_registers, mips_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * rs6000-nat.c (fetch_register, store_register): Likewise. (rs6000_fetch_inferior_registers): Likewise. (rs6000_store_inferior_registers): Likewise. * s390-nat.c (fetch_regs, store_regs): Likewise. (fetch_fpregs, store_fpregs): Likewise. (s390_linux_fetch_inferior_registers): Likewise. (s390_linux_store_inferior_registers): Likewise. * shnbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sol-thread.c (sol_thread_fetch_registers): Likewise. (sol_thread_store_registers): Likewise. * sparc-nat.c (fetch_inferior_registers): Likewise. (store_inferior_registers): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. (spu_store_inferior_registers): Likewise. * target.c (debug_print_register): Likewise. (debug_to_fetch_registers, debug_to_store_registers): Likewise. * vaxbsd-nat.c (vaxbsd_fetch_inferior_registers): Likewise. (vaxbsd_store_inferior_registers): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers): Likewise. (win32_fetch_inferior_registers): Likewise. (win32_store_inferior_registers): Likewise.
2007-05-06 22:34:38 +08:00
store_spe_register (regcache, tid, regno);
return;
}
[PowerPC] Add support for PPR and DSCR This patch adds gdb support for the Program Priorty Register and the Data Stream Control Register, for the powerpc linux native and core file targets, and for the powerpc linux server stub. gdb/ChangeLog: 2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * arch/ppc-linux-tdesc.h (tdesc_powerpc_isa205_ppr_dscr_vsx32l) (tdesc_powerpc_isa205_ppr_dscr_vsx64l): Declare. * arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_PPRREGSET) (PPC_LINUX_SIZEOF_DSCRREGSET): Define. (struct ppc_linux_features) <ppr_dscr>: New field. (ppc_linux_no_features): Add initializer for ppr_dscr field. * arch/ppc-linux-common.c (ppc_linux_match_description): Return new tdescs. * nat/ppc-linux.h (PPC_FEATURE2_DSCR, NT_PPC_PPR, NT_PPC_DSCR): Define if not already defined. * features/Makefile (WHICH): Add rs6000/powerpc-isa205-ppr-dscr-vsx32l and rs6000/powerpc-isa205-ppr-dscr-vsx64l. (XMLTOC): Add rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml and rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml. * features/rs6000/power-dscr.xml: New file. * features/rs6000/power-ppr.xml: New file. * features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml: New file. * features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml: New file. * features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.c: Generate. * features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.c: Generate. * regformats/rs6000/powerpc-isa205-ppr-dscr-vsx32l.dat: Generate. * regformats/rs6000/powerpc-isa205-ppr-dscr-vsx64l.dat: Generate. * ppc-linux-nat.c: Include <sys/uio.h>. (fetch_regset, store_regset, check_regset): New functions. (fetch_register, fetch_ppc_registers): Call fetch_regset with DSCR and PPR regsets. (store_register, store_ppc_registers): Call store_regset with DSCR and PPR regsets. (ppc_linux_get_hwcap2): New function. (ppc_linux_nat_target::read_description): Call ppc_linux_get_hwcap2 and check_regset, set ppr_dscr field in the features struct if needed. * ppc-linux-tdep.c: Include features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.c and features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.c. (ppc32_regmap_ppr, ppc32_regmap_dscr, ppc32_linux_pprregset) (ppc32_linux_dscrregset): New globals. (ppc_linux_iterate_over_regset_sections): Call back with the ppr and dscr regsets. (ppc_linux_core_read_description): Check if the ppr and dscr sections are present and set ppr_dscr in the features struct. (_initialize_ppc_linux_tdep): Call initialize_tdesc_powerpc_isa205_ppr_dscr_vsx32l and initialize_tdesc_powerpc_isa205_ppr_dscr_vsx64l. * ppc-linux-tdep.h (ppc32_linux_pprregset) (ppc32_linux_dscrregset): Declare. * ppc-tdep.h (struct gdbarch_tdep) <ppc_ppr_regnum>: New field. <ppc_dscr_regnum>: New field. (enum) <PPC_PPR_REGNUM, PPC_DSCR_REGNUM>: New enum values. * rs6000-tdep.c (rs6000_gdbarch_init): Look for and validate ppr and dscr features. (ppc_process_record_op31): Record changes to PPR and DSCR. gdb/gdbserver/ChangeLog: 2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * configure.srv (ipa_ppc_linux_regobj): Add powerpc-isa205-ppr-dscr-vsx32l-ipa.o and powerpc-isa205-ppr-dscr-vsx64l-ipa.o. (powerpc*-*-linux*): Add powerpc-isa205-ppr-dscr-vsx32l.o and powerpc-isa205-ppr-dscr-vsx64l.o to srv_regobj, add rs6000/power-dscr.xml, rs6000/power-ppr.xml, rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml and rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml to srv_xmlfiles. * linux-ppc-tdesc-init.h (enum ppc_linux_tdesc) <PPC_TDESC_ISA205_PPR_DSCR_VSX>: New enum value. (init_registers_powerpc_isa205_ppr_dscr_vsx32l) (init_registers_powerpc_isa205_ppr_dscr_vsx64l): Declare. * linux-ppc-low.c: Include "elf/common.h" and <sys/uio.h>. (ppc_hwcap): Add comment. (ppc_hwcap2): New global. (ppc_check_regset, ppc_fill_pprregset, ppc_store_pprregset) (ppc_fill_dscrregset, ppc_store_dscrregset): New functions. (ppc_regsets): Add entries for the DSCR and PPR regsets. (ppc_arch_setup): Get AT_HWCAP2. Set ppr_dscr in features struct when needed. Set sizes for the the DSCR and PPR regsets. (ppc_get_ipa_tdesc_idx): Return PPC_TDESC_ISA205_PPR_DSCR_VSX. (initialize_low_arch): Call init_registers_powerpc_isa205_ppr_dscr_vsx32l and init_registers_powerpc_isa205_ppr_dscr_vsx64l. * linux-ppc-ipa.c (get_ipa_tdesc): Handle PPC_TDESC_ISA205_PPR_DSCR_VSX. (initialize_low_tracepoint): Call init_registers_powerpc_isa205_ppr_dscr_vsx32l and init_registers_powerpc_isa205_ppr_dscr_vsx64l. gdb/testsuite/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.arch/powerpc-ppr-dscr.c: New file. * gdb.arch/powerpc-ppr-dscr.exp: New file. gdb/doc/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.texinfo (PowerPC Features): Describe new features "org.gnu.gdb.power.ppr" and "org.gnu.gdb.power.dscr".
2018-10-26 20:37:54 +08:00
else if (regno == PPC_DSCR_REGNUM)
{
gdb_assert (tdep->ppc_dscr_regnum != -1);
store_regset (regcache, tid, regno, NT_PPC_DSCR,
PPC_LINUX_SIZEOF_DSCRREGSET,
&ppc32_linux_dscrregset);
return;
}
else if (regno == PPC_PPR_REGNUM)
{
gdb_assert (tdep->ppc_ppr_regnum != -1);
store_regset (regcache, tid, regno, NT_PPC_PPR,
PPC_LINUX_SIZEOF_PPRREGSET,
&ppc32_linux_pprregset);
return;
}
[PowerPC] Add support for TAR This patch adds support for the Target Address Register for powerpc linux native and core file targets, and in the powerpc linux server stub. gdb/ChangeLog: 2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * arch/ppc-linux-tdesc.h (tdesc_powerpc_isa207_vsx32l) (tdesc_powerpc_isa207_vsx64l): Declare. * arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_TARREGSET): Define. (struct ppc_linux_features) <isa207>: New field. (ppc_linux_no_features): Add initializer for isa207 field. * arch/ppc-linux-common.c (ppc_linux_match_description): Return new tdescs. * nat/ppc-linux.h (PPC_FEATURE2_ARCH_2_07, PPC_FEATURE2_TAR) (NT_PPC_TAR): Define if not already defined. * features/Makefile (WHICH): Add rs6000/powerpc-isa207-vsx32l and rs6000/powerpc-isa207-vsx64l. (XMLTOC): Add rs6000/powerpc-isa207-vsx32l.xml and rs6000/powerpc-isa207-vsx64l.xml. * features/rs6000/power-tar.xml: New file. * features/rs6000/powerpc-isa207-vsx32l.xml: New file. * features/rs6000/powerpc-isa207-vsx64l.xml: New file. * features/rs6000/powerpc-isa207-vsx32l.c: Generate. * features/rs6000/powerpc-isa207-vsx64l.c: Generate. * regformats/rs6000/powerpc-isa207-vsx32l.dat: Generate. * regformats/rs6000/powerpc-isa207-vsx64l.dat: Generate. * ppc-linux-nat.c (fetch_register, fetch_ppc_registers): Call fetch_regset with the TAR regset. (store_register, store_ppc_registers): Call store_regset with the TAR regset. (ppc_linux_nat_target::read_description): Set isa207 field in the features struct if needed. * ppc-linux-tdep.c: Include features/rs6000/powerpc-isa207-vsx32l.c and features/rs6000/powerpc-isa207-vsx64l.c. (ppc32_regmap_tar, ppc32_linux_tarregset): New globals. (ppc_linux_iterate_over_regset_sections): Call back with the tar regset. (ppc_linux_core_read_description): Check if the tar section is present and set isa207 in the features struct. (_initialize_ppc_linux_tdep): Call initialize_tdesc_powerpc_isa207_vsx32l and initialize_tdesc_powerpc_isa207_vsx64l. * ppc-linux-tdep.h (ppc32_linux_tarregset): Declare. * ppc-tdep.h (gdbarch_tdep) <ppc_tar_regnum>: New field. (enum) <PPC_TAR_REGNUM>: New enum value. * rs6000-tdep.c (rs6000_gdbarch_init): Look for and validate tar feature. (ppc_process_record_op31): Record changes to TAR. gdb/gdbserver/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * configure.srv (ipa_ppc_linux_regobj): Add powerpc-isa207-vsx64l-ipa.o and powerpc-isa207-vsx32l-ipa.o. (powerpc*-*-linux*): Add powerpc-isa207-vsx32l.o and powerpc-isa207-vsx64l.o to srv_regobj, add rs6000/power-tar.xml, rs6000/powerpc-isa207-vsx32l.xml, and rs6000/powerpc-isa207-vsx64l.xml to srv_xmlfiles. * linux-ppc-tdesc-init.h (enum ppc_linux_tdesc) <PPC_TDESC_ISA207_VSX>: New enum value. (init_registers_powerpc_isa207_vsx32l): Declare. (init_registers_powerpc_isa207_vsx64l): Declare. * linux-ppc-low.c (ppc_fill_tarregset): New function. (ppc_store_tarregset): New function. (ppc_regsets): Add entry for the TAR regset. (ppc_arch_setup): Set isa207 in features struct when needed. Set size for the TAR regsets. (ppc_get_ipa_tdesc_idx): Return PPC_TDESC_ISA207_VSX. (initialize_low_arch): Call init_registers_powerpc_isa207_vsx32l and init_registers_powerpc_isa207_vsx64l. * linux-ppc-ipa.c (get_ipa_tdesc): Handle PPC_TDESC_ISA207_VSX. (initialize_low_tracepoint): Call init_registers_powerpc_isa207_vsx32l and init_registers_powerpc_isa207_vsx64l. gdb/testsuite/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.arch/powerpc-tar.c: New file. * gdb.arch/powerpc-tar.exp: New file. gdb/doc/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.texinfo (PowerPC Features): Describe new feature "org.gnu.gdb.power.tar".
2018-10-26 20:37:54 +08:00
else if (regno == PPC_TAR_REGNUM)
{
gdb_assert (tdep->ppc_tar_regnum != -1);
store_regset (regcache, tid, regno, NT_PPC_TAR,
PPC_LINUX_SIZEOF_TARREGSET,
&ppc32_linux_tarregset);
return;
}
[PowerPC] Add support for EBB and PMU registers This patch adds support for registers of the Event Based Branching and Performance Monitoring Units for the powerpc linux native and core file targets, and for the powerpc linux server stub. All three EBB registers are accessible. Only a subset of the PMU registers can be accessed through ptrace. Because of this, the PMU registers are enumerated individually in gdbarch_tdep, as opposed to having a single "have_pmu" flag. This is intended to make it easier to add additional PMU registers in the future, since checking a "have_pmu" flag elsewhere in the code would no longer be correct. The tdesc feature is named org.gnu.gdb.power.linux.pmu because of this. It's unclear if it makes sense to save and restore these registers across function calls, since some of them can be modified asynchronously. They are also not tracked in record-replay mode. The kernel can return ENODATA when ptrace is used to get the EBB registers, unless a linux performance event that uses EBB is open in the inferior. For this reason, the "fill" functions in the server stub for the ebb register sets is not implemented. Since gdbserver writes all registers in one go before resuming the inferior, this error would not be detected at the time the user tries to write to one of the registers on the client side, and gdbserver would print out warnings every time it resumes the inferior when no ebb performance event is opened, so there is currently no straightforward way to handle this case. This means the ebb registers in the client-side regcache can become dirty when the user tries to write to them, until the inferior is resumed and stopped again. A related issue is that 'G' packets used to write to unrelated registers will include bad data for the EBB registers if they are unavailable, since no register status information is included in the 'G' packet. This data won't be written to the inferior by the gdbserver stub because the "fill" functions are not implemented, and currently the gdbserver stub doesn't change the status of the registers in its own regcache in response to 'G' packets. Another limitation for the ebb registers is that traceframes don't record if registers are available or not, so if these registers are collected when a tracepoint is hit and the inferior has no ebb event opened, the user will see zero values for all of them, instead of the usual <unavailable>. Because these registers are often unavailable, trying to store them with target_store_registers with -1 for the regno argument (all registers) would almost always fail, so they are ignored in this case. gdb/ChangeLog: 2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_EBBREGSET) (PPC_LINUX_SIZEOF_PMUREGSET): Declare. * nat/ppc-linux.h (PPC_FEATURE2_EBB, NT_PPC_EBB, NT_PPC_PMU): Define if not already defined. * features/rs6000/power-ebb.xml: New file. * features/rs6000/power-linux-pmu.xml: New file. * features/rs6000/powerpc-isa207-vsx32l.xml: Include ebb and pmu features. * features/rs6000/powerpc-isa207-vsx64l.xml: Likewise. * features/rs6000/powerpc-isa207-vsx32l.c: Re-generate. * features/rs6000/powerpc-isa207-vsx64l.c: Re-generate. * regformats/rs6000/powerpc-isa207-vsx32l.dat: Re-generate. * regformats/rs6000/powerpc-isa207-vsx64l.dat: Re-generate. * ppc-linux-nat.c (fetch_register, fetch_ppc_registers): Call fetch_regset with ebb and pmu regsets. (store_register, store_ppc_registers): Call store_regset with ebb and pmu regsets. (ppc_linux_nat_target::read_description): Set isa207 field in the features struct if ebb and pmu are avaiable. * ppc-linux-tdep.c (ppc32_regmap_ebb, ppc32_regmap_pmu) (ppc32_linux_ebbregset, ppc32_linux_pmuregset): New globals. (ppc_linux_iterate_over_regset_sections): Call back with the ebb and pmu regsets. (ppc_linux_core_read_description): Check if the pmu section is present and set isa207 in the features struct. * ppc-linux-tdep.h (ppc32_linux_ebbregset) (ppc32_linux_pmuregset): Declare. * ppc-tdep.h (struct gdbarch_tdep) <ppc_mmcr0_regnum>: New field. <ppc_mmcr2_regnum, ppc_siar_regnum, ppc_sdar_regnum>: New fields. <ppc_sier_regnum>: New field. (enum): <PPC_BESCR_REGNUM, PPC_EBBHR_REGNUM, PPC_EBBRR_REGNUM>: New enum values. <PPC_MMCR0_REGNUM, PPC_MMCR2_REGNUM, PPC_SIAR_REGNUM>: New enum values. <PPC_SDAR_REGNUM, PPC_SIER_REGNUM>: New enum values. (PPC_IS_EBB_REGNUM, PPC_IS_PMU_REGNUM): Define. * rs6000-tdep.c (rs6000_gdbarch_init): Look for and validate the ebb and pmu features. gdb/gdbserver/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * configure.srv (powerpc*-*-linux*): Add rs6000/power-ebb.xml and rs6000/power-linux-pmu.xml to srv_xmlfiles. * linux-ppc-low.c (ppc_store_ebbregset, ppc_fill_pmuregset) (ppc_store_pmuregset): New functions. (ppc_regsets): Add entries for ebb and pmu regsets. (ppc_arch_setup): Set isa207 in features struct if the ebb and pmu regsets are available. Set sizes for these regsets. gdb/doc/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.texinfo (PowerPC Features): Describe new features "org.gnu.gdb.power.ebb" and "org.gnu.gdb.power.linux.pmu".
2018-10-26 20:37:54 +08:00
else if (PPC_IS_EBB_REGNUM (regno))
{
gdb_assert (tdep->have_ebb);
store_regset (regcache, tid, regno, NT_PPC_EBB,
PPC_LINUX_SIZEOF_EBBREGSET,
&ppc32_linux_ebbregset);
return;
}
else if (PPC_IS_PMU_REGNUM (regno))
{
gdb_assert (tdep->ppc_mmcr0_regnum != -1);
store_regset (regcache, tid, regno, NT_PPC_PMU,
PPC_LINUX_SIZEOF_PMUREGSET,
&ppc32_linux_pmuregset);
return;
}
[PowerPC] Add support for HTM registers This patch adds support for Hardware Transactional Memory registers for the powerpc linux native and core file targets, and for the pwoerpc linux server stub. These registers include both the HTM special-purpose registers (TFHAR, TEXASR and TFIAR) as well as the set of registers that are checkpointed (saved) when a transaction is initiated, which the processor restores in the event of a transaction failure. The set of checkpointed general-purpose registers is returned by the linux kernel in the same format as the regular general-purpose registers, defined in struct pt_regs. However, the architecture specifies that only some of the registers present in pt_regs are checkpointed (GPRs 0-31, CR, XER, LR and CTR). The kernel fills the slots for MSR and NIP with other info. The other fields usually don't have meaningful values. GDB doesn't define registers that are not checkpointed in the architecture, but when generating a core file, GDB fills the slot for the checkpointed MSR with the regular MSR. These are usually similar, although some bits might be different, and in some cases the checkpointed MSR will have a value of 0 in a kernel-generated core-file. The checkpointed NIP is filled with TFHAR by GDB in the core-file, which is what the kernel does. The other fields are set to 0 by GDB. Core files generated by the kernel have a note section for checkpointed GPRs with the same size for both 32-bit and 64-bit threads, and the values for the registers of a 32-bit thread are squeezed in the first half, with no useful data in the second half. GDB generates a smaller note section for 32-bit threads, but can read both sizes. The checkpointed XER is required to be 32-bit in the target description documentation, even though the more recent ISAs define it as 64-bit wide, since the high-order 32-bits are reserved, and because in Linux there is no way to get a 64-bit checkpointed XER for 32-bit threads. If this changes in the future, the target description feature requirement can be relaxed to allow for a 64-bit checkpointed XER. Access to the checkpointed CR (condition register) can be confusing. The architecture only specifies that CR fields 1 to 7 (the 24 least significant bits) are checkpointed, but the kernel provides all 8 fields (32 bits). The value of field 0 is not masked by ptrace, so it will sometimes show the result of some kernel operation, probably treclaim., which sets this field. The checkpointed registers are marked not to be saved and restored. Inferior function calls during an active transaction don't work well, and it's unclear what should be done in this case. TEXASR and TFIAR can be altered asynchronously, during transaction failure recording, so they are also not saved and restored. For consistency neither is TFHAR. Record and replay also doesn't work well when transactions are involved. This patch doesn't address this, so the values of the HTM SPRs will sometimes be innacurate when the record/relay target is enabled. For instance, executing a "tbegin." alters TFHAR and TEXASR, but these changes are not currently recorded. Because the checkpointed registers are only available when a transaction is active (or suspended), ptrace can return ENODATA when gdb tries to read these registers and the inferior is not in a transactional state. The registers are set to the unavailable state when this happens. When gbd tries to write to one of these registers, and it is unavailable, an error is raised. The "fill" functions for checkpointed register sets in the server stub are not implemented for the same reason as for the EBB register set, since ptrace can also return ENODATA for checkpointed regsets. The same issues with 'G' packets apply here. Just like for the EBB registers, tracepoints will not mark the checkpointed registers as unavailable if the inferior was not in a transaction, so their content will also show 0 instead of <unavailable> when inspecting trace data. The new tests record the values of the regular registers before stepping the inferior through a "tbegin." instruction to start a transaction, then the checkpointed registers are checked against the recorded pre-transactional values. New values are written to the checkpointed registers and recorded, the inferior continues until the transaction aborts (which is usually immediately when it is resumed), and the regular registers are checked against the recorded values, because the abort should have reverted the registers to these values. Like for the EBB registers, target_store_registers will ignore the checkpointed registers when called with -1 as the regno argument (store all registers in one go). gdb/ChangeLog: 2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * arch/ppc-linux-tdesc.h (tdesc_powerpc_isa207_htm_vsx32l) (tdesc_powerpc_isa207_htm_vsx64l): Declare. * arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_TM_SPRREGSET) (PPC32_LINUX_SIZEOF_CGPRREGSET, PPC64_LINUX_SIZEOF_CGPRREGSET) (PPC_LINUX_SIZEOF_CFPRREGSET, PPC_LINUX_SIZEOF_CVMXREGSET) (PPC_LINUX_SIZEOF_CVSXREGSET, PPC_LINUX_SIZEOF_CPPRREGSET) (PPC_LINUX_SIZEOF_CDSCRREGSET, PPC_LINUX_SIZEOF_CTARREGSET): Define. (struct ppc_linux_features) <htm>: New field. (ppc_linux_no_features): Add initializer for htm field. * arch/ppc-linux-common.c (ppc_linux_match_description): Return new tdescs. * nat/ppc-linux.h (PPC_FEATURE2_HTM, NT_PPC_TM_CGPR) (NT_PPC_TM_CFPR, NT_PPC_TM_CVMX, NT_PPC_TM_CVSX) (NT_PPC_TM_SPR, NT_PPC_TM_CTAR, NT_PPC_TM_CPPR, NT_PPC_TM_CDSCR): Define if not already defined. * features/Makefile (WHICH): Add rs6000/powerpc-isa207-htm-vsx32l and rs6000/powerpc-isa207-htm-vsx64l. (XMLTOC): Add rs6000/powerpc-isa207-htm-vsx32l.xml and rs6000/powerpc-isa207-htm-vsx64l.xml. * features/rs6000/power-htm-spr.xml: New file. * features/rs6000/power-htm-core.xml: New file. * features/rs6000/power64-htm-core.xml: New file. * features/rs6000/power-htm-fpu.xml: New file. * features/rs6000/power-htm-altivec.xml: New file. * features/rs6000/power-htm-vsx.xml: New file. * features/rs6000/power-htm-ppr.xml: New file. * features/rs6000/power-htm-dscr.xml: New file. * features/rs6000/power-htm-tar.xml: New file. * features/rs6000/powerpc-isa207-htm-vsx32l.xml: New file. * features/rs6000/powerpc-isa207-htm-vsx64l.xml: New file. * features/rs6000/powerpc-isa207-htm-vsx32l.c: Generate. * features/rs6000/powerpc-isa207-htm-vsx64l.c: Generate. * regformats/rs6000/powerpc-isa207-htm-vsx32l.dat: Generate. * regformats/rs6000/powerpc-isa207-htm-vsx64l.dat: Generate. * ppc-linux-nat.c (fetch_register, fetch_ppc_registers): Call fetch_regset with HTM regsets. (store_register, store_ppc_registers): Call store_regset with HTM regsets. (ppc_linux_nat_target::read_description): Set htm field in the features struct if needed. * ppc-linux-tdep.c: Include features/rs6000/powerpc-isa207-htm-vsx32l.c and features/rs6000/powerpc-isa207-htm-vsx64l.c. (ppc32_regmap_tm_spr, ppc32_regmap_cgpr, ppc64_le_regmap_cgpr) (ppc64_be_regmap_cgpr, ppc32_regmap_cfpr, ppc32_le_regmap_cvmx) (ppc32_be_regmap_cvmx, ppc32_regmap_cvsx, ppc32_regmap_cppr) (ppc32_regmap_cdscr, ppc32_regmap_ctar): New globals. (ppc32_linux_tm_sprregset, ppc32_linux_cgprregset) (ppc64_be_linux_cgprregset, ppc64_le_linux_cgprregset) (ppc32_linux_cfprregset, ppc32_le_linux_cvmxregset) (ppc32_be_linux_cvmxregset, ppc32_linux_cvsxregset) (ppc32_linux_cpprregset, ppc32_linux_cdscrregset) (ppc32_linux_ctarregset): New globals. (ppc_linux_cgprregset, ppc_linux_cvmxregset): New functions. (ppc_linux_collect_core_cpgrregset): New function. (ppc_linux_iterate_over_regset_sections): Call back with the htm regsets. (ppc_linux_core_read_description): Check if the tm spr section is present and set htm in the features struct. (_initialize_ppc_linux_tdep): Call initialize_tdesc_powerpc_isa207_htm_vsx32l and initialize_tdesc_powerpc_isa207_htm_vsx64l. * ppc-linux-tdep.h (ppc_linux_cgprregset, ppc_linux_cvmxregset): Declare. (ppc32_linux_tm_sprregset, ppc32_linux_cfprregset) (ppc32_linux_cvsxregset, ppc32_linux_cpprregset) (ppc32_linux_cdscrregset, ppc32_linux_ctarregset): Declare. * ppc-tdep.h (struct gdbarch_tdep) <have_htm_spr, have_htm_core>: New fields. <have_htm_fpu, have_htm_altivec, have_htm_vsx>: Likewise. <ppc_cppr_regnum, ppc_cdscr_regnum, ppc_ctar_regnum>: Likewise. <ppc_cdl0_regnum, ppc_cvsr0_regnum, ppc_cefpr0_regnum>: Likewise. (enum) <PPC_TFHAR_REGNUM, PPC_TEXASR_REGNUM, PPC_TFIAR_REGNUM>: New enum fields. <PPC_CR0_REGNUM, PPC_CCR_REGNUM, PPC_CXER_REGNUM>: Likewise. <PPC_CLR_REGNUM, PPC_CCTR_REGNUM, PPC_CF0_REGNUM>: Likewise. <PPC_CFPSCR_REGNUM, PPC_CVR0_REGNUM, PPC_CVSCR_REGNUM>: Likewise. <PPC_CVRSAVE_REGNUM, PPC_CVSR0_UPPER_REGNUM>: Likewise. <PPC_CPPR_REGNUM, PPC_CDSCR_REGNUM>: Likewise. <PPC_CTAR_REGNUM>: Likewise. (PPC_IS_TMSPR_REGNUM, PPC_IS_CKPTGP_REGNUM, PPC_IS_CKPTFP_REGNUM) (PPC_IS_CKPTVMX_REGNUM, PPC_IS_CKPTVSX_REGNUM): Define. * rs6000-tdep.c (IS_CDFP_PSEUDOREG, IS_CVSX_PSEUDOREG) (IS_CEFP_PSEUDOREG): Define. (rs6000_register_name): Hide the upper halves of checkpointed VSX registers. Return names for the checkpointed DFP, VSX, and EFP pseudo registers. (rs6000_pseudo_register_type): Remove initial assert and raise an internal error in the else clause instead. Return types for the checkpointed DFP, VSX, and EFP pseudo registers. (dfp_pseudo_register_read, dfp_pseudo_register_write): Handle checkpointed DFP pseudo registers. (vsx_pseudo_register_read, vsx_pseudo_register_write): Handle checkpointed VSX pseudo registers. (efp_pseudo_register_read, efp_pseudo_register_write): Rename from efpr_pseudo_register_read and efpr_pseudo_register_write. Handle checkpointed EFP pseudo registers. (rs6000_pseudo_register_read, rs6000_pseudo_register_write): Handle checkpointed DFP, VSX, and EFP registers. (dfp_ax_pseudo_register_collect, vsx_ax_pseudo_register_collect) (efp_ax_pseudo_register_collect): New functions. (rs6000_ax_pseudo_register_collect): Move DFP, VSX and EFP pseudo register logic to new functions. Handle checkpointed DFP, VSX, and EFP pseudo registers. (rs6000_gdbarch_init): Look for and validate the htm features. Include checkpointed DFP, VSX and EFP pseudo-registers. * NEWS: Mention access to PPR, DSCR, TAR, EBB/PMU registers and HTM registers. gdb/gdbserver/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * configure.srv (ipa_ppc_linux_regobj): Add powerpc-isa207-htm-vsx32l-ipa.o and powerpc-isa207-htm-vsx64l-ipa.o. (powerpc*-*-linux*): Add powerpc-isa207-htm-vsx32l.o and powerpc-isa207-htm-vsx64l.o to srv_regobj. Add rs6000/power-htm-spr.xml, rs6000/power-htm-core.xml, rs6000/power64-htm-core.xml, rs6000/power-htm-fpu.xml, rs6000/power-htm-altivec.xml, rs6000/power-htm-vsx.xml, rs6000/power-htm-ppr.xml, rs6000/power-htm-dscr.xml, rs6000/power-htm-tar.xml, rs6000/powerpc-isa207-htm-vsx32l.xml, and rs6000/powerpc-isa207-htm-vsx64l.xml to srv_xmlfiles. * linux-ppc-tdesc-init.h (enum ppc_linux_tdesc) <PPC_TDESC_ISA207_HTM_VSX>: New enum value. (init_registers_powerpc_isa207_htm_vsx32l) (init_registers_powerpc_isa207_htm_vsx64l): Declare. * linux-ppc-low.c (ppc_fill_tm_sprregset, ppc_store_tm_sprregset) (ppc_store_tm_cgprregset, ppc_store_tm_cfprregset) (ppc_store_tm_cvrregset, ppc_store_tm_cvsxregset) (ppc_store_tm_cpprregset, ppc_store_tm_cdscrregset) (ppc_store_tm_ctarregset): New functions. (ppc_regsets): Add entries for HTM regsets. (ppc_arch_setup): Set htm in features struct when needed. Set sizes for the HTM regsets. (ppc_get_ipa_tdesc_idx): Return PPC_TDESC_ISA207_HTM_VSX. (initialize_low_arch): Call init_registers_powerpc_isa207_htm_vsx32l and init_registers_powerpc_isa207_htm_vsx64l. * linux-ppc-ipa.c (get_ipa_tdesc): Handle PPC_TDESC_ISA207_HTM_VSX. (initialize_low_tracepoint): Call init_registers_powerpc_isa207_htm_vsx32l and init_registers_powerpc_isa207_htm_vsx64l. gdb/testsuite/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.arch/powerpc-htm-regs.c: New file. * gdb.arch/powerpc-htm-regs.exp: New file. gdb/doc/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.texinfo (PowerPC Features): Describe new features "org.gnu.gdb.power.htm.spr", "org.gnu.gdb.power.htm.core", "org.gnu.gdb.power.htm.fpu", "org.gnu.gdb.power.htm.altivec", "org.gnu.gdb.power.htm.vsx", "org.gnu.gdb.power.htm.ppr", "org.gnu.gdb.power.htm.dscr", "org.gnu.gdb.power.htm.tar".
2018-10-26 20:37:55 +08:00
else if (PPC_IS_TMSPR_REGNUM (regno))
{
gdb_assert (tdep->have_htm_spr);
store_regset (regcache, tid, regno, NT_PPC_TM_SPR,
PPC_LINUX_SIZEOF_TM_SPRREGSET,
&ppc32_linux_tm_sprregset);
return;
}
else if (PPC_IS_CKPTGP_REGNUM (regno))
{
gdb_assert (tdep->have_htm_core);
const struct regset *cgprregset = ppc_linux_cgprregset (gdbarch);
store_regset (regcache, tid, regno, NT_PPC_TM_CGPR,
(tdep->wordsize == 4?
PPC32_LINUX_SIZEOF_CGPRREGSET
: PPC64_LINUX_SIZEOF_CGPRREGSET),
cgprregset);
return;
}
else if (PPC_IS_CKPTFP_REGNUM (regno))
{
gdb_assert (tdep->have_htm_fpu);
store_regset (regcache, tid, regno, NT_PPC_TM_CFPR,
PPC_LINUX_SIZEOF_CFPRREGSET,
&ppc32_linux_cfprregset);
return;
}
else if (PPC_IS_CKPTVMX_REGNUM (regno))
{
gdb_assert (tdep->have_htm_altivec);
const struct regset *cvmxregset = ppc_linux_cvmxregset (gdbarch);
store_regset (regcache, tid, regno, NT_PPC_TM_CVMX,
PPC_LINUX_SIZEOF_CVMXREGSET,
cvmxregset);
return;
}
else if (PPC_IS_CKPTVSX_REGNUM (regno))
{
gdb_assert (tdep->have_htm_vsx);
store_regset (regcache, tid, regno, NT_PPC_TM_CVSX,
PPC_LINUX_SIZEOF_CVSXREGSET,
&ppc32_linux_cvsxregset);
return;
}
else if (regno == PPC_CPPR_REGNUM)
{
gdb_assert (tdep->ppc_cppr_regnum != -1);
store_regset (regcache, tid, regno, NT_PPC_TM_CPPR,
PPC_LINUX_SIZEOF_CPPRREGSET,
&ppc32_linux_cpprregset);
return;
}
else if (regno == PPC_CDSCR_REGNUM)
{
gdb_assert (tdep->ppc_cdscr_regnum != -1);
store_regset (regcache, tid, regno, NT_PPC_TM_CDSCR,
PPC_LINUX_SIZEOF_CDSCRREGSET,
&ppc32_linux_cdscrregset);
return;
}
else if (regno == PPC_CTAR_REGNUM)
{
gdb_assert (tdep->ppc_ctar_regnum != -1);
store_regset (regcache, tid, regno, NT_PPC_TM_CTAR,
PPC_LINUX_SIZEOF_CTARREGSET,
&ppc32_linux_ctarregset);
return;
}
if (regaddr == -1)
return;
/* First collect the register. Keep in mind that the regcache's
idea of the register's size may not be a multiple of sizeof
(long). */
memset (buf, 0, sizeof buf);
2007-11-16 Markus Deuling <deuling@de.ibm.com> * m32r-rom.c (m32r_supply_register): Use get_regcache_arch to get at the current architecture by regcache. * ppcnbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register) (fetch_register, supply_vrregset, fetch_ppc_registers) (store_altivec_register, store_spe_register, store_register) (fill_vrregset, store_ppc_registers): Likewise. * ppcobsd-nat.c (ppcobsd_supply_pcb): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers) (do_win32_store_inferior_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers) (m32r_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register, gdbsim_store_register): Likewise. * trad-frame.c (trad_frame_alloc_saved_regs): Replace current_gdbarch by gdbarch. * user-regs.c (user_reg_map_name_to_regnum): Likewise. * ppc-sysv-tdep.c (ppc_sysv_abi_push_dummy_call) (do_ppc_sysv_return_value, ppc64_sysv_abi_push_dummy_call) (ppc64_sysv_abi_return_value): Likewise. * m32c-tdep.c (m32c_register_reggroup_p): Likewise. * m2-lang.c (build_m2_types): Likewise. * ppc-linux-tdep.c (ppc_linux_sigtramp_cache * ppcnbsd-tdep.c (ppcnbsd_sigtramp_cache_init): Likewise. * ppcobsd-tdep.c (ppcobsd_sigtramp_frame_cache): Likewise. * rs6000-tdep.c (ppc_dwarf2_frame_init_reg): Likewise. * m68hc11-tdep.c (m68hc11_frame_unwind_cache): Use get_frame_arch to get at the current architecture by frame_info. * gcore.c (derive_stack_segment): Likewise. * shnbsd-nat.c (GETREGS_SUPPLIES): Add gdbarch parameter. (shnbsd_fetch_inferior_registers, shnbsd_store_inferior_registers): Add gdbarch to GETREGS_SUPPLIES call.
2007-11-16 12:53:46 +08:00
bytes_to_transfer = align_up (register_size (gdbarch, regno), sizeof (long));
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
{
/* Little-endian values always sit at the left end of the buffer. */
regcache->raw_collect (regno, buf);
}
2007-11-16 Markus Deuling <deuling@de.ibm.com> * m32r-rom.c (m32r_supply_register): Use get_regcache_arch to get at the current architecture by regcache. * ppcnbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register) (fetch_register, supply_vrregset, fetch_ppc_registers) (store_altivec_register, store_spe_register, store_register) (fill_vrregset, store_ppc_registers): Likewise. * ppcobsd-nat.c (ppcobsd_supply_pcb): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers) (do_win32_store_inferior_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers) (m32r_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register, gdbsim_store_register): Likewise. * trad-frame.c (trad_frame_alloc_saved_regs): Replace current_gdbarch by gdbarch. * user-regs.c (user_reg_map_name_to_regnum): Likewise. * ppc-sysv-tdep.c (ppc_sysv_abi_push_dummy_call) (do_ppc_sysv_return_value, ppc64_sysv_abi_push_dummy_call) (ppc64_sysv_abi_return_value): Likewise. * m32c-tdep.c (m32c_register_reggroup_p): Likewise. * m2-lang.c (build_m2_types): Likewise. * ppc-linux-tdep.c (ppc_linux_sigtramp_cache * ppcnbsd-tdep.c (ppcnbsd_sigtramp_cache_init): Likewise. * ppcobsd-tdep.c (ppcobsd_sigtramp_frame_cache): Likewise. * rs6000-tdep.c (ppc_dwarf2_frame_init_reg): Likewise. * m68hc11-tdep.c (m68hc11_frame_unwind_cache): Use get_frame_arch to get at the current architecture by frame_info. * gcore.c (derive_stack_segment): Likewise. * shnbsd-nat.c (GETREGS_SUPPLIES): Add gdbarch parameter. (shnbsd_fetch_inferior_registers, shnbsd_store_inferior_registers): Add gdbarch to GETREGS_SUPPLIES call.
2007-11-16 12:53:46 +08:00
else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
{
/* Big-endian values sit at the right end of the buffer. */
2007-11-16 Markus Deuling <deuling@de.ibm.com> * m32r-rom.c (m32r_supply_register): Use get_regcache_arch to get at the current architecture by regcache. * ppcnbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register) (fetch_register, supply_vrregset, fetch_ppc_registers) (store_altivec_register, store_spe_register, store_register) (fill_vrregset, store_ppc_registers): Likewise. * ppcobsd-nat.c (ppcobsd_supply_pcb): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers) (do_win32_store_inferior_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers) (m32r_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register, gdbsim_store_register): Likewise. * trad-frame.c (trad_frame_alloc_saved_regs): Replace current_gdbarch by gdbarch. * user-regs.c (user_reg_map_name_to_regnum): Likewise. * ppc-sysv-tdep.c (ppc_sysv_abi_push_dummy_call) (do_ppc_sysv_return_value, ppc64_sysv_abi_push_dummy_call) (ppc64_sysv_abi_return_value): Likewise. * m32c-tdep.c (m32c_register_reggroup_p): Likewise. * m2-lang.c (build_m2_types): Likewise. * ppc-linux-tdep.c (ppc_linux_sigtramp_cache * ppcnbsd-tdep.c (ppcnbsd_sigtramp_cache_init): Likewise. * ppcobsd-tdep.c (ppcobsd_sigtramp_frame_cache): Likewise. * rs6000-tdep.c (ppc_dwarf2_frame_init_reg): Likewise. * m68hc11-tdep.c (m68hc11_frame_unwind_cache): Use get_frame_arch to get at the current architecture by frame_info. * gcore.c (derive_stack_segment): Likewise. * shnbsd-nat.c (GETREGS_SUPPLIES): Add gdbarch parameter. (shnbsd_fetch_inferior_registers, shnbsd_store_inferior_registers): Add gdbarch to GETREGS_SUPPLIES call.
2007-11-16 12:53:46 +08:00
size_t padding = (bytes_to_transfer - register_size (gdbarch, regno));
regcache->raw_collect (regno, buf + padding);
}
for (i = 0; i < bytes_to_transfer; i += sizeof (long))
{
long l;
memcpy (&l, &buf[i], sizeof (l));
errno = 0;
ptrace (PTRACE_POKEUSER, tid, (PTRACE_TYPE_ARG3) regaddr, l);
regaddr += sizeof (long);
if (errno == EIO
ChangeLog: * Makefile.in (ppc_linux_tdep_h): New macro. (powerpc_32l_c, powerpc_altivec32_c, powerpc_altivec32l_c): Likewise. (powerpc_64l_c, powerpc_altivec64_c, powerpc_altivec64l_c): Likewise. (powerpc_e500l_c): Likewise. (ppc-linux-nat.o): Update dependencies. (ppc-linux-tdep.o): Update dependencies. (rs6000-tdep.o): Update dependencies. * ppc-tdep.h (ppc_linux_memory_remove_breakpoint): Remove. (ppc_linux_svr4_fetch_link_map_offsets): Remove. (ppc_linux_gregset, ppc_linux_fpregset): Move to ppc-linux-tdep.h (ppc_supply_reg, ppc_collect_reg): Add prototypes. (tdesc_powerpc_e500): Remove. * rs6000.c: Include "features/rs6000/powerpc-altivec32.c" and "features/rs6000/powerpc-altivec64.c". (ppc_supply_reg, ppc_collect_reg): Make global. (variants): Use tdesc_powerpc_32 for "powerpc" and tdesc_powerpc_altivec64 for "powerpc64". (_initialize_rs6000_tdep): Initialize AltiVec descriptions. * ppc-linux-tdep.h: New file. * ppc-linux-tdep.c: Include "ppc-linux-tdep.c". Include "features/rs6000/powerpc-32l.c". Include "features/rs6000/powerpc-altivec32l.c". Include "features/rs6000/powerpc-64l.c". Include "features/rs6000/powerpc-altivec64l.c". Include "features/rs6000/powerpc-e500l.c". (ppc_linux_supply_gregset): New function. (ppc_linux_collect_gregset): Handle orig_r3 and trap registers. (ppc32_linux_gregset): Use ppc_linux_supply_gregset. (ppc64_linux_gregset): Likewise. (ppc_linux_sigtramp_cache): Handle orig_r3 and trap registers. (ppc_linux_trap_reg_p): New function. (ppc_linux_write_pc): New function. (ppc_linux_core_read_description): New function. (ppc_linux_init_abi): Install ppc_linux_write_pc and ppc_linux_core_read_description. Install orig_r3 and trap registers if present in the target description. (_initialize_ppc_linux_tdep): Initialize Linux target descriptions. * ppc-linux-nat.c: Include "ppc-linux-tdep.h". (PT_ORIG_R3, PT_TRAP): Define if necessary. (ppc_register_u_addr): Handle orig_r3 and trap registers. (fetch_ppc_registers): Likewise. (store_ppc_registers): Likewise. (store_register): Likewise. (ppc_linux_read_description): Check whether AltiVec is supported. Check whether inferior is 32-bit or 64-bit. Return the appropriate Linux target description. * features/Makefile (WHICH): Use rs6000/powerpc-32l and rs6000/powerpc-altivec32l instead of rs6000/powerpc-32. Use rs6000/powerpc-64l and rs6000/powerpc-altivec64l instead of rs6000/powerpc-64. Use rs6000/powerpc-e500l instead of rs6000/powerpc-e500. Update -expedite variables accordingly. * features/rs6000/power-spe.xml: Use regnum 73 for "acc". * features/rs6000/powerpc-32.xml: Do not include power-altivec.xml. * features/rs6000/powerpc-64.xml: Do not include power-altivec.xml. * features/rs6000/powerpc-e500.c: Regenerate. * features/rs6000/powerpc-32.c: Regenerate. * features/rs6000/powerpc-64.c: Regenerate. * features/rs6000/power-linux.xml: New file. * features/rs6000/power64-linux.xml: New file. * features/rs6000/powerpc-32l.xml: New file. * features/rs6000/powerpc-altivec32l.xml: New file. * features/rs6000/powerpc-64l.xml: New file. * features/rs6000/powerpc-altivec64l.xml: New file. * features/rs6000/powerpc-e500l.xml: New file. * features/rs6000/powerpc-32l.c: New (generated) file. * features/rs6000/powerpc-altivec32l.c: New (generated) file. * features/rs6000/powerpc-64l.c: New (generated) file. * features/rs6000/powerpc-altivec64l.c: New (generated) file. * features/rs6000/powerpc-e500l.xml: New (generated) file. * regformats/reg-ppc.dat: Remove. * regformats/reg-ppc64.dat: Remove. * regformats/rs6000/powerpc-32.dat: Remove. * regformats/rs6000/powerpc-64.dat: Remove. * regformats/rs6000/powerpc-e500.dat: Remove. * regformats/rs6000/powerpc-32l.dat: New (generated) file. * regformats/rs6000/powerpc-altivec32l.dat: New (generated) file. * regformats/rs6000/powerpc-64l.dat: New (generated) file. * regformats/rs6000/powerpc-altivec64l.dat: New (generated) file. * regformats/rs6000/powerpc-e500l.dat: New (generated) file. gdbserver/ChangeLog: * configure.srv (powerpc*-*-linux*): Set srv_regobj to powerpc-32l.o, powerpc-altivec32l.o, powerpc-e500l.o, powerpc-64l.o, and powerpc-altivec64l.o. Remove rs6000/powerpc-32.xml, rs6000/powerpc-64.xml, and rs6000/powerpc-e500.xml; add rs6000/powerpc-32l.xml, rs6000/powerpc-altivec32l.xml, rs6000/powerpc-e500l.xml, rs6000/powerpc-64l.xml, rs6000/powerpc-altivec64l.xml, rs6000/power-linux.xml, and rs6000/power64-linux.xml to srv_xmlfiles. * Makefile.in (reg-ppc.o, reg-ppc.c): Remove, replace by ... (powerpc-32l.o, powerpc-32l.c): ... these new rules. (powerpc-32.o, powerpc-32.c): Remove, replace by ... (powerpc-altivec32l.o, powerpc-altivec32l.c): ... these new rules. (powerpc-e500.o, powerpc-e500.c): Remove, replace by ... (powerpc-e500l.o, powerpc-e500l.c): ... these new rules. (reg-ppc64.o, reg-ppc64.c): Remove, replace by ... (powerpc-64l.o, powerpc-64l.c): ... these new rules. (powerpc-64.o, powerpc-64.c): Remove, replace by ... (powerpc-altivec64l.o, powerpc-altivec64l.c): ... these new rules. (clean): Update. * linux-ppc-low.c (init_registers_ppc): Remove, replace by ... (init_registers_powerpc_32l): ... this new prototype. (init_registers_powerpc_32): Remove, replace by ... (init_registers_powerpc_altivec32l): ... this new prototype. (init_registers_powerpc_e500): Remove, replace by ... (init_registers_powerpc_e500l): ... this new prototype. (init_registers_ppc64): Remove, replace by ... (init_registers_powerpc_64l): ... this new prototype. (init_registers_powerpc_64): Remove, replace by ... (init_registers_powerpc_altivec64l): ... this new prototype. (ppc_num_regs): Set to 73. (PT_ORIG_R3, PT_TRAP): Define if necessary. (ppc_regmap, ppc_regmap_e500): Add values for orig_r3 and trap. (ppc_cannot_store_register): Handle orig_r3 and trap. (ppc_arch_setup): Update init_registers_... calls. (ppc_fill_gregset): Handle orig_r3 and trap. * inferiors.c (clear_inferiors): Reset current_inferior.
2008-05-04 01:16:44 +08:00
&& (regno == tdep->ppc_fpscr_regnum
|| regno == PPC_ORIG_R3_REGNUM
|| regno == PPC_TRAP_REGNUM))
{
ChangeLog: * Makefile.in (ppc_linux_tdep_h): New macro. (powerpc_32l_c, powerpc_altivec32_c, powerpc_altivec32l_c): Likewise. (powerpc_64l_c, powerpc_altivec64_c, powerpc_altivec64l_c): Likewise. (powerpc_e500l_c): Likewise. (ppc-linux-nat.o): Update dependencies. (ppc-linux-tdep.o): Update dependencies. (rs6000-tdep.o): Update dependencies. * ppc-tdep.h (ppc_linux_memory_remove_breakpoint): Remove. (ppc_linux_svr4_fetch_link_map_offsets): Remove. (ppc_linux_gregset, ppc_linux_fpregset): Move to ppc-linux-tdep.h (ppc_supply_reg, ppc_collect_reg): Add prototypes. (tdesc_powerpc_e500): Remove. * rs6000.c: Include "features/rs6000/powerpc-altivec32.c" and "features/rs6000/powerpc-altivec64.c". (ppc_supply_reg, ppc_collect_reg): Make global. (variants): Use tdesc_powerpc_32 for "powerpc" and tdesc_powerpc_altivec64 for "powerpc64". (_initialize_rs6000_tdep): Initialize AltiVec descriptions. * ppc-linux-tdep.h: New file. * ppc-linux-tdep.c: Include "ppc-linux-tdep.c". Include "features/rs6000/powerpc-32l.c". Include "features/rs6000/powerpc-altivec32l.c". Include "features/rs6000/powerpc-64l.c". Include "features/rs6000/powerpc-altivec64l.c". Include "features/rs6000/powerpc-e500l.c". (ppc_linux_supply_gregset): New function. (ppc_linux_collect_gregset): Handle orig_r3 and trap registers. (ppc32_linux_gregset): Use ppc_linux_supply_gregset. (ppc64_linux_gregset): Likewise. (ppc_linux_sigtramp_cache): Handle orig_r3 and trap registers. (ppc_linux_trap_reg_p): New function. (ppc_linux_write_pc): New function. (ppc_linux_core_read_description): New function. (ppc_linux_init_abi): Install ppc_linux_write_pc and ppc_linux_core_read_description. Install orig_r3 and trap registers if present in the target description. (_initialize_ppc_linux_tdep): Initialize Linux target descriptions. * ppc-linux-nat.c: Include "ppc-linux-tdep.h". (PT_ORIG_R3, PT_TRAP): Define if necessary. (ppc_register_u_addr): Handle orig_r3 and trap registers. (fetch_ppc_registers): Likewise. (store_ppc_registers): Likewise. (store_register): Likewise. (ppc_linux_read_description): Check whether AltiVec is supported. Check whether inferior is 32-bit or 64-bit. Return the appropriate Linux target description. * features/Makefile (WHICH): Use rs6000/powerpc-32l and rs6000/powerpc-altivec32l instead of rs6000/powerpc-32. Use rs6000/powerpc-64l and rs6000/powerpc-altivec64l instead of rs6000/powerpc-64. Use rs6000/powerpc-e500l instead of rs6000/powerpc-e500. Update -expedite variables accordingly. * features/rs6000/power-spe.xml: Use regnum 73 for "acc". * features/rs6000/powerpc-32.xml: Do not include power-altivec.xml. * features/rs6000/powerpc-64.xml: Do not include power-altivec.xml. * features/rs6000/powerpc-e500.c: Regenerate. * features/rs6000/powerpc-32.c: Regenerate. * features/rs6000/powerpc-64.c: Regenerate. * features/rs6000/power-linux.xml: New file. * features/rs6000/power64-linux.xml: New file. * features/rs6000/powerpc-32l.xml: New file. * features/rs6000/powerpc-altivec32l.xml: New file. * features/rs6000/powerpc-64l.xml: New file. * features/rs6000/powerpc-altivec64l.xml: New file. * features/rs6000/powerpc-e500l.xml: New file. * features/rs6000/powerpc-32l.c: New (generated) file. * features/rs6000/powerpc-altivec32l.c: New (generated) file. * features/rs6000/powerpc-64l.c: New (generated) file. * features/rs6000/powerpc-altivec64l.c: New (generated) file. * features/rs6000/powerpc-e500l.xml: New (generated) file. * regformats/reg-ppc.dat: Remove. * regformats/reg-ppc64.dat: Remove. * regformats/rs6000/powerpc-32.dat: Remove. * regformats/rs6000/powerpc-64.dat: Remove. * regformats/rs6000/powerpc-e500.dat: Remove. * regformats/rs6000/powerpc-32l.dat: New (generated) file. * regformats/rs6000/powerpc-altivec32l.dat: New (generated) file. * regformats/rs6000/powerpc-64l.dat: New (generated) file. * regformats/rs6000/powerpc-altivec64l.dat: New (generated) file. * regformats/rs6000/powerpc-e500l.dat: New (generated) file. gdbserver/ChangeLog: * configure.srv (powerpc*-*-linux*): Set srv_regobj to powerpc-32l.o, powerpc-altivec32l.o, powerpc-e500l.o, powerpc-64l.o, and powerpc-altivec64l.o. Remove rs6000/powerpc-32.xml, rs6000/powerpc-64.xml, and rs6000/powerpc-e500.xml; add rs6000/powerpc-32l.xml, rs6000/powerpc-altivec32l.xml, rs6000/powerpc-e500l.xml, rs6000/powerpc-64l.xml, rs6000/powerpc-altivec64l.xml, rs6000/power-linux.xml, and rs6000/power64-linux.xml to srv_xmlfiles. * Makefile.in (reg-ppc.o, reg-ppc.c): Remove, replace by ... (powerpc-32l.o, powerpc-32l.c): ... these new rules. (powerpc-32.o, powerpc-32.c): Remove, replace by ... (powerpc-altivec32l.o, powerpc-altivec32l.c): ... these new rules. (powerpc-e500.o, powerpc-e500.c): Remove, replace by ... (powerpc-e500l.o, powerpc-e500l.c): ... these new rules. (reg-ppc64.o, reg-ppc64.c): Remove, replace by ... (powerpc-64l.o, powerpc-64l.c): ... these new rules. (powerpc-64.o, powerpc-64.c): Remove, replace by ... (powerpc-altivec64l.o, powerpc-altivec64l.c): ... these new rules. (clean): Update. * linux-ppc-low.c (init_registers_ppc): Remove, replace by ... (init_registers_powerpc_32l): ... this new prototype. (init_registers_powerpc_32): Remove, replace by ... (init_registers_powerpc_altivec32l): ... this new prototype. (init_registers_powerpc_e500): Remove, replace by ... (init_registers_powerpc_e500l): ... this new prototype. (init_registers_ppc64): Remove, replace by ... (init_registers_powerpc_64l): ... this new prototype. (init_registers_powerpc_64): Remove, replace by ... (init_registers_powerpc_altivec64l): ... this new prototype. (ppc_num_regs): Set to 73. (PT_ORIG_R3, PT_TRAP): Define if necessary. (ppc_regmap, ppc_regmap_e500): Add values for orig_r3 and trap. (ppc_cannot_store_register): Handle orig_r3 and trap. (ppc_arch_setup): Update init_registers_... calls. (ppc_fill_gregset): Handle orig_r3 and trap. * inferiors.c (clear_inferiors): Reset current_inferior.
2008-05-04 01:16:44 +08:00
/* Some older kernel versions don't allow fpscr, orig_r3
or trap to be written. */
continue;
}
if (errno != 0)
{
char message[128];
xsnprintf (message, sizeof (message), "writing register %s (#%d)",
gdbarch_register_name (gdbarch, regno), regno);
perror_with_name (message);
}
}
}
/* This function actually issues the request to ptrace, telling
it to store all general-purpose registers present in the specified
regset.
If the ptrace request does not exist, this function returns 0
and properly sets the have_ptrace_* flag. If the request fails,
this function calls perror_with_name. Otherwise, if the request
succeeds, then the regcache is stored and 1 is returned. */
static int
store_all_gp_regs (const struct regcache *regcache, int tid, int regno)
{
gdb_gregset_t gregset;
if (ptrace (PTRACE_GETREGS, tid, 0, (void *) &gregset) < 0)
{
if (errno == EIO)
{
have_ptrace_getsetregs = 0;
return 0;
}
perror_with_name (_("Couldn't get general-purpose registers."));
}
fill_gregset (regcache, &gregset, regno);
if (ptrace (PTRACE_SETREGS, tid, 0, (void *) &gregset) < 0)
{
if (errno == EIO)
{
have_ptrace_getsetregs = 0;
return 0;
}
perror_with_name (_("Couldn't set general-purpose registers."));
}
return 1;
}
/* This is a wrapper for the store_all_gp_regs function. It is
responsible for verifying if this target has the ptrace request
that can be used to store all general-purpose registers at one
shot. If it doesn't, then we should store them using the
old-fashioned way, which is to iterate over the registers and
store them one by one. */
static void
store_gp_regs (const struct regcache *regcache, int tid, int regno)
{
s/get_regcache_arch (regcache)/regcache->arch ()/g This patches removes get_regcache_arch, and use regache->arch () instead. The motivation of this change is that I am going to move some basic stuff into a base class of regcache. I don't need to update "client" code regcache->arch (). On the other hand, this patch shortens the code a little bit. gdb: 2017-10-25 Yao Qi <yao.qi@linaro.org> * aarch32-linux-nat.c (aarch32_gp_regcache_supply): Use regcache->arch () instead get_regcache_arch. * aarch64-fbsd-nat.c (aarch64_fbsd_fetch_inferior_registers): Likewise. (aarch64_fbsd_store_inferior_registers): Likewise. * aarch64-linux-nat.c (fetch_gregs_from_thread): Likewise. (store_gregs_to_thread): Likewise. (fetch_fpregs_from_thread): Likewise. (store_fpregs_to_thread): Likewise. * aarch64-tdep.c (aarch64_extract_return_value): Likewise. (aarch64_store_return_value): Likewise. (aarch64_software_single_step): Likewise. * aix-thread.c (aix_thread_wait): Likewise. (supply_reg32): Likewise. (supply_sprs64): Likewise. (supply_sprs32): Likewise. (fill_gprs64): Likewise. (fill_gprs32): Likewise. (fill_sprs64): Likewise. (fill_sprs32): Likewise. (store_regs_user_thread): Likewise. (store_regs_kernel_thread): Likewise. * alpha-bsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * alpha-tdep.c (alpha_extract_return_value): Likewise. (alpha_store_return_value): Likewise. (alpha_deal_with_atomic_sequence): Likewise. (alpha_next_pc): Likewise. (alpha_software_single_step): Likewise. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * amd64-nat.c (amd64_supply_native_gregset): Likewise. (amd64_collect_native_gregset): Likewise. * amd64-obsd-tdep.c (amd64obsd_supply_uthread): Likewise. (amd64obsd_collect_uthread): Likewise. * amd64-tdep.c (amd64_supply_fpregset): Likewise. (amd64_collect_fpregset): Likewise. (amd64_supply_fxsave): Likewise. (amd64_supply_xsave): Likewise. (amd64_collect_fxsave): Likewise. (amd64_collect_xsave): Likewise. * arc-tdep.c (arc_write_pc): Likewise. * arch-utils.c (default_skip_permanent_breakpoint): Likewise. * arm-fbsd-nat.c (arm_fbsd_fetch_inferior_registers): Likewise. (arm_fbsd_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_vfp_regs): Likewise. (store_vfp_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * arm-linux-tdep.c (arm_linux_supply_gregset): Likewise. (arm_linux_sigreturn_next_pc): Likewise. (arm_linux_get_next_pcs_syscall_next_pc): Likewise. * arm-nbsd-nat.c (arm_supply_gregset): Likewise. (fetch_register): Likewise. (store_register): Likewise. * arm-tdep.c (arm_is_thumb): Likewise. (displaced_in_arm_mode): Likewise. (bx_write_pc): Likewise. (arm_get_next_pcs_addr_bits_remove): Likewise. (arm_software_single_step): Likewise. (arm_extract_return_value): Likewise. (arm_store_return_value): Likewise. (arm_write_pc): Likewise. * bfin-tdep.c (bfin_extract_return_value): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * core-regset.c (fetch_core_registers): Likewise. * corelow.c (get_core_registers): Likewise. * cris-tdep.c (cris_store_return_value): Likewise. (cris_extract_return_value): Likewise. (find_step_target): Likewise. (find_step_target): Likewise. (cris_software_single_step): Likewise. * ctf.c (ctf_fetch_registers): Likewise. * darwin-nat.c (cancel_breakpoint): Likewise. * fbsd-tdep.c (fbsd_collect_thread_registers): Likewise. * frv-tdep.c (frv_extract_return_value): Likewise. * ft32-tdep.c (ft32_store_return_value): Likewise. (ft32_extract_return_value): Likewise. * go32-nat.c (fetch_register): Likewise. (go32_fetch_registers): Likewise. (go32_store_registers): Likewise. (store_register): Likewise. * h8300-tdep.c (h8300_extract_return_value): Likewise. (h8300_store_return_value): Likewise. * hppa-linux-nat.c (fetch_register): Likewise. (store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * i386-darwin-nat.c (i386_darwin_fetch_inferior_registers): Likewise. (i386_darwin_store_inferior_registers): Likewise. * i386-gnu-nat.c (gnu_fetch_registers): Likewise. (gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register): Likewise. (store_register): Likewise. (supply_gregset): Likewise. (fill_gregset): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. (i386_linux_resume): Likewise. * i386-linux-tdep.c (i386_linux_get_syscall_number_from_regcache): Likewise. * i386-nto-tdep.c (i386nto_supply_gregset): Likewise. * i386-obsd-nat.c (i386obsd_supply_pcb): Likewise. * i386-obsd-tdep.c (i386obsd_supply_uthread): Likewise. (i386obsd_collect_uthread): Likewise. * i386-tdep.c (i386_mmx_regnum_to_fp_regnum): Likewise. (i386_supply_gregset): Likewise. (i386_collect_gregset): Likewise. (i386_supply_fpregset): Likewise. (i386_collect_fpregset): Likewise. (i386_mpx_bd_base): Likewise. * i386-v4-nat.c (supply_fpregset): Likewise. (fill_fpregset): Likewise. * i387-tdep.c (i387_supply_fsave): Likewise. (i387_collect_fsave): Likewise. (i387_supply_fxsave): Likewise. (i387_collect_fxsave): Likewise. (i387_supply_xsave): Likewise. (i387_collect_xsave): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_registers): Likewise. * ia64-tdep.c (ia64_access_rse_reg): Likewise. (ia64_extract_return_value): Likewise. (ia64_store_return_value): Likewise. (find_func_descr): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_registers): Likewise. * infrun.c (use_displaced_stepping): Likewise. (displaced_step_prepare_throw): Likewise. (resume): Likewise. (proceed): Likewise. (do_target_wait): Likewise. (adjust_pc_after_break): Likewise. (handle_inferior_event_1): Likewise. (handle_signal_stop): Likewise. (save_infcall_suspend_state): Likewise. (restore_infcall_suspend_state): Likewise. * iq2000-tdep.c (iq2000_extract_return_value): Likewise. * jit.c (jit_frame_prev_register): Likewise. * linux-nat.c (save_stop_reason): Likewise. (linux_nat_wait_1): Likewise. (resume_stopped_resumed_lwps): Likewise. * linux-record.c (record_linux_sockaddr): Likewise. (record_linux_msghdr): Likewise. (record_linux_system_call): Likewise. * linux-tdep.c (linux_collect_thread_registers): Likewise. * lm32-tdep.c (lm32_extract_return_value): Likewise. (lm32_store_return_value): Likewise. * m32c-tdep.c (m32c_read_flg): Likewise. (m32c_pseudo_register_read): Likewise. (m32c_pseudo_register_write): Likewise. * m32r-linux-tdep.c (m32r_linux_supply_gregset): Likewise. (m32r_linux_collect_gregset): Likewise. * m32r-tdep.c (m32r_store_return_value): Likewise. (m32r_extract_return_value): Likewise. * m68k-bsd-nat.c (m68kbsd_supply_fpregset): Likewise. (m68kbsd_collect_fpregset): Likewise. * m68k-bsd-tdep.c (m68kbsd_supply_fpregset): Likewise. * m68k-linux-nat.c (fetch_register): Likewise. (old_fetch_inferior_registers): Likewise. (old_store_inferior_registers): Likewise. (store_regs): Likewise. * m68k-tdep.c (m68k_svr4_extract_return_value): Likewise. (m68k_svr4_store_return_value): Likewise. * m88k-tdep.c (m88k_store_arguments): Likewise. * mi/mi-main.c (mi_cmd_data_list_changed_registers): Likewise. (mi_cmd_data_write_register_values): Likewise. * mips-fbsd-nat.c (mips_fbsd_fetch_inferior_registers): Likewise. (mips_fbsd_store_inferior_registers): Likewise. * mips-fbsd-tdep.c (mips_fbsd_supply_fpregs): Likewise. (mips_fbsd_supply_gregs): Likewise. (mips_fbsd_collect_fpregs): Likewise. (mips_fbsd_collect_gregs): Likewise. (mips_fbsd_supply_fpregset): Likewise. (mips_fbsd_collect_fpregset): Likewise. (mips_fbsd_supply_gregset): Likewise. (mips_fbsd_collect_gregset): Likewise. * mips-linux-nat.c (supply_gregset): Likewise. (fill_gregset): Likewise. (supply_fpregset): Likewise. (fill_fpregset): Likewise. * mips-linux-tdep.c (mips_supply_gregset): Likewise. (mips_fill_gregset): Likewise. (mips_supply_fpregset): Likewise. (mips_fill_fpregset): Likewise. (mips64_supply_gregset): Likewise. (micromips_linux_sigframe_validate): Likewise. * mips-nbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * mips-nbsd-tdep.c (mipsnbsd_supply_fpregset): Likewise. (mipsnbsd_supply_gregset): Likewise. (mipsnbsd_iterate_over_regset_sections): Likewise. (mipsnbsd_supply_reg): Likewise. (mipsnbsd_supply_fpreg): Likewise. * mips-tdep.c (mips_in_frame_stub): Likewise. (mips_dummy_id): Likewise. (is_octeon_bbit_op): Likewise. (micromips_bc1_pc): Likewise. (extended_mips16_next_pc): Likewise. (mips16_next_pc): Likewise. (deal_with_atomic_sequence): Likewise. * moxie-tdep.c (moxie_process_readu): Likewise. * nios2-tdep.c (nios2_get_next_pc): Likewise. * nto-procfs.c (procfs_store_registers): Likewise. * ppc-fbsd-nat.c (ppcfbsd_fetch_inferior_registers): Likewise. (ppcfbsd_store_inferior_registers): Likewise. * ppc-linux-nat.c (fetch_vsx_register): Likewise. (fetch_altivec_register): Likewise. (get_spe_registers): Likewise. (fetch_spe_register): Likewise. (fetch_altivec_registers): Likewise. (fetch_all_gp_regs): Likewise. (fetch_all_fp_regs): Likewise. (store_vsx_register): Likewise. (store_altivec_register): Likewise. (set_spe_registers): Likewise. (store_spe_register): Likewise. (store_altivec_registers): Likewise. (store_all_gp_regs): Likewise. (store_all_fp_regs): Likewise. * ppc-linux-tdep.c (ppc_linux_supply_gregset): Likewise. (ppc_linux_collect_gregset): Likewise. (ppc_canonicalize_syscall): Likewise. (ppc_linux_record_signal): Likewise. (ppu2spu_prev_register): Likewise. * ppc-nbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-obsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * ppc-ravenscar-thread.c (ppc_ravenscar_generic_fetch_registers): Likewise. (ppc_ravenscar_generic_store_registers): Likewise. * procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ravenscar-thread.c (ravenscar_fetch_registers): Likewise. (ravenscar_store_registers): Likewise. (ravenscar_prepare_to_store): Likewise. * record-btrace.c (record_btrace_fetch_registers): Likewise. * record-full.c (record_full_wait_1): Likewise. (record_full_registers_change): Likewise. (record_full_store_registers): Likewise. (record_full_core_fetch_registers): Likewise. (record_full_save): Likewise. (record_full_goto_insn): Likewise. * regcache.c (regcache_register_size): Likewise. (get_regcache_arch): Remove. (regcache_read_pc): Likewise. * regcache.h (get_regcache_arch): Remove. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * remote.c (fetch_register_using_p): Likewise. (send_g_packet): Likewise. (remote_prepare_to_store): Likewise. (store_registers_using_G): Likewise. * reverse.c (save_bookmark_command): Likewise. (goto_bookmark_command): Likewise. * rs6000-aix-tdep.c (branch_dest): Likewise. * rs6000-nat.c (rs6000_ptrace64): Likewise. (fetch_register): Likewise. * rs6000-tdep.c (ppc_supply_reg): Likewise. (ppc_collect_reg): Likewise. (ppc_collect_gregset): Likewise. (ppc_collect_fpregset): Likewise. (ppc_collect_vsxregset): Likewise. (ppc_collect_vrregset): Likewise. (ppc_displaced_step_hw_singlestep): Likewise. (rs6000_pseudo_register_read): Likewise. (rs6000_pseudo_register_write): Likewise. * s390-linux-nat.c (supply_gregset): Likewise. (fill_gregset): Likewise. (s390_linux_fetch_inferior_registers): Likewise. * s390-linux-tdep.c (s390_write_pc): Likewise. (s390_software_single_step): Likewise. (s390_all_but_pc_registers_record): Likewise. (s390_linux_syscall_record): Likewise. * sentinel-frame.c (sentinel_frame_prev_arch): Likewise. * sh-nbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sh-tdep.c (sh_extract_return_value_nofpu): Likewise. (sh_extract_return_value_fpu): Likewise. (sh_store_return_value_nofpu): Likewise. (sh_corefile_supply_regset): Likewise. (sh_corefile_collect_regset): Likewise. * sh64-tdep.c (sh64_extract_return_value): Likewise. (sh64_store_return_value): Likewise. * sparc-linux-tdep.c (sparc32_linux_collect_core_fpregset): Likewise. * sparc-nat.c (sparc_fetch_inferior_registers): Likewise. (sparc_store_inferior_registers): Likewise. * sparc-ravenscar-thread.c (register_in_thread_descriptor_p): Likewise. (sparc_ravenscar_prepare_to_store): Likewise. * sparc-tdep.c (sparc32_store_arguments): Likewise. (sparc_analyze_control_transfer): Likewise. (sparc_step_trap): Likewise. (sparc_software_single_step): Likewise. (sparc32_gdbarch_init): Likewise. (sparc_supply_rwindow): Likewise. (sparc_collect_rwindow): Likewise. * sparc64-linux-tdep.c (sparc64_linux_collect_core_fpregset): Likewise. * sparc64-nbsd-nat.c (sparc64nbsd_supply_gregset): Likewise. (sparc64nbsd_collect_gregset): Likewise. (sparc64nbsd_supply_fpregset): Likewise. (sparc64nbsd_collect_fpregset): Likewise. * sparc64-tdep.c (sparc64_store_arguments): Likewise. (sparc64_supply_gregset): Likewise. (sparc64_collect_gregset): Likewise. (sparc64_supply_fpregset): Likewise. (sparc64_collect_fpregset): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. * spu-tdep.c (spu_unwind_sp): Likewise. (spu2ppu_prev_register): Likewise. (spu_memory_remove_breakpoint): Likewise. * stack.c (return_command): Likewise. * tic6x-tdep.c (tic6x_extract_signed_field): Likewise. * tracefile-tfile.c (tfile_fetch_registers): Likewise. * tracefile.c (trace_save_ctf): Likewise. * windows-nat.c (do_windows_fetch_inferior_registers): Likewise. (do_windows_store_inferior_registers): Likewise. (windows_resume): Likewise. * xtensa-linux-nat.c (fill_gregset): Likewise. (supply_gregset_reg): Likewise. * xtensa-tdep.c (xtensa_register_write_masked): Likewise. (xtensa_register_read_masked): Likewise. (xtensa_supply_gregset): Likewise. (xtensa_extract_return_value): Likewise. (xtensa_store_return_value): Likewise.
2017-10-25 23:37:03 +08:00
struct gdbarch *gdbarch = regcache->arch ();
2007-11-16 Markus Deuling <deuling@de.ibm.com> * m32r-rom.c (m32r_supply_register): Use get_regcache_arch to get at the current architecture by regcache. * ppcnbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register) (fetch_register, supply_vrregset, fetch_ppc_registers) (store_altivec_register, store_spe_register, store_register) (fill_vrregset, store_ppc_registers): Likewise. * ppcobsd-nat.c (ppcobsd_supply_pcb): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers) (do_win32_store_inferior_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers) (m32r_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register, gdbsim_store_register): Likewise. * trad-frame.c (trad_frame_alloc_saved_regs): Replace current_gdbarch by gdbarch. * user-regs.c (user_reg_map_name_to_regnum): Likewise. * ppc-sysv-tdep.c (ppc_sysv_abi_push_dummy_call) (do_ppc_sysv_return_value, ppc64_sysv_abi_push_dummy_call) (ppc64_sysv_abi_return_value): Likewise. * m32c-tdep.c (m32c_register_reggroup_p): Likewise. * m2-lang.c (build_m2_types): Likewise. * ppc-linux-tdep.c (ppc_linux_sigtramp_cache * ppcnbsd-tdep.c (ppcnbsd_sigtramp_cache_init): Likewise. * ppcobsd-tdep.c (ppcobsd_sigtramp_frame_cache): Likewise. * rs6000-tdep.c (ppc_dwarf2_frame_init_reg): Likewise. * m68hc11-tdep.c (m68hc11_frame_unwind_cache): Use get_frame_arch to get at the current architecture by frame_info. * gcore.c (derive_stack_segment): Likewise. * shnbsd-nat.c (GETREGS_SUPPLIES): Add gdbarch parameter. (shnbsd_fetch_inferior_registers, shnbsd_store_inferior_registers): Add gdbarch to GETREGS_SUPPLIES call.
2007-11-16 12:53:46 +08:00
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int i;
if (have_ptrace_getsetregs)
if (store_all_gp_regs (regcache, tid, regno))
return;
/* If we hit this point, it doesn't really matter which
architecture we are using. We just need to store the
registers in the "old-fashioned way". */
Change the layout of the PowerPC E500 raw register cache to allow the lower 32-bit halves of the GPRS to be their own raw registers, not pseudoregisters. * ppc-tdep.h (struct gdbarch_tdep): Remove ppc_gprs_pseudo_p flag; add ppc_ev0_upper_regnum flag. * rs6000-tdep.c: #include "reggroups.h". (spe_register_p): Recognize the ev upper half registers as SPE registers. (init_sim_regno_table): Build gdb->sim mappings for the upper-half registers. (e500_move_ev_register): New function. (e500_pseudo_register_read, e500_pseudo_register_write): The 'ev' vector registers are the pseudo-registers now, formed by splicing together the gprs and the upper-half registers. (e500_register_reggroup_p): New function. (P): Macro deleted. (P8, A4): New macro. (PPC_EV_REGS, PPC_GPRS_PSEUDO_REGS): Macros deleted. (PPC_SPE_GP_REGS, PPC_SPE_UPPER_GP_REGS, PPC_EV_PSEUDO_REGS): New macros. (registers_e500): Rearrange register set so that the raw register set contains 32-bit GPRs and upper-half registers, and the SPE vector registers become pseudo-registers. (rs6000_gdbarch_init): Don't initialize tdep->ppc_gprs_pseudo_p; it has been deleted. Initialize ppc_ev0_upper_regnum. Many other register numbers are now the same for the E500 as they are for other PowerPC variants. Register e500_register_reggroup_p as the register group function for the E500. * Makefile.in (rs6000-tdep.o): Update dependencies. Adapt PPC E500 native support to the new raw regcache layout. * ppc-linux-nat.c (struct gdb_evrregset_t): Doc fixes. (read_spliced_spe_reg, write_spliced_spe_reg): Deleted. (fetch_spe_register, store_spe_register): Handle fetching/storing all the SPE registers at once, if regno == -1. These now take over the job of fetch_spe_registers and store_spe_registers. (fetch_spe_registers, store_spe_registers): Deleted. (fetch_ppc_registers, store_ppc_registers): Fetch/store gprs unconditionally; they're always raw. Fetch/store SPE upper half registers, if present, instead of ev registers. (fetch_register, store_register): Remove sanity checks: gprs are never pseudo-registers now, so we never need to even mention any registers that are ever pseudoregisters.
2004-08-05 01:17:55 +08:00
for (i = 0; i < ppc_num_gprs; i++)
* target.h (struct regcache): Add forward declaration. (struct target_ops): Add REGCACHE parameter to to_fetch_registers and to_store_registers target operations. (target_fetch_registers, target_store_registers): Update. * regcache.c (regcache_raw_read): Replace register_cached by regcache_valid_p. Pass regcache to target_fetch_registers. (regcache_raw_write): Pass regcache to target_store_registers. * arm-linux-nat.c (store_fpregister, store_fpregs, store_register, store_regs, store_wmmx_regs): Replace register_cached by regcache_valid_p. * bsd-kvm.c (bsd_kvm_open, bsd_kvm_proc_cmd): Pass current_regcache to target_fetch_registers calls. * corelow.c (core_open): Likewise. * linux-nat.c (linux_nat_corefile_thread_callback): Likewise. * proc-service.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * sol-thread.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * win32-nat.c (win32_resume): Likewise. * ia64-tdep.c (ia64_store_return_value): Pass current_regcache to target_store_registers call. * rs6000-tdep.c (rs6000_push_dummy_call): Likewise. * inferior.h (store_inferior_registers): Update prototype. (fetch_inferior_registers): Likewise. * gnu-nat.c (gnu_store_registers, gnu_fetch_registers): Likewise. * mips-linux-nat.c (super_fetch_registers, super_store_registers): Update function pointer signatures. * aix-thread.c (aix_thread_fetch_registers): Add REGCACHE parameter, use it instead of current_regcache, update calls. (aix_thread_store_registers): Likewise. * alphabsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * amd64bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_fpregister, fetch_fpregs, store_fpregister, store_fpregs, fetch_register, fetch_regs, store_register, store_regs, fetch_wmmx_regs, store_wmmx_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * armnbsd-nat.c (fetch_register, fetch_regs, fetch_fp_register, fetch_fp_regs, armnbsd_fetch_registers): Likewise. (store_register, store_regs, store_fp_register, store_fp_regs, armnbsd_store_registers): Likewise. * bsd-kvm.c (bsd_kvm_fetch_pcb, bsd_kvm_fetch_registers): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * corelow.c (get_core_registers): Likewise. * go32-nat.c (fetch_register, go32_fetch_registers, store_register, go32_store_registers): Likewise. * hppabsd-nat.c (hppabsd_fetch_registers): Likewise. (hppabsd_store_registers): Likewise. * hppa-hpux-nat.c (hppa_hpux_fetch_register): Likewise. (hppa_hpux_fetch_inferior_registers): Likewise. (hppa_hpux_store_register): Likewise. (hppa_hpux_store_inferior_registers): Likewise. * hppa-linux-nat.c (fetch_register, store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * hpux-thread.c (hpux_thread_fetch_registers): Likewise. (hpux_thread_store_registers): Likewise. * i386bsd-nat.c (i386bsd_fetch_inferior_registers): Likewise. (i386bsd_store_inferior_registers): Likewise. * i386gnu-nat.c (fetch_fpregs, gnu_fetch_registers, store_fpregs, gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register, store_register, fetch_regs, store_regs, fetch_fpregs, store_fpregs, fetch_fpxregs, store_fpxregs): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_register): Likewise. (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_register): Likewise. (ia64_linux_store_registers): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. (inf_child_store_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register): Likewise. (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_register): Likewise. (inf_ptrace_store_registers): Likewise. * infptrace.c (fetch_register, store_register): Likewise. (fetch_inferior_registers, store_inferior_registers): Likewise. * m32r-linux-nat.c (fetch_regs, store_regs): Likewise. (m32r_linux_fetch_inferior_registers): Likewise. (m32r_linux_store_inferior_registers): Likewise. * m68kbsd-nat.c (m68kbsd_fetch_inferior_registers): Likewise. (m68kbsd_store_inferior_registers): Likewise. * m68klinux-nat.c (fetch_register, old_fetch_inferior_registers, store_register, old_store_inferior_registers, fetch_regs, store_regs, fetch_fpregs, store_fpregs): Likewise. (m68k_linux_fetch_inferior_registers): Likewise. (m68k_linux_store_inferior_registers): Likewise. * m88kbsd-nat.c (m88kbsd_fetch_inferior_registers): Likewise. (m88kbsd_store_inferior_registers): Likewise. * mips64obsd-nat.c (mips64obsd_fetch_inferior_registers): Likewise. (mips64obsd_store_inferior_registers): Likewise. * mips-linux-nat.c (mips64_linux_regsets_fetch_registers): Likewise. (mips64_linux_regsets_store_registers): Likewise. (mips64_linux_fetch_registers): Likewise. (mips64_linux_store_registers): Likewise. * mipsnbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * monitor.c (monitor_fetch_register, monitor_store_register): Likewise. (monitor_fetch_registers, monitor_store_registers): Likewise. * nto-procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register, fetch_register, supply_vrregset, fetch_altivec_registers, fetch_ppc_registers, ppc_linux_fetch_inferior_registers): Likewise. (store_altivec_register, store_spe_register, store_register, fill_vrregset, store_altivec_registers, store_ppc_registers, ppc_linux_store_inferior_registers): Likewise. * ppcnbsd-nat.c (ppcnbsd_fetch_inferior_registers): Likewise. (ppcnbsd_store_inferior_registers): Likewise. * ppcobsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote.c (fetch_register_using_p, process_g_packet, fetch_registers_using_g, remote_fetch_registers): Likewise. (store_register_using_P, store_registers_using_G, remote_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers, m32r_fetch_register, m32r_store_register, m32r_store_register): Likewise. * remote-mips.c (mips_fetch_registers, mips_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * rs6000-nat.c (fetch_register, store_register): Likewise. (rs6000_fetch_inferior_registers): Likewise. (rs6000_store_inferior_registers): Likewise. * s390-nat.c (fetch_regs, store_regs): Likewise. (fetch_fpregs, store_fpregs): Likewise. (s390_linux_fetch_inferior_registers): Likewise. (s390_linux_store_inferior_registers): Likewise. * shnbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sol-thread.c (sol_thread_fetch_registers): Likewise. (sol_thread_store_registers): Likewise. * sparc-nat.c (fetch_inferior_registers): Likewise. (store_inferior_registers): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. (spu_store_inferior_registers): Likewise. * target.c (debug_print_register): Likewise. (debug_to_fetch_registers, debug_to_store_registers): Likewise. * vaxbsd-nat.c (vaxbsd_fetch_inferior_registers): Likewise. (vaxbsd_store_inferior_registers): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers): Likewise. (win32_fetch_inferior_registers): Likewise. (win32_store_inferior_registers): Likewise.
2007-05-06 22:34:38 +08:00
store_register (regcache, tid, tdep->ppc_gp0_regnum + i);
}
/* This function actually issues the request to ptrace, telling
it to store all floating-point registers present in the specified
regset.
If the ptrace request does not exist, this function returns 0
and properly sets the have_ptrace_* flag. If the request fails,
this function calls perror_with_name. Otherwise, if the request
succeeds, then the regcache is stored and 1 is returned. */
static int
store_all_fp_regs (const struct regcache *regcache, int tid, int regno)
{
gdb_fpregset_t fpregs;
if (ptrace (PTRACE_GETFPREGS, tid, 0, (void *) &fpregs) < 0)
{
if (errno == EIO)
{
have_ptrace_getsetfpregs = 0;
return 0;
}
perror_with_name (_("Couldn't get floating-point registers."));
}
fill_fpregset (regcache, &fpregs, regno);
if (ptrace (PTRACE_SETFPREGS, tid, 0, (void *) &fpregs) < 0)
{
if (errno == EIO)
{
have_ptrace_getsetfpregs = 0;
return 0;
}
perror_with_name (_("Couldn't set floating-point registers."));
}
return 1;
}
/* This is a wrapper for the store_all_fp_regs function. It is
responsible for verifying if this target has the ptrace request
that can be used to store all floating-point registers at one
shot. If it doesn't, then we should store them using the
old-fashioned way, which is to iterate over the registers and
store them one by one. */
static void
store_fp_regs (const struct regcache *regcache, int tid, int regno)
{
s/get_regcache_arch (regcache)/regcache->arch ()/g This patches removes get_regcache_arch, and use regache->arch () instead. The motivation of this change is that I am going to move some basic stuff into a base class of regcache. I don't need to update "client" code regcache->arch (). On the other hand, this patch shortens the code a little bit. gdb: 2017-10-25 Yao Qi <yao.qi@linaro.org> * aarch32-linux-nat.c (aarch32_gp_regcache_supply): Use regcache->arch () instead get_regcache_arch. * aarch64-fbsd-nat.c (aarch64_fbsd_fetch_inferior_registers): Likewise. (aarch64_fbsd_store_inferior_registers): Likewise. * aarch64-linux-nat.c (fetch_gregs_from_thread): Likewise. (store_gregs_to_thread): Likewise. (fetch_fpregs_from_thread): Likewise. (store_fpregs_to_thread): Likewise. * aarch64-tdep.c (aarch64_extract_return_value): Likewise. (aarch64_store_return_value): Likewise. (aarch64_software_single_step): Likewise. * aix-thread.c (aix_thread_wait): Likewise. (supply_reg32): Likewise. (supply_sprs64): Likewise. (supply_sprs32): Likewise. (fill_gprs64): Likewise. (fill_gprs32): Likewise. (fill_sprs64): Likewise. (fill_sprs32): Likewise. (store_regs_user_thread): Likewise. (store_regs_kernel_thread): Likewise. * alpha-bsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * alpha-tdep.c (alpha_extract_return_value): Likewise. (alpha_store_return_value): Likewise. (alpha_deal_with_atomic_sequence): Likewise. (alpha_next_pc): Likewise. (alpha_software_single_step): Likewise. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * amd64-nat.c (amd64_supply_native_gregset): Likewise. (amd64_collect_native_gregset): Likewise. * amd64-obsd-tdep.c (amd64obsd_supply_uthread): Likewise. (amd64obsd_collect_uthread): Likewise. * amd64-tdep.c (amd64_supply_fpregset): Likewise. (amd64_collect_fpregset): Likewise. (amd64_supply_fxsave): Likewise. (amd64_supply_xsave): Likewise. (amd64_collect_fxsave): Likewise. (amd64_collect_xsave): Likewise. * arc-tdep.c (arc_write_pc): Likewise. * arch-utils.c (default_skip_permanent_breakpoint): Likewise. * arm-fbsd-nat.c (arm_fbsd_fetch_inferior_registers): Likewise. (arm_fbsd_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_vfp_regs): Likewise. (store_vfp_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * arm-linux-tdep.c (arm_linux_supply_gregset): Likewise. (arm_linux_sigreturn_next_pc): Likewise. (arm_linux_get_next_pcs_syscall_next_pc): Likewise. * arm-nbsd-nat.c (arm_supply_gregset): Likewise. (fetch_register): Likewise. (store_register): Likewise. * arm-tdep.c (arm_is_thumb): Likewise. (displaced_in_arm_mode): Likewise. (bx_write_pc): Likewise. (arm_get_next_pcs_addr_bits_remove): Likewise. (arm_software_single_step): Likewise. (arm_extract_return_value): Likewise. (arm_store_return_value): Likewise. (arm_write_pc): Likewise. * bfin-tdep.c (bfin_extract_return_value): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * core-regset.c (fetch_core_registers): Likewise. * corelow.c (get_core_registers): Likewise. * cris-tdep.c (cris_store_return_value): Likewise. (cris_extract_return_value): Likewise. (find_step_target): Likewise. (find_step_target): Likewise. (cris_software_single_step): Likewise. * ctf.c (ctf_fetch_registers): Likewise. * darwin-nat.c (cancel_breakpoint): Likewise. * fbsd-tdep.c (fbsd_collect_thread_registers): Likewise. * frv-tdep.c (frv_extract_return_value): Likewise. * ft32-tdep.c (ft32_store_return_value): Likewise. (ft32_extract_return_value): Likewise. * go32-nat.c (fetch_register): Likewise. (go32_fetch_registers): Likewise. (go32_store_registers): Likewise. (store_register): Likewise. * h8300-tdep.c (h8300_extract_return_value): Likewise. (h8300_store_return_value): Likewise. * hppa-linux-nat.c (fetch_register): Likewise. (store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * i386-darwin-nat.c (i386_darwin_fetch_inferior_registers): Likewise. (i386_darwin_store_inferior_registers): Likewise. * i386-gnu-nat.c (gnu_fetch_registers): Likewise. (gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register): Likewise. (store_register): Likewise. (supply_gregset): Likewise. (fill_gregset): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. (i386_linux_resume): Likewise. * i386-linux-tdep.c (i386_linux_get_syscall_number_from_regcache): Likewise. * i386-nto-tdep.c (i386nto_supply_gregset): Likewise. * i386-obsd-nat.c (i386obsd_supply_pcb): Likewise. * i386-obsd-tdep.c (i386obsd_supply_uthread): Likewise. (i386obsd_collect_uthread): Likewise. * i386-tdep.c (i386_mmx_regnum_to_fp_regnum): Likewise. (i386_supply_gregset): Likewise. (i386_collect_gregset): Likewise. (i386_supply_fpregset): Likewise. (i386_collect_fpregset): Likewise. (i386_mpx_bd_base): Likewise. * i386-v4-nat.c (supply_fpregset): Likewise. (fill_fpregset): Likewise. * i387-tdep.c (i387_supply_fsave): Likewise. (i387_collect_fsave): Likewise. (i387_supply_fxsave): Likewise. (i387_collect_fxsave): Likewise. (i387_supply_xsave): Likewise. (i387_collect_xsave): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_registers): Likewise. * ia64-tdep.c (ia64_access_rse_reg): Likewise. (ia64_extract_return_value): Likewise. (ia64_store_return_value): Likewise. (find_func_descr): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_registers): Likewise. * infrun.c (use_displaced_stepping): Likewise. (displaced_step_prepare_throw): Likewise. (resume): Likewise. (proceed): Likewise. (do_target_wait): Likewise. (adjust_pc_after_break): Likewise. (handle_inferior_event_1): Likewise. (handle_signal_stop): Likewise. (save_infcall_suspend_state): Likewise. (restore_infcall_suspend_state): Likewise. * iq2000-tdep.c (iq2000_extract_return_value): Likewise. * jit.c (jit_frame_prev_register): Likewise. * linux-nat.c (save_stop_reason): Likewise. (linux_nat_wait_1): Likewise. (resume_stopped_resumed_lwps): Likewise. * linux-record.c (record_linux_sockaddr): Likewise. (record_linux_msghdr): Likewise. (record_linux_system_call): Likewise. * linux-tdep.c (linux_collect_thread_registers): Likewise. * lm32-tdep.c (lm32_extract_return_value): Likewise. (lm32_store_return_value): Likewise. * m32c-tdep.c (m32c_read_flg): Likewise. (m32c_pseudo_register_read): Likewise. (m32c_pseudo_register_write): Likewise. * m32r-linux-tdep.c (m32r_linux_supply_gregset): Likewise. (m32r_linux_collect_gregset): Likewise. * m32r-tdep.c (m32r_store_return_value): Likewise. (m32r_extract_return_value): Likewise. * m68k-bsd-nat.c (m68kbsd_supply_fpregset): Likewise. (m68kbsd_collect_fpregset): Likewise. * m68k-bsd-tdep.c (m68kbsd_supply_fpregset): Likewise. * m68k-linux-nat.c (fetch_register): Likewise. (old_fetch_inferior_registers): Likewise. (old_store_inferior_registers): Likewise. (store_regs): Likewise. * m68k-tdep.c (m68k_svr4_extract_return_value): Likewise. (m68k_svr4_store_return_value): Likewise. * m88k-tdep.c (m88k_store_arguments): Likewise. * mi/mi-main.c (mi_cmd_data_list_changed_registers): Likewise. (mi_cmd_data_write_register_values): Likewise. * mips-fbsd-nat.c (mips_fbsd_fetch_inferior_registers): Likewise. (mips_fbsd_store_inferior_registers): Likewise. * mips-fbsd-tdep.c (mips_fbsd_supply_fpregs): Likewise. (mips_fbsd_supply_gregs): Likewise. (mips_fbsd_collect_fpregs): Likewise. (mips_fbsd_collect_gregs): Likewise. (mips_fbsd_supply_fpregset): Likewise. (mips_fbsd_collect_fpregset): Likewise. (mips_fbsd_supply_gregset): Likewise. (mips_fbsd_collect_gregset): Likewise. * mips-linux-nat.c (supply_gregset): Likewise. (fill_gregset): Likewise. (supply_fpregset): Likewise. (fill_fpregset): Likewise. * mips-linux-tdep.c (mips_supply_gregset): Likewise. (mips_fill_gregset): Likewise. (mips_supply_fpregset): Likewise. (mips_fill_fpregset): Likewise. (mips64_supply_gregset): Likewise. (micromips_linux_sigframe_validate): Likewise. * mips-nbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * mips-nbsd-tdep.c (mipsnbsd_supply_fpregset): Likewise. (mipsnbsd_supply_gregset): Likewise. (mipsnbsd_iterate_over_regset_sections): Likewise. (mipsnbsd_supply_reg): Likewise. (mipsnbsd_supply_fpreg): Likewise. * mips-tdep.c (mips_in_frame_stub): Likewise. (mips_dummy_id): Likewise. (is_octeon_bbit_op): Likewise. (micromips_bc1_pc): Likewise. (extended_mips16_next_pc): Likewise. (mips16_next_pc): Likewise. (deal_with_atomic_sequence): Likewise. * moxie-tdep.c (moxie_process_readu): Likewise. * nios2-tdep.c (nios2_get_next_pc): Likewise. * nto-procfs.c (procfs_store_registers): Likewise. * ppc-fbsd-nat.c (ppcfbsd_fetch_inferior_registers): Likewise. (ppcfbsd_store_inferior_registers): Likewise. * ppc-linux-nat.c (fetch_vsx_register): Likewise. (fetch_altivec_register): Likewise. (get_spe_registers): Likewise. (fetch_spe_register): Likewise. (fetch_altivec_registers): Likewise. (fetch_all_gp_regs): Likewise. (fetch_all_fp_regs): Likewise. (store_vsx_register): Likewise. (store_altivec_register): Likewise. (set_spe_registers): Likewise. (store_spe_register): Likewise. (store_altivec_registers): Likewise. (store_all_gp_regs): Likewise. (store_all_fp_regs): Likewise. * ppc-linux-tdep.c (ppc_linux_supply_gregset): Likewise. (ppc_linux_collect_gregset): Likewise. (ppc_canonicalize_syscall): Likewise. (ppc_linux_record_signal): Likewise. (ppu2spu_prev_register): Likewise. * ppc-nbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-obsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * ppc-ravenscar-thread.c (ppc_ravenscar_generic_fetch_registers): Likewise. (ppc_ravenscar_generic_store_registers): Likewise. * procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ravenscar-thread.c (ravenscar_fetch_registers): Likewise. (ravenscar_store_registers): Likewise. (ravenscar_prepare_to_store): Likewise. * record-btrace.c (record_btrace_fetch_registers): Likewise. * record-full.c (record_full_wait_1): Likewise. (record_full_registers_change): Likewise. (record_full_store_registers): Likewise. (record_full_core_fetch_registers): Likewise. (record_full_save): Likewise. (record_full_goto_insn): Likewise. * regcache.c (regcache_register_size): Likewise. (get_regcache_arch): Remove. (regcache_read_pc): Likewise. * regcache.h (get_regcache_arch): Remove. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * remote.c (fetch_register_using_p): Likewise. (send_g_packet): Likewise. (remote_prepare_to_store): Likewise. (store_registers_using_G): Likewise. * reverse.c (save_bookmark_command): Likewise. (goto_bookmark_command): Likewise. * rs6000-aix-tdep.c (branch_dest): Likewise. * rs6000-nat.c (rs6000_ptrace64): Likewise. (fetch_register): Likewise. * rs6000-tdep.c (ppc_supply_reg): Likewise. (ppc_collect_reg): Likewise. (ppc_collect_gregset): Likewise. (ppc_collect_fpregset): Likewise. (ppc_collect_vsxregset): Likewise. (ppc_collect_vrregset): Likewise. (ppc_displaced_step_hw_singlestep): Likewise. (rs6000_pseudo_register_read): Likewise. (rs6000_pseudo_register_write): Likewise. * s390-linux-nat.c (supply_gregset): Likewise. (fill_gregset): Likewise. (s390_linux_fetch_inferior_registers): Likewise. * s390-linux-tdep.c (s390_write_pc): Likewise. (s390_software_single_step): Likewise. (s390_all_but_pc_registers_record): Likewise. (s390_linux_syscall_record): Likewise. * sentinel-frame.c (sentinel_frame_prev_arch): Likewise. * sh-nbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sh-tdep.c (sh_extract_return_value_nofpu): Likewise. (sh_extract_return_value_fpu): Likewise. (sh_store_return_value_nofpu): Likewise. (sh_corefile_supply_regset): Likewise. (sh_corefile_collect_regset): Likewise. * sh64-tdep.c (sh64_extract_return_value): Likewise. (sh64_store_return_value): Likewise. * sparc-linux-tdep.c (sparc32_linux_collect_core_fpregset): Likewise. * sparc-nat.c (sparc_fetch_inferior_registers): Likewise. (sparc_store_inferior_registers): Likewise. * sparc-ravenscar-thread.c (register_in_thread_descriptor_p): Likewise. (sparc_ravenscar_prepare_to_store): Likewise. * sparc-tdep.c (sparc32_store_arguments): Likewise. (sparc_analyze_control_transfer): Likewise. (sparc_step_trap): Likewise. (sparc_software_single_step): Likewise. (sparc32_gdbarch_init): Likewise. (sparc_supply_rwindow): Likewise. (sparc_collect_rwindow): Likewise. * sparc64-linux-tdep.c (sparc64_linux_collect_core_fpregset): Likewise. * sparc64-nbsd-nat.c (sparc64nbsd_supply_gregset): Likewise. (sparc64nbsd_collect_gregset): Likewise. (sparc64nbsd_supply_fpregset): Likewise. (sparc64nbsd_collect_fpregset): Likewise. * sparc64-tdep.c (sparc64_store_arguments): Likewise. (sparc64_supply_gregset): Likewise. (sparc64_collect_gregset): Likewise. (sparc64_supply_fpregset): Likewise. (sparc64_collect_fpregset): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. * spu-tdep.c (spu_unwind_sp): Likewise. (spu2ppu_prev_register): Likewise. (spu_memory_remove_breakpoint): Likewise. * stack.c (return_command): Likewise. * tic6x-tdep.c (tic6x_extract_signed_field): Likewise. * tracefile-tfile.c (tfile_fetch_registers): Likewise. * tracefile.c (trace_save_ctf): Likewise. * windows-nat.c (do_windows_fetch_inferior_registers): Likewise. (do_windows_store_inferior_registers): Likewise. (windows_resume): Likewise. * xtensa-linux-nat.c (fill_gregset): Likewise. (supply_gregset_reg): Likewise. * xtensa-tdep.c (xtensa_register_write_masked): Likewise. (xtensa_register_read_masked): Likewise. (xtensa_supply_gregset): Likewise. (xtensa_extract_return_value): Likewise. (xtensa_store_return_value): Likewise.
2017-10-25 23:37:03 +08:00
struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int i;
if (have_ptrace_getsetfpregs)
if (store_all_fp_regs (regcache, tid, regno))
return;
/* If we hit this point, it doesn't really matter which
architecture we are using. We just need to store the
registers in the "old-fashioned way". */
for (i = 0; i < ppc_num_fprs; i++)
store_register (regcache, tid, tdep->ppc_fp0_regnum + i);
}
static void
store_ppc_registers (const struct regcache *regcache, int tid)
{
s/get_regcache_arch (regcache)/regcache->arch ()/g This patches removes get_regcache_arch, and use regache->arch () instead. The motivation of this change is that I am going to move some basic stuff into a base class of regcache. I don't need to update "client" code regcache->arch (). On the other hand, this patch shortens the code a little bit. gdb: 2017-10-25 Yao Qi <yao.qi@linaro.org> * aarch32-linux-nat.c (aarch32_gp_regcache_supply): Use regcache->arch () instead get_regcache_arch. * aarch64-fbsd-nat.c (aarch64_fbsd_fetch_inferior_registers): Likewise. (aarch64_fbsd_store_inferior_registers): Likewise. * aarch64-linux-nat.c (fetch_gregs_from_thread): Likewise. (store_gregs_to_thread): Likewise. (fetch_fpregs_from_thread): Likewise. (store_fpregs_to_thread): Likewise. * aarch64-tdep.c (aarch64_extract_return_value): Likewise. (aarch64_store_return_value): Likewise. (aarch64_software_single_step): Likewise. * aix-thread.c (aix_thread_wait): Likewise. (supply_reg32): Likewise. (supply_sprs64): Likewise. (supply_sprs32): Likewise. (fill_gprs64): Likewise. (fill_gprs32): Likewise. (fill_sprs64): Likewise. (fill_sprs32): Likewise. (store_regs_user_thread): Likewise. (store_regs_kernel_thread): Likewise. * alpha-bsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * alpha-tdep.c (alpha_extract_return_value): Likewise. (alpha_store_return_value): Likewise. (alpha_deal_with_atomic_sequence): Likewise. (alpha_next_pc): Likewise. (alpha_software_single_step): Likewise. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * amd64-nat.c (amd64_supply_native_gregset): Likewise. (amd64_collect_native_gregset): Likewise. * amd64-obsd-tdep.c (amd64obsd_supply_uthread): Likewise. (amd64obsd_collect_uthread): Likewise. * amd64-tdep.c (amd64_supply_fpregset): Likewise. (amd64_collect_fpregset): Likewise. (amd64_supply_fxsave): Likewise. (amd64_supply_xsave): Likewise. (amd64_collect_fxsave): Likewise. (amd64_collect_xsave): Likewise. * arc-tdep.c (arc_write_pc): Likewise. * arch-utils.c (default_skip_permanent_breakpoint): Likewise. * arm-fbsd-nat.c (arm_fbsd_fetch_inferior_registers): Likewise. (arm_fbsd_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_vfp_regs): Likewise. (store_vfp_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * arm-linux-tdep.c (arm_linux_supply_gregset): Likewise. (arm_linux_sigreturn_next_pc): Likewise. (arm_linux_get_next_pcs_syscall_next_pc): Likewise. * arm-nbsd-nat.c (arm_supply_gregset): Likewise. (fetch_register): Likewise. (store_register): Likewise. * arm-tdep.c (arm_is_thumb): Likewise. (displaced_in_arm_mode): Likewise. (bx_write_pc): Likewise. (arm_get_next_pcs_addr_bits_remove): Likewise. (arm_software_single_step): Likewise. (arm_extract_return_value): Likewise. (arm_store_return_value): Likewise. (arm_write_pc): Likewise. * bfin-tdep.c (bfin_extract_return_value): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * core-regset.c (fetch_core_registers): Likewise. * corelow.c (get_core_registers): Likewise. * cris-tdep.c (cris_store_return_value): Likewise. (cris_extract_return_value): Likewise. (find_step_target): Likewise. (find_step_target): Likewise. (cris_software_single_step): Likewise. * ctf.c (ctf_fetch_registers): Likewise. * darwin-nat.c (cancel_breakpoint): Likewise. * fbsd-tdep.c (fbsd_collect_thread_registers): Likewise. * frv-tdep.c (frv_extract_return_value): Likewise. * ft32-tdep.c (ft32_store_return_value): Likewise. (ft32_extract_return_value): Likewise. * go32-nat.c (fetch_register): Likewise. (go32_fetch_registers): Likewise. (go32_store_registers): Likewise. (store_register): Likewise. * h8300-tdep.c (h8300_extract_return_value): Likewise. (h8300_store_return_value): Likewise. * hppa-linux-nat.c (fetch_register): Likewise. (store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * i386-darwin-nat.c (i386_darwin_fetch_inferior_registers): Likewise. (i386_darwin_store_inferior_registers): Likewise. * i386-gnu-nat.c (gnu_fetch_registers): Likewise. (gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register): Likewise. (store_register): Likewise. (supply_gregset): Likewise. (fill_gregset): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. (i386_linux_resume): Likewise. * i386-linux-tdep.c (i386_linux_get_syscall_number_from_regcache): Likewise. * i386-nto-tdep.c (i386nto_supply_gregset): Likewise. * i386-obsd-nat.c (i386obsd_supply_pcb): Likewise. * i386-obsd-tdep.c (i386obsd_supply_uthread): Likewise. (i386obsd_collect_uthread): Likewise. * i386-tdep.c (i386_mmx_regnum_to_fp_regnum): Likewise. (i386_supply_gregset): Likewise. (i386_collect_gregset): Likewise. (i386_supply_fpregset): Likewise. (i386_collect_fpregset): Likewise. (i386_mpx_bd_base): Likewise. * i386-v4-nat.c (supply_fpregset): Likewise. (fill_fpregset): Likewise. * i387-tdep.c (i387_supply_fsave): Likewise. (i387_collect_fsave): Likewise. (i387_supply_fxsave): Likewise. (i387_collect_fxsave): Likewise. (i387_supply_xsave): Likewise. (i387_collect_xsave): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_registers): Likewise. * ia64-tdep.c (ia64_access_rse_reg): Likewise. (ia64_extract_return_value): Likewise. (ia64_store_return_value): Likewise. (find_func_descr): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_registers): Likewise. * infrun.c (use_displaced_stepping): Likewise. (displaced_step_prepare_throw): Likewise. (resume): Likewise. (proceed): Likewise. (do_target_wait): Likewise. (adjust_pc_after_break): Likewise. (handle_inferior_event_1): Likewise. (handle_signal_stop): Likewise. (save_infcall_suspend_state): Likewise. (restore_infcall_suspend_state): Likewise. * iq2000-tdep.c (iq2000_extract_return_value): Likewise. * jit.c (jit_frame_prev_register): Likewise. * linux-nat.c (save_stop_reason): Likewise. (linux_nat_wait_1): Likewise. (resume_stopped_resumed_lwps): Likewise. * linux-record.c (record_linux_sockaddr): Likewise. (record_linux_msghdr): Likewise. (record_linux_system_call): Likewise. * linux-tdep.c (linux_collect_thread_registers): Likewise. * lm32-tdep.c (lm32_extract_return_value): Likewise. (lm32_store_return_value): Likewise. * m32c-tdep.c (m32c_read_flg): Likewise. (m32c_pseudo_register_read): Likewise. (m32c_pseudo_register_write): Likewise. * m32r-linux-tdep.c (m32r_linux_supply_gregset): Likewise. (m32r_linux_collect_gregset): Likewise. * m32r-tdep.c (m32r_store_return_value): Likewise. (m32r_extract_return_value): Likewise. * m68k-bsd-nat.c (m68kbsd_supply_fpregset): Likewise. (m68kbsd_collect_fpregset): Likewise. * m68k-bsd-tdep.c (m68kbsd_supply_fpregset): Likewise. * m68k-linux-nat.c (fetch_register): Likewise. (old_fetch_inferior_registers): Likewise. (old_store_inferior_registers): Likewise. (store_regs): Likewise. * m68k-tdep.c (m68k_svr4_extract_return_value): Likewise. (m68k_svr4_store_return_value): Likewise. * m88k-tdep.c (m88k_store_arguments): Likewise. * mi/mi-main.c (mi_cmd_data_list_changed_registers): Likewise. (mi_cmd_data_write_register_values): Likewise. * mips-fbsd-nat.c (mips_fbsd_fetch_inferior_registers): Likewise. (mips_fbsd_store_inferior_registers): Likewise. * mips-fbsd-tdep.c (mips_fbsd_supply_fpregs): Likewise. (mips_fbsd_supply_gregs): Likewise. (mips_fbsd_collect_fpregs): Likewise. (mips_fbsd_collect_gregs): Likewise. (mips_fbsd_supply_fpregset): Likewise. (mips_fbsd_collect_fpregset): Likewise. (mips_fbsd_supply_gregset): Likewise. (mips_fbsd_collect_gregset): Likewise. * mips-linux-nat.c (supply_gregset): Likewise. (fill_gregset): Likewise. (supply_fpregset): Likewise. (fill_fpregset): Likewise. * mips-linux-tdep.c (mips_supply_gregset): Likewise. (mips_fill_gregset): Likewise. (mips_supply_fpregset): Likewise. (mips_fill_fpregset): Likewise. (mips64_supply_gregset): Likewise. (micromips_linux_sigframe_validate): Likewise. * mips-nbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * mips-nbsd-tdep.c (mipsnbsd_supply_fpregset): Likewise. (mipsnbsd_supply_gregset): Likewise. (mipsnbsd_iterate_over_regset_sections): Likewise. (mipsnbsd_supply_reg): Likewise. (mipsnbsd_supply_fpreg): Likewise. * mips-tdep.c (mips_in_frame_stub): Likewise. (mips_dummy_id): Likewise. (is_octeon_bbit_op): Likewise. (micromips_bc1_pc): Likewise. (extended_mips16_next_pc): Likewise. (mips16_next_pc): Likewise. (deal_with_atomic_sequence): Likewise. * moxie-tdep.c (moxie_process_readu): Likewise. * nios2-tdep.c (nios2_get_next_pc): Likewise. * nto-procfs.c (procfs_store_registers): Likewise. * ppc-fbsd-nat.c (ppcfbsd_fetch_inferior_registers): Likewise. (ppcfbsd_store_inferior_registers): Likewise. * ppc-linux-nat.c (fetch_vsx_register): Likewise. (fetch_altivec_register): Likewise. (get_spe_registers): Likewise. (fetch_spe_register): Likewise. (fetch_altivec_registers): Likewise. (fetch_all_gp_regs): Likewise. (fetch_all_fp_regs): Likewise. (store_vsx_register): Likewise. (store_altivec_register): Likewise. (set_spe_registers): Likewise. (store_spe_register): Likewise. (store_altivec_registers): Likewise. (store_all_gp_regs): Likewise. (store_all_fp_regs): Likewise. * ppc-linux-tdep.c (ppc_linux_supply_gregset): Likewise. (ppc_linux_collect_gregset): Likewise. (ppc_canonicalize_syscall): Likewise. (ppc_linux_record_signal): Likewise. (ppu2spu_prev_register): Likewise. * ppc-nbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-obsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * ppc-ravenscar-thread.c (ppc_ravenscar_generic_fetch_registers): Likewise. (ppc_ravenscar_generic_store_registers): Likewise. * procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ravenscar-thread.c (ravenscar_fetch_registers): Likewise. (ravenscar_store_registers): Likewise. (ravenscar_prepare_to_store): Likewise. * record-btrace.c (record_btrace_fetch_registers): Likewise. * record-full.c (record_full_wait_1): Likewise. (record_full_registers_change): Likewise. (record_full_store_registers): Likewise. (record_full_core_fetch_registers): Likewise. (record_full_save): Likewise. (record_full_goto_insn): Likewise. * regcache.c (regcache_register_size): Likewise. (get_regcache_arch): Remove. (regcache_read_pc): Likewise. * regcache.h (get_regcache_arch): Remove. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * remote.c (fetch_register_using_p): Likewise. (send_g_packet): Likewise. (remote_prepare_to_store): Likewise. (store_registers_using_G): Likewise. * reverse.c (save_bookmark_command): Likewise. (goto_bookmark_command): Likewise. * rs6000-aix-tdep.c (branch_dest): Likewise. * rs6000-nat.c (rs6000_ptrace64): Likewise. (fetch_register): Likewise. * rs6000-tdep.c (ppc_supply_reg): Likewise. (ppc_collect_reg): Likewise. (ppc_collect_gregset): Likewise. (ppc_collect_fpregset): Likewise. (ppc_collect_vsxregset): Likewise. (ppc_collect_vrregset): Likewise. (ppc_displaced_step_hw_singlestep): Likewise. (rs6000_pseudo_register_read): Likewise. (rs6000_pseudo_register_write): Likewise. * s390-linux-nat.c (supply_gregset): Likewise. (fill_gregset): Likewise. (s390_linux_fetch_inferior_registers): Likewise. * s390-linux-tdep.c (s390_write_pc): Likewise. (s390_software_single_step): Likewise. (s390_all_but_pc_registers_record): Likewise. (s390_linux_syscall_record): Likewise. * sentinel-frame.c (sentinel_frame_prev_arch): Likewise. * sh-nbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sh-tdep.c (sh_extract_return_value_nofpu): Likewise. (sh_extract_return_value_fpu): Likewise. (sh_store_return_value_nofpu): Likewise. (sh_corefile_supply_regset): Likewise. (sh_corefile_collect_regset): Likewise. * sh64-tdep.c (sh64_extract_return_value): Likewise. (sh64_store_return_value): Likewise. * sparc-linux-tdep.c (sparc32_linux_collect_core_fpregset): Likewise. * sparc-nat.c (sparc_fetch_inferior_registers): Likewise. (sparc_store_inferior_registers): Likewise. * sparc-ravenscar-thread.c (register_in_thread_descriptor_p): Likewise. (sparc_ravenscar_prepare_to_store): Likewise. * sparc-tdep.c (sparc32_store_arguments): Likewise. (sparc_analyze_control_transfer): Likewise. (sparc_step_trap): Likewise. (sparc_software_single_step): Likewise. (sparc32_gdbarch_init): Likewise. (sparc_supply_rwindow): Likewise. (sparc_collect_rwindow): Likewise. * sparc64-linux-tdep.c (sparc64_linux_collect_core_fpregset): Likewise. * sparc64-nbsd-nat.c (sparc64nbsd_supply_gregset): Likewise. (sparc64nbsd_collect_gregset): Likewise. (sparc64nbsd_supply_fpregset): Likewise. (sparc64nbsd_collect_fpregset): Likewise. * sparc64-tdep.c (sparc64_store_arguments): Likewise. (sparc64_supply_gregset): Likewise. (sparc64_collect_gregset): Likewise. (sparc64_supply_fpregset): Likewise. (sparc64_collect_fpregset): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. * spu-tdep.c (spu_unwind_sp): Likewise. (spu2ppu_prev_register): Likewise. (spu_memory_remove_breakpoint): Likewise. * stack.c (return_command): Likewise. * tic6x-tdep.c (tic6x_extract_signed_field): Likewise. * tracefile-tfile.c (tfile_fetch_registers): Likewise. * tracefile.c (trace_save_ctf): Likewise. * windows-nat.c (do_windows_fetch_inferior_registers): Likewise. (do_windows_store_inferior_registers): Likewise. (windows_resume): Likewise. * xtensa-linux-nat.c (fill_gregset): Likewise. (supply_gregset_reg): Likewise. * xtensa-tdep.c (xtensa_register_write_masked): Likewise. (xtensa_register_read_masked): Likewise. (xtensa_supply_gregset): Likewise. (xtensa_extract_return_value): Likewise. (xtensa_store_return_value): Likewise.
2017-10-25 23:37:03 +08:00
struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
store_gp_regs (regcache, tid, -1);
if (tdep->ppc_fp0_regnum >= 0)
store_fp_regs (regcache, tid, -1);
2007-11-16 Markus Deuling <deuling@de.ibm.com> * m32r-rom.c (m32r_supply_register): Use get_regcache_arch to get at the current architecture by regcache. * ppcnbsd-nat.c (ppcnbsd_supply_pcb): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register) (fetch_register, supply_vrregset, fetch_ppc_registers) (store_altivec_register, store_spe_register, store_register) (fill_vrregset, store_ppc_registers): Likewise. * ppcobsd-nat.c (ppcobsd_supply_pcb): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers) (do_win32_store_inferior_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers) (m32r_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register, gdbsim_store_register): Likewise. * trad-frame.c (trad_frame_alloc_saved_regs): Replace current_gdbarch by gdbarch. * user-regs.c (user_reg_map_name_to_regnum): Likewise. * ppc-sysv-tdep.c (ppc_sysv_abi_push_dummy_call) (do_ppc_sysv_return_value, ppc64_sysv_abi_push_dummy_call) (ppc64_sysv_abi_return_value): Likewise. * m32c-tdep.c (m32c_register_reggroup_p): Likewise. * m2-lang.c (build_m2_types): Likewise. * ppc-linux-tdep.c (ppc_linux_sigtramp_cache * ppcnbsd-tdep.c (ppcnbsd_sigtramp_cache_init): Likewise. * ppcobsd-tdep.c (ppcobsd_sigtramp_frame_cache): Likewise. * rs6000-tdep.c (ppc_dwarf2_frame_init_reg): Likewise. * m68hc11-tdep.c (m68hc11_frame_unwind_cache): Use get_frame_arch to get at the current architecture by frame_info. * gcore.c (derive_stack_segment): Likewise. * shnbsd-nat.c (GETREGS_SUPPLIES): Add gdbarch parameter. (shnbsd_fetch_inferior_registers, shnbsd_store_inferior_registers): Add gdbarch to GETREGS_SUPPLIES call.
2007-11-16 12:53:46 +08:00
store_register (regcache, tid, gdbarch_pc_regnum (gdbarch));
if (tdep->ppc_ps_regnum != -1)
* target.h (struct regcache): Add forward declaration. (struct target_ops): Add REGCACHE parameter to to_fetch_registers and to_store_registers target operations. (target_fetch_registers, target_store_registers): Update. * regcache.c (regcache_raw_read): Replace register_cached by regcache_valid_p. Pass regcache to target_fetch_registers. (regcache_raw_write): Pass regcache to target_store_registers. * arm-linux-nat.c (store_fpregister, store_fpregs, store_register, store_regs, store_wmmx_regs): Replace register_cached by regcache_valid_p. * bsd-kvm.c (bsd_kvm_open, bsd_kvm_proc_cmd): Pass current_regcache to target_fetch_registers calls. * corelow.c (core_open): Likewise. * linux-nat.c (linux_nat_corefile_thread_callback): Likewise. * proc-service.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * sol-thread.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * win32-nat.c (win32_resume): Likewise. * ia64-tdep.c (ia64_store_return_value): Pass current_regcache to target_store_registers call. * rs6000-tdep.c (rs6000_push_dummy_call): Likewise. * inferior.h (store_inferior_registers): Update prototype. (fetch_inferior_registers): Likewise. * gnu-nat.c (gnu_store_registers, gnu_fetch_registers): Likewise. * mips-linux-nat.c (super_fetch_registers, super_store_registers): Update function pointer signatures. * aix-thread.c (aix_thread_fetch_registers): Add REGCACHE parameter, use it instead of current_regcache, update calls. (aix_thread_store_registers): Likewise. * alphabsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * amd64bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_fpregister, fetch_fpregs, store_fpregister, store_fpregs, fetch_register, fetch_regs, store_register, store_regs, fetch_wmmx_regs, store_wmmx_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * armnbsd-nat.c (fetch_register, fetch_regs, fetch_fp_register, fetch_fp_regs, armnbsd_fetch_registers): Likewise. (store_register, store_regs, store_fp_register, store_fp_regs, armnbsd_store_registers): Likewise. * bsd-kvm.c (bsd_kvm_fetch_pcb, bsd_kvm_fetch_registers): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * corelow.c (get_core_registers): Likewise. * go32-nat.c (fetch_register, go32_fetch_registers, store_register, go32_store_registers): Likewise. * hppabsd-nat.c (hppabsd_fetch_registers): Likewise. (hppabsd_store_registers): Likewise. * hppa-hpux-nat.c (hppa_hpux_fetch_register): Likewise. (hppa_hpux_fetch_inferior_registers): Likewise. (hppa_hpux_store_register): Likewise. (hppa_hpux_store_inferior_registers): Likewise. * hppa-linux-nat.c (fetch_register, store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * hpux-thread.c (hpux_thread_fetch_registers): Likewise. (hpux_thread_store_registers): Likewise. * i386bsd-nat.c (i386bsd_fetch_inferior_registers): Likewise. (i386bsd_store_inferior_registers): Likewise. * i386gnu-nat.c (fetch_fpregs, gnu_fetch_registers, store_fpregs, gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register, store_register, fetch_regs, store_regs, fetch_fpregs, store_fpregs, fetch_fpxregs, store_fpxregs): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_register): Likewise. (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_register): Likewise. (ia64_linux_store_registers): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. (inf_child_store_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register): Likewise. (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_register): Likewise. (inf_ptrace_store_registers): Likewise. * infptrace.c (fetch_register, store_register): Likewise. (fetch_inferior_registers, store_inferior_registers): Likewise. * m32r-linux-nat.c (fetch_regs, store_regs): Likewise. (m32r_linux_fetch_inferior_registers): Likewise. (m32r_linux_store_inferior_registers): Likewise. * m68kbsd-nat.c (m68kbsd_fetch_inferior_registers): Likewise. (m68kbsd_store_inferior_registers): Likewise. * m68klinux-nat.c (fetch_register, old_fetch_inferior_registers, store_register, old_store_inferior_registers, fetch_regs, store_regs, fetch_fpregs, store_fpregs): Likewise. (m68k_linux_fetch_inferior_registers): Likewise. (m68k_linux_store_inferior_registers): Likewise. * m88kbsd-nat.c (m88kbsd_fetch_inferior_registers): Likewise. (m88kbsd_store_inferior_registers): Likewise. * mips64obsd-nat.c (mips64obsd_fetch_inferior_registers): Likewise. (mips64obsd_store_inferior_registers): Likewise. * mips-linux-nat.c (mips64_linux_regsets_fetch_registers): Likewise. (mips64_linux_regsets_store_registers): Likewise. (mips64_linux_fetch_registers): Likewise. (mips64_linux_store_registers): Likewise. * mipsnbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * monitor.c (monitor_fetch_register, monitor_store_register): Likewise. (monitor_fetch_registers, monitor_store_registers): Likewise. * nto-procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register, fetch_register, supply_vrregset, fetch_altivec_registers, fetch_ppc_registers, ppc_linux_fetch_inferior_registers): Likewise. (store_altivec_register, store_spe_register, store_register, fill_vrregset, store_altivec_registers, store_ppc_registers, ppc_linux_store_inferior_registers): Likewise. * ppcnbsd-nat.c (ppcnbsd_fetch_inferior_registers): Likewise. (ppcnbsd_store_inferior_registers): Likewise. * ppcobsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote.c (fetch_register_using_p, process_g_packet, fetch_registers_using_g, remote_fetch_registers): Likewise. (store_register_using_P, store_registers_using_G, remote_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers, m32r_fetch_register, m32r_store_register, m32r_store_register): Likewise. * remote-mips.c (mips_fetch_registers, mips_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * rs6000-nat.c (fetch_register, store_register): Likewise. (rs6000_fetch_inferior_registers): Likewise. (rs6000_store_inferior_registers): Likewise. * s390-nat.c (fetch_regs, store_regs): Likewise. (fetch_fpregs, store_fpregs): Likewise. (s390_linux_fetch_inferior_registers): Likewise. (s390_linux_store_inferior_registers): Likewise. * shnbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sol-thread.c (sol_thread_fetch_registers): Likewise. (sol_thread_store_registers): Likewise. * sparc-nat.c (fetch_inferior_registers): Likewise. (store_inferior_registers): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. (spu_store_inferior_registers): Likewise. * target.c (debug_print_register): Likewise. (debug_to_fetch_registers, debug_to_store_registers): Likewise. * vaxbsd-nat.c (vaxbsd_fetch_inferior_registers): Likewise. (vaxbsd_store_inferior_registers): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers): Likewise. (win32_fetch_inferior_registers): Likewise. (win32_store_inferior_registers): Likewise.
2007-05-06 22:34:38 +08:00
store_register (regcache, tid, tdep->ppc_ps_regnum);
if (tdep->ppc_cr_regnum != -1)
* target.h (struct regcache): Add forward declaration. (struct target_ops): Add REGCACHE parameter to to_fetch_registers and to_store_registers target operations. (target_fetch_registers, target_store_registers): Update. * regcache.c (regcache_raw_read): Replace register_cached by regcache_valid_p. Pass regcache to target_fetch_registers. (regcache_raw_write): Pass regcache to target_store_registers. * arm-linux-nat.c (store_fpregister, store_fpregs, store_register, store_regs, store_wmmx_regs): Replace register_cached by regcache_valid_p. * bsd-kvm.c (bsd_kvm_open, bsd_kvm_proc_cmd): Pass current_regcache to target_fetch_registers calls. * corelow.c (core_open): Likewise. * linux-nat.c (linux_nat_corefile_thread_callback): Likewise. * proc-service.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * sol-thread.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * win32-nat.c (win32_resume): Likewise. * ia64-tdep.c (ia64_store_return_value): Pass current_regcache to target_store_registers call. * rs6000-tdep.c (rs6000_push_dummy_call): Likewise. * inferior.h (store_inferior_registers): Update prototype. (fetch_inferior_registers): Likewise. * gnu-nat.c (gnu_store_registers, gnu_fetch_registers): Likewise. * mips-linux-nat.c (super_fetch_registers, super_store_registers): Update function pointer signatures. * aix-thread.c (aix_thread_fetch_registers): Add REGCACHE parameter, use it instead of current_regcache, update calls. (aix_thread_store_registers): Likewise. * alphabsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * amd64bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_fpregister, fetch_fpregs, store_fpregister, store_fpregs, fetch_register, fetch_regs, store_register, store_regs, fetch_wmmx_regs, store_wmmx_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * armnbsd-nat.c (fetch_register, fetch_regs, fetch_fp_register, fetch_fp_regs, armnbsd_fetch_registers): Likewise. (store_register, store_regs, store_fp_register, store_fp_regs, armnbsd_store_registers): Likewise. * bsd-kvm.c (bsd_kvm_fetch_pcb, bsd_kvm_fetch_registers): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * corelow.c (get_core_registers): Likewise. * go32-nat.c (fetch_register, go32_fetch_registers, store_register, go32_store_registers): Likewise. * hppabsd-nat.c (hppabsd_fetch_registers): Likewise. (hppabsd_store_registers): Likewise. * hppa-hpux-nat.c (hppa_hpux_fetch_register): Likewise. (hppa_hpux_fetch_inferior_registers): Likewise. (hppa_hpux_store_register): Likewise. (hppa_hpux_store_inferior_registers): Likewise. * hppa-linux-nat.c (fetch_register, store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * hpux-thread.c (hpux_thread_fetch_registers): Likewise. (hpux_thread_store_registers): Likewise. * i386bsd-nat.c (i386bsd_fetch_inferior_registers): Likewise. (i386bsd_store_inferior_registers): Likewise. * i386gnu-nat.c (fetch_fpregs, gnu_fetch_registers, store_fpregs, gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register, store_register, fetch_regs, store_regs, fetch_fpregs, store_fpregs, fetch_fpxregs, store_fpxregs): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_register): Likewise. (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_register): Likewise. (ia64_linux_store_registers): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. (inf_child_store_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register): Likewise. (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_register): Likewise. (inf_ptrace_store_registers): Likewise. * infptrace.c (fetch_register, store_register): Likewise. (fetch_inferior_registers, store_inferior_registers): Likewise. * m32r-linux-nat.c (fetch_regs, store_regs): Likewise. (m32r_linux_fetch_inferior_registers): Likewise. (m32r_linux_store_inferior_registers): Likewise. * m68kbsd-nat.c (m68kbsd_fetch_inferior_registers): Likewise. (m68kbsd_store_inferior_registers): Likewise. * m68klinux-nat.c (fetch_register, old_fetch_inferior_registers, store_register, old_store_inferior_registers, fetch_regs, store_regs, fetch_fpregs, store_fpregs): Likewise. (m68k_linux_fetch_inferior_registers): Likewise. (m68k_linux_store_inferior_registers): Likewise. * m88kbsd-nat.c (m88kbsd_fetch_inferior_registers): Likewise. (m88kbsd_store_inferior_registers): Likewise. * mips64obsd-nat.c (mips64obsd_fetch_inferior_registers): Likewise. (mips64obsd_store_inferior_registers): Likewise. * mips-linux-nat.c (mips64_linux_regsets_fetch_registers): Likewise. (mips64_linux_regsets_store_registers): Likewise. (mips64_linux_fetch_registers): Likewise. (mips64_linux_store_registers): Likewise. * mipsnbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * monitor.c (monitor_fetch_register, monitor_store_register): Likewise. (monitor_fetch_registers, monitor_store_registers): Likewise. * nto-procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register, fetch_register, supply_vrregset, fetch_altivec_registers, fetch_ppc_registers, ppc_linux_fetch_inferior_registers): Likewise. (store_altivec_register, store_spe_register, store_register, fill_vrregset, store_altivec_registers, store_ppc_registers, ppc_linux_store_inferior_registers): Likewise. * ppcnbsd-nat.c (ppcnbsd_fetch_inferior_registers): Likewise. (ppcnbsd_store_inferior_registers): Likewise. * ppcobsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote.c (fetch_register_using_p, process_g_packet, fetch_registers_using_g, remote_fetch_registers): Likewise. (store_register_using_P, store_registers_using_G, remote_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers, m32r_fetch_register, m32r_store_register, m32r_store_register): Likewise. * remote-mips.c (mips_fetch_registers, mips_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * rs6000-nat.c (fetch_register, store_register): Likewise. (rs6000_fetch_inferior_registers): Likewise. (rs6000_store_inferior_registers): Likewise. * s390-nat.c (fetch_regs, store_regs): Likewise. (fetch_fpregs, store_fpregs): Likewise. (s390_linux_fetch_inferior_registers): Likewise. (s390_linux_store_inferior_registers): Likewise. * shnbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sol-thread.c (sol_thread_fetch_registers): Likewise. (sol_thread_store_registers): Likewise. * sparc-nat.c (fetch_inferior_registers): Likewise. (store_inferior_registers): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. (spu_store_inferior_registers): Likewise. * target.c (debug_print_register): Likewise. (debug_to_fetch_registers, debug_to_store_registers): Likewise. * vaxbsd-nat.c (vaxbsd_fetch_inferior_registers): Likewise. (vaxbsd_store_inferior_registers): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers): Likewise. (win32_fetch_inferior_registers): Likewise. (win32_store_inferior_registers): Likewise.
2007-05-06 22:34:38 +08:00
store_register (regcache, tid, tdep->ppc_cr_regnum);
if (tdep->ppc_lr_regnum != -1)
* target.h (struct regcache): Add forward declaration. (struct target_ops): Add REGCACHE parameter to to_fetch_registers and to_store_registers target operations. (target_fetch_registers, target_store_registers): Update. * regcache.c (regcache_raw_read): Replace register_cached by regcache_valid_p. Pass regcache to target_fetch_registers. (regcache_raw_write): Pass regcache to target_store_registers. * arm-linux-nat.c (store_fpregister, store_fpregs, store_register, store_regs, store_wmmx_regs): Replace register_cached by regcache_valid_p. * bsd-kvm.c (bsd_kvm_open, bsd_kvm_proc_cmd): Pass current_regcache to target_fetch_registers calls. * corelow.c (core_open): Likewise. * linux-nat.c (linux_nat_corefile_thread_callback): Likewise. * proc-service.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * sol-thread.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * win32-nat.c (win32_resume): Likewise. * ia64-tdep.c (ia64_store_return_value): Pass current_regcache to target_store_registers call. * rs6000-tdep.c (rs6000_push_dummy_call): Likewise. * inferior.h (store_inferior_registers): Update prototype. (fetch_inferior_registers): Likewise. * gnu-nat.c (gnu_store_registers, gnu_fetch_registers): Likewise. * mips-linux-nat.c (super_fetch_registers, super_store_registers): Update function pointer signatures. * aix-thread.c (aix_thread_fetch_registers): Add REGCACHE parameter, use it instead of current_regcache, update calls. (aix_thread_store_registers): Likewise. * alphabsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * amd64bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_fpregister, fetch_fpregs, store_fpregister, store_fpregs, fetch_register, fetch_regs, store_register, store_regs, fetch_wmmx_regs, store_wmmx_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * armnbsd-nat.c (fetch_register, fetch_regs, fetch_fp_register, fetch_fp_regs, armnbsd_fetch_registers): Likewise. (store_register, store_regs, store_fp_register, store_fp_regs, armnbsd_store_registers): Likewise. * bsd-kvm.c (bsd_kvm_fetch_pcb, bsd_kvm_fetch_registers): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * corelow.c (get_core_registers): Likewise. * go32-nat.c (fetch_register, go32_fetch_registers, store_register, go32_store_registers): Likewise. * hppabsd-nat.c (hppabsd_fetch_registers): Likewise. (hppabsd_store_registers): Likewise. * hppa-hpux-nat.c (hppa_hpux_fetch_register): Likewise. (hppa_hpux_fetch_inferior_registers): Likewise. (hppa_hpux_store_register): Likewise. (hppa_hpux_store_inferior_registers): Likewise. * hppa-linux-nat.c (fetch_register, store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * hpux-thread.c (hpux_thread_fetch_registers): Likewise. (hpux_thread_store_registers): Likewise. * i386bsd-nat.c (i386bsd_fetch_inferior_registers): Likewise. (i386bsd_store_inferior_registers): Likewise. * i386gnu-nat.c (fetch_fpregs, gnu_fetch_registers, store_fpregs, gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register, store_register, fetch_regs, store_regs, fetch_fpregs, store_fpregs, fetch_fpxregs, store_fpxregs): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_register): Likewise. (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_register): Likewise. (ia64_linux_store_registers): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. (inf_child_store_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register): Likewise. (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_register): Likewise. (inf_ptrace_store_registers): Likewise. * infptrace.c (fetch_register, store_register): Likewise. (fetch_inferior_registers, store_inferior_registers): Likewise. * m32r-linux-nat.c (fetch_regs, store_regs): Likewise. (m32r_linux_fetch_inferior_registers): Likewise. (m32r_linux_store_inferior_registers): Likewise. * m68kbsd-nat.c (m68kbsd_fetch_inferior_registers): Likewise. (m68kbsd_store_inferior_registers): Likewise. * m68klinux-nat.c (fetch_register, old_fetch_inferior_registers, store_register, old_store_inferior_registers, fetch_regs, store_regs, fetch_fpregs, store_fpregs): Likewise. (m68k_linux_fetch_inferior_registers): Likewise. (m68k_linux_store_inferior_registers): Likewise. * m88kbsd-nat.c (m88kbsd_fetch_inferior_registers): Likewise. (m88kbsd_store_inferior_registers): Likewise. * mips64obsd-nat.c (mips64obsd_fetch_inferior_registers): Likewise. (mips64obsd_store_inferior_registers): Likewise. * mips-linux-nat.c (mips64_linux_regsets_fetch_registers): Likewise. (mips64_linux_regsets_store_registers): Likewise. (mips64_linux_fetch_registers): Likewise. (mips64_linux_store_registers): Likewise. * mipsnbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * monitor.c (monitor_fetch_register, monitor_store_register): Likewise. (monitor_fetch_registers, monitor_store_registers): Likewise. * nto-procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register, fetch_register, supply_vrregset, fetch_altivec_registers, fetch_ppc_registers, ppc_linux_fetch_inferior_registers): Likewise. (store_altivec_register, store_spe_register, store_register, fill_vrregset, store_altivec_registers, store_ppc_registers, ppc_linux_store_inferior_registers): Likewise. * ppcnbsd-nat.c (ppcnbsd_fetch_inferior_registers): Likewise. (ppcnbsd_store_inferior_registers): Likewise. * ppcobsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote.c (fetch_register_using_p, process_g_packet, fetch_registers_using_g, remote_fetch_registers): Likewise. (store_register_using_P, store_registers_using_G, remote_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers, m32r_fetch_register, m32r_store_register, m32r_store_register): Likewise. * remote-mips.c (mips_fetch_registers, mips_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * rs6000-nat.c (fetch_register, store_register): Likewise. (rs6000_fetch_inferior_registers): Likewise. (rs6000_store_inferior_registers): Likewise. * s390-nat.c (fetch_regs, store_regs): Likewise. (fetch_fpregs, store_fpregs): Likewise. (s390_linux_fetch_inferior_registers): Likewise. (s390_linux_store_inferior_registers): Likewise. * shnbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sol-thread.c (sol_thread_fetch_registers): Likewise. (sol_thread_store_registers): Likewise. * sparc-nat.c (fetch_inferior_registers): Likewise. (store_inferior_registers): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. (spu_store_inferior_registers): Likewise. * target.c (debug_print_register): Likewise. (debug_to_fetch_registers, debug_to_store_registers): Likewise. * vaxbsd-nat.c (vaxbsd_fetch_inferior_registers): Likewise. (vaxbsd_store_inferior_registers): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers): Likewise. (win32_fetch_inferior_registers): Likewise. (win32_store_inferior_registers): Likewise.
2007-05-06 22:34:38 +08:00
store_register (regcache, tid, tdep->ppc_lr_regnum);
if (tdep->ppc_ctr_regnum != -1)
* target.h (struct regcache): Add forward declaration. (struct target_ops): Add REGCACHE parameter to to_fetch_registers and to_store_registers target operations. (target_fetch_registers, target_store_registers): Update. * regcache.c (regcache_raw_read): Replace register_cached by regcache_valid_p. Pass regcache to target_fetch_registers. (regcache_raw_write): Pass regcache to target_store_registers. * arm-linux-nat.c (store_fpregister, store_fpregs, store_register, store_regs, store_wmmx_regs): Replace register_cached by regcache_valid_p. * bsd-kvm.c (bsd_kvm_open, bsd_kvm_proc_cmd): Pass current_regcache to target_fetch_registers calls. * corelow.c (core_open): Likewise. * linux-nat.c (linux_nat_corefile_thread_callback): Likewise. * proc-service.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * sol-thread.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * win32-nat.c (win32_resume): Likewise. * ia64-tdep.c (ia64_store_return_value): Pass current_regcache to target_store_registers call. * rs6000-tdep.c (rs6000_push_dummy_call): Likewise. * inferior.h (store_inferior_registers): Update prototype. (fetch_inferior_registers): Likewise. * gnu-nat.c (gnu_store_registers, gnu_fetch_registers): Likewise. * mips-linux-nat.c (super_fetch_registers, super_store_registers): Update function pointer signatures. * aix-thread.c (aix_thread_fetch_registers): Add REGCACHE parameter, use it instead of current_regcache, update calls. (aix_thread_store_registers): Likewise. * alphabsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * amd64bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_fpregister, fetch_fpregs, store_fpregister, store_fpregs, fetch_register, fetch_regs, store_register, store_regs, fetch_wmmx_regs, store_wmmx_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * armnbsd-nat.c (fetch_register, fetch_regs, fetch_fp_register, fetch_fp_regs, armnbsd_fetch_registers): Likewise. (store_register, store_regs, store_fp_register, store_fp_regs, armnbsd_store_registers): Likewise. * bsd-kvm.c (bsd_kvm_fetch_pcb, bsd_kvm_fetch_registers): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * corelow.c (get_core_registers): Likewise. * go32-nat.c (fetch_register, go32_fetch_registers, store_register, go32_store_registers): Likewise. * hppabsd-nat.c (hppabsd_fetch_registers): Likewise. (hppabsd_store_registers): Likewise. * hppa-hpux-nat.c (hppa_hpux_fetch_register): Likewise. (hppa_hpux_fetch_inferior_registers): Likewise. (hppa_hpux_store_register): Likewise. (hppa_hpux_store_inferior_registers): Likewise. * hppa-linux-nat.c (fetch_register, store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * hpux-thread.c (hpux_thread_fetch_registers): Likewise. (hpux_thread_store_registers): Likewise. * i386bsd-nat.c (i386bsd_fetch_inferior_registers): Likewise. (i386bsd_store_inferior_registers): Likewise. * i386gnu-nat.c (fetch_fpregs, gnu_fetch_registers, store_fpregs, gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register, store_register, fetch_regs, store_regs, fetch_fpregs, store_fpregs, fetch_fpxregs, store_fpxregs): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_register): Likewise. (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_register): Likewise. (ia64_linux_store_registers): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. (inf_child_store_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register): Likewise. (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_register): Likewise. (inf_ptrace_store_registers): Likewise. * infptrace.c (fetch_register, store_register): Likewise. (fetch_inferior_registers, store_inferior_registers): Likewise. * m32r-linux-nat.c (fetch_regs, store_regs): Likewise. (m32r_linux_fetch_inferior_registers): Likewise. (m32r_linux_store_inferior_registers): Likewise. * m68kbsd-nat.c (m68kbsd_fetch_inferior_registers): Likewise. (m68kbsd_store_inferior_registers): Likewise. * m68klinux-nat.c (fetch_register, old_fetch_inferior_registers, store_register, old_store_inferior_registers, fetch_regs, store_regs, fetch_fpregs, store_fpregs): Likewise. (m68k_linux_fetch_inferior_registers): Likewise. (m68k_linux_store_inferior_registers): Likewise. * m88kbsd-nat.c (m88kbsd_fetch_inferior_registers): Likewise. (m88kbsd_store_inferior_registers): Likewise. * mips64obsd-nat.c (mips64obsd_fetch_inferior_registers): Likewise. (mips64obsd_store_inferior_registers): Likewise. * mips-linux-nat.c (mips64_linux_regsets_fetch_registers): Likewise. (mips64_linux_regsets_store_registers): Likewise. (mips64_linux_fetch_registers): Likewise. (mips64_linux_store_registers): Likewise. * mipsnbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * monitor.c (monitor_fetch_register, monitor_store_register): Likewise. (monitor_fetch_registers, monitor_store_registers): Likewise. * nto-procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register, fetch_register, supply_vrregset, fetch_altivec_registers, fetch_ppc_registers, ppc_linux_fetch_inferior_registers): Likewise. (store_altivec_register, store_spe_register, store_register, fill_vrregset, store_altivec_registers, store_ppc_registers, ppc_linux_store_inferior_registers): Likewise. * ppcnbsd-nat.c (ppcnbsd_fetch_inferior_registers): Likewise. (ppcnbsd_store_inferior_registers): Likewise. * ppcobsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote.c (fetch_register_using_p, process_g_packet, fetch_registers_using_g, remote_fetch_registers): Likewise. (store_register_using_P, store_registers_using_G, remote_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers, m32r_fetch_register, m32r_store_register, m32r_store_register): Likewise. * remote-mips.c (mips_fetch_registers, mips_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * rs6000-nat.c (fetch_register, store_register): Likewise. (rs6000_fetch_inferior_registers): Likewise. (rs6000_store_inferior_registers): Likewise. * s390-nat.c (fetch_regs, store_regs): Likewise. (fetch_fpregs, store_fpregs): Likewise. (s390_linux_fetch_inferior_registers): Likewise. (s390_linux_store_inferior_registers): Likewise. * shnbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sol-thread.c (sol_thread_fetch_registers): Likewise. (sol_thread_store_registers): Likewise. * sparc-nat.c (fetch_inferior_registers): Likewise. (store_inferior_registers): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. (spu_store_inferior_registers): Likewise. * target.c (debug_print_register): Likewise. (debug_to_fetch_registers, debug_to_store_registers): Likewise. * vaxbsd-nat.c (vaxbsd_fetch_inferior_registers): Likewise. (vaxbsd_store_inferior_registers): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers): Likewise. (win32_fetch_inferior_registers): Likewise. (win32_store_inferior_registers): Likewise.
2007-05-06 22:34:38 +08:00
store_register (regcache, tid, tdep->ppc_ctr_regnum);
if (tdep->ppc_xer_regnum != -1)
* target.h (struct regcache): Add forward declaration. (struct target_ops): Add REGCACHE parameter to to_fetch_registers and to_store_registers target operations. (target_fetch_registers, target_store_registers): Update. * regcache.c (regcache_raw_read): Replace register_cached by regcache_valid_p. Pass regcache to target_fetch_registers. (regcache_raw_write): Pass regcache to target_store_registers. * arm-linux-nat.c (store_fpregister, store_fpregs, store_register, store_regs, store_wmmx_regs): Replace register_cached by regcache_valid_p. * bsd-kvm.c (bsd_kvm_open, bsd_kvm_proc_cmd): Pass current_regcache to target_fetch_registers calls. * corelow.c (core_open): Likewise. * linux-nat.c (linux_nat_corefile_thread_callback): Likewise. * proc-service.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * sol-thread.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * win32-nat.c (win32_resume): Likewise. * ia64-tdep.c (ia64_store_return_value): Pass current_regcache to target_store_registers call. * rs6000-tdep.c (rs6000_push_dummy_call): Likewise. * inferior.h (store_inferior_registers): Update prototype. (fetch_inferior_registers): Likewise. * gnu-nat.c (gnu_store_registers, gnu_fetch_registers): Likewise. * mips-linux-nat.c (super_fetch_registers, super_store_registers): Update function pointer signatures. * aix-thread.c (aix_thread_fetch_registers): Add REGCACHE parameter, use it instead of current_regcache, update calls. (aix_thread_store_registers): Likewise. * alphabsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * amd64bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_fpregister, fetch_fpregs, store_fpregister, store_fpregs, fetch_register, fetch_regs, store_register, store_regs, fetch_wmmx_regs, store_wmmx_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * armnbsd-nat.c (fetch_register, fetch_regs, fetch_fp_register, fetch_fp_regs, armnbsd_fetch_registers): Likewise. (store_register, store_regs, store_fp_register, store_fp_regs, armnbsd_store_registers): Likewise. * bsd-kvm.c (bsd_kvm_fetch_pcb, bsd_kvm_fetch_registers): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * corelow.c (get_core_registers): Likewise. * go32-nat.c (fetch_register, go32_fetch_registers, store_register, go32_store_registers): Likewise. * hppabsd-nat.c (hppabsd_fetch_registers): Likewise. (hppabsd_store_registers): Likewise. * hppa-hpux-nat.c (hppa_hpux_fetch_register): Likewise. (hppa_hpux_fetch_inferior_registers): Likewise. (hppa_hpux_store_register): Likewise. (hppa_hpux_store_inferior_registers): Likewise. * hppa-linux-nat.c (fetch_register, store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * hpux-thread.c (hpux_thread_fetch_registers): Likewise. (hpux_thread_store_registers): Likewise. * i386bsd-nat.c (i386bsd_fetch_inferior_registers): Likewise. (i386bsd_store_inferior_registers): Likewise. * i386gnu-nat.c (fetch_fpregs, gnu_fetch_registers, store_fpregs, gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register, store_register, fetch_regs, store_regs, fetch_fpregs, store_fpregs, fetch_fpxregs, store_fpxregs): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_register): Likewise. (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_register): Likewise. (ia64_linux_store_registers): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. (inf_child_store_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register): Likewise. (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_register): Likewise. (inf_ptrace_store_registers): Likewise. * infptrace.c (fetch_register, store_register): Likewise. (fetch_inferior_registers, store_inferior_registers): Likewise. * m32r-linux-nat.c (fetch_regs, store_regs): Likewise. (m32r_linux_fetch_inferior_registers): Likewise. (m32r_linux_store_inferior_registers): Likewise. * m68kbsd-nat.c (m68kbsd_fetch_inferior_registers): Likewise. (m68kbsd_store_inferior_registers): Likewise. * m68klinux-nat.c (fetch_register, old_fetch_inferior_registers, store_register, old_store_inferior_registers, fetch_regs, store_regs, fetch_fpregs, store_fpregs): Likewise. (m68k_linux_fetch_inferior_registers): Likewise. (m68k_linux_store_inferior_registers): Likewise. * m88kbsd-nat.c (m88kbsd_fetch_inferior_registers): Likewise. (m88kbsd_store_inferior_registers): Likewise. * mips64obsd-nat.c (mips64obsd_fetch_inferior_registers): Likewise. (mips64obsd_store_inferior_registers): Likewise. * mips-linux-nat.c (mips64_linux_regsets_fetch_registers): Likewise. (mips64_linux_regsets_store_registers): Likewise. (mips64_linux_fetch_registers): Likewise. (mips64_linux_store_registers): Likewise. * mipsnbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * monitor.c (monitor_fetch_register, monitor_store_register): Likewise. (monitor_fetch_registers, monitor_store_registers): Likewise. * nto-procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register, fetch_register, supply_vrregset, fetch_altivec_registers, fetch_ppc_registers, ppc_linux_fetch_inferior_registers): Likewise. (store_altivec_register, store_spe_register, store_register, fill_vrregset, store_altivec_registers, store_ppc_registers, ppc_linux_store_inferior_registers): Likewise. * ppcnbsd-nat.c (ppcnbsd_fetch_inferior_registers): Likewise. (ppcnbsd_store_inferior_registers): Likewise. * ppcobsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote.c (fetch_register_using_p, process_g_packet, fetch_registers_using_g, remote_fetch_registers): Likewise. (store_register_using_P, store_registers_using_G, remote_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers, m32r_fetch_register, m32r_store_register, m32r_store_register): Likewise. * remote-mips.c (mips_fetch_registers, mips_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * rs6000-nat.c (fetch_register, store_register): Likewise. (rs6000_fetch_inferior_registers): Likewise. (rs6000_store_inferior_registers): Likewise. * s390-nat.c (fetch_regs, store_regs): Likewise. (fetch_fpregs, store_fpregs): Likewise. (s390_linux_fetch_inferior_registers): Likewise. (s390_linux_store_inferior_registers): Likewise. * shnbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sol-thread.c (sol_thread_fetch_registers): Likewise. (sol_thread_store_registers): Likewise. * sparc-nat.c (fetch_inferior_registers): Likewise. (store_inferior_registers): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. (spu_store_inferior_registers): Likewise. * target.c (debug_print_register): Likewise. (debug_to_fetch_registers, debug_to_store_registers): Likewise. * vaxbsd-nat.c (vaxbsd_fetch_inferior_registers): Likewise. (vaxbsd_store_inferior_registers): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers): Likewise. (win32_fetch_inferior_registers): Likewise. (win32_store_inferior_registers): Likewise.
2007-05-06 22:34:38 +08:00
store_register (regcache, tid, tdep->ppc_xer_regnum);
if (tdep->ppc_mq_regnum != -1)
* target.h (struct regcache): Add forward declaration. (struct target_ops): Add REGCACHE parameter to to_fetch_registers and to_store_registers target operations. (target_fetch_registers, target_store_registers): Update. * regcache.c (regcache_raw_read): Replace register_cached by regcache_valid_p. Pass regcache to target_fetch_registers. (regcache_raw_write): Pass regcache to target_store_registers. * arm-linux-nat.c (store_fpregister, store_fpregs, store_register, store_regs, store_wmmx_regs): Replace register_cached by regcache_valid_p. * bsd-kvm.c (bsd_kvm_open, bsd_kvm_proc_cmd): Pass current_regcache to target_fetch_registers calls. * corelow.c (core_open): Likewise. * linux-nat.c (linux_nat_corefile_thread_callback): Likewise. * proc-service.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * sol-thread.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * win32-nat.c (win32_resume): Likewise. * ia64-tdep.c (ia64_store_return_value): Pass current_regcache to target_store_registers call. * rs6000-tdep.c (rs6000_push_dummy_call): Likewise. * inferior.h (store_inferior_registers): Update prototype. (fetch_inferior_registers): Likewise. * gnu-nat.c (gnu_store_registers, gnu_fetch_registers): Likewise. * mips-linux-nat.c (super_fetch_registers, super_store_registers): Update function pointer signatures. * aix-thread.c (aix_thread_fetch_registers): Add REGCACHE parameter, use it instead of current_regcache, update calls. (aix_thread_store_registers): Likewise. * alphabsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * amd64bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_fpregister, fetch_fpregs, store_fpregister, store_fpregs, fetch_register, fetch_regs, store_register, store_regs, fetch_wmmx_regs, store_wmmx_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * armnbsd-nat.c (fetch_register, fetch_regs, fetch_fp_register, fetch_fp_regs, armnbsd_fetch_registers): Likewise. (store_register, store_regs, store_fp_register, store_fp_regs, armnbsd_store_registers): Likewise. * bsd-kvm.c (bsd_kvm_fetch_pcb, bsd_kvm_fetch_registers): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * corelow.c (get_core_registers): Likewise. * go32-nat.c (fetch_register, go32_fetch_registers, store_register, go32_store_registers): Likewise. * hppabsd-nat.c (hppabsd_fetch_registers): Likewise. (hppabsd_store_registers): Likewise. * hppa-hpux-nat.c (hppa_hpux_fetch_register): Likewise. (hppa_hpux_fetch_inferior_registers): Likewise. (hppa_hpux_store_register): Likewise. (hppa_hpux_store_inferior_registers): Likewise. * hppa-linux-nat.c (fetch_register, store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * hpux-thread.c (hpux_thread_fetch_registers): Likewise. (hpux_thread_store_registers): Likewise. * i386bsd-nat.c (i386bsd_fetch_inferior_registers): Likewise. (i386bsd_store_inferior_registers): Likewise. * i386gnu-nat.c (fetch_fpregs, gnu_fetch_registers, store_fpregs, gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register, store_register, fetch_regs, store_regs, fetch_fpregs, store_fpregs, fetch_fpxregs, store_fpxregs): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_register): Likewise. (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_register): Likewise. (ia64_linux_store_registers): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. (inf_child_store_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register): Likewise. (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_register): Likewise. (inf_ptrace_store_registers): Likewise. * infptrace.c (fetch_register, store_register): Likewise. (fetch_inferior_registers, store_inferior_registers): Likewise. * m32r-linux-nat.c (fetch_regs, store_regs): Likewise. (m32r_linux_fetch_inferior_registers): Likewise. (m32r_linux_store_inferior_registers): Likewise. * m68kbsd-nat.c (m68kbsd_fetch_inferior_registers): Likewise. (m68kbsd_store_inferior_registers): Likewise. * m68klinux-nat.c (fetch_register, old_fetch_inferior_registers, store_register, old_store_inferior_registers, fetch_regs, store_regs, fetch_fpregs, store_fpregs): Likewise. (m68k_linux_fetch_inferior_registers): Likewise. (m68k_linux_store_inferior_registers): Likewise. * m88kbsd-nat.c (m88kbsd_fetch_inferior_registers): Likewise. (m88kbsd_store_inferior_registers): Likewise. * mips64obsd-nat.c (mips64obsd_fetch_inferior_registers): Likewise. (mips64obsd_store_inferior_registers): Likewise. * mips-linux-nat.c (mips64_linux_regsets_fetch_registers): Likewise. (mips64_linux_regsets_store_registers): Likewise. (mips64_linux_fetch_registers): Likewise. (mips64_linux_store_registers): Likewise. * mipsnbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * monitor.c (monitor_fetch_register, monitor_store_register): Likewise. (monitor_fetch_registers, monitor_store_registers): Likewise. * nto-procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register, fetch_register, supply_vrregset, fetch_altivec_registers, fetch_ppc_registers, ppc_linux_fetch_inferior_registers): Likewise. (store_altivec_register, store_spe_register, store_register, fill_vrregset, store_altivec_registers, store_ppc_registers, ppc_linux_store_inferior_registers): Likewise. * ppcnbsd-nat.c (ppcnbsd_fetch_inferior_registers): Likewise. (ppcnbsd_store_inferior_registers): Likewise. * ppcobsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote.c (fetch_register_using_p, process_g_packet, fetch_registers_using_g, remote_fetch_registers): Likewise. (store_register_using_P, store_registers_using_G, remote_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers, m32r_fetch_register, m32r_store_register, m32r_store_register): Likewise. * remote-mips.c (mips_fetch_registers, mips_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * rs6000-nat.c (fetch_register, store_register): Likewise. (rs6000_fetch_inferior_registers): Likewise. (rs6000_store_inferior_registers): Likewise. * s390-nat.c (fetch_regs, store_regs): Likewise. (fetch_fpregs, store_fpregs): Likewise. (s390_linux_fetch_inferior_registers): Likewise. (s390_linux_store_inferior_registers): Likewise. * shnbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sol-thread.c (sol_thread_fetch_registers): Likewise. (sol_thread_store_registers): Likewise. * sparc-nat.c (fetch_inferior_registers): Likewise. (store_inferior_registers): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. (spu_store_inferior_registers): Likewise. * target.c (debug_print_register): Likewise. (debug_to_fetch_registers, debug_to_store_registers): Likewise. * vaxbsd-nat.c (vaxbsd_fetch_inferior_registers): Likewise. (vaxbsd_store_inferior_registers): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers): Likewise. (win32_fetch_inferior_registers): Likewise. (win32_store_inferior_registers): Likewise.
2007-05-06 22:34:38 +08:00
store_register (regcache, tid, tdep->ppc_mq_regnum);
if (tdep->ppc_fpscr_regnum != -1)
* target.h (struct regcache): Add forward declaration. (struct target_ops): Add REGCACHE parameter to to_fetch_registers and to_store_registers target operations. (target_fetch_registers, target_store_registers): Update. * regcache.c (regcache_raw_read): Replace register_cached by regcache_valid_p. Pass regcache to target_fetch_registers. (regcache_raw_write): Pass regcache to target_store_registers. * arm-linux-nat.c (store_fpregister, store_fpregs, store_register, store_regs, store_wmmx_regs): Replace register_cached by regcache_valid_p. * bsd-kvm.c (bsd_kvm_open, bsd_kvm_proc_cmd): Pass current_regcache to target_fetch_registers calls. * corelow.c (core_open): Likewise. * linux-nat.c (linux_nat_corefile_thread_callback): Likewise. * proc-service.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * sol-thread.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * win32-nat.c (win32_resume): Likewise. * ia64-tdep.c (ia64_store_return_value): Pass current_regcache to target_store_registers call. * rs6000-tdep.c (rs6000_push_dummy_call): Likewise. * inferior.h (store_inferior_registers): Update prototype. (fetch_inferior_registers): Likewise. * gnu-nat.c (gnu_store_registers, gnu_fetch_registers): Likewise. * mips-linux-nat.c (super_fetch_registers, super_store_registers): Update function pointer signatures. * aix-thread.c (aix_thread_fetch_registers): Add REGCACHE parameter, use it instead of current_regcache, update calls. (aix_thread_store_registers): Likewise. * alphabsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * amd64bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_fpregister, fetch_fpregs, store_fpregister, store_fpregs, fetch_register, fetch_regs, store_register, store_regs, fetch_wmmx_regs, store_wmmx_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * armnbsd-nat.c (fetch_register, fetch_regs, fetch_fp_register, fetch_fp_regs, armnbsd_fetch_registers): Likewise. (store_register, store_regs, store_fp_register, store_fp_regs, armnbsd_store_registers): Likewise. * bsd-kvm.c (bsd_kvm_fetch_pcb, bsd_kvm_fetch_registers): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * corelow.c (get_core_registers): Likewise. * go32-nat.c (fetch_register, go32_fetch_registers, store_register, go32_store_registers): Likewise. * hppabsd-nat.c (hppabsd_fetch_registers): Likewise. (hppabsd_store_registers): Likewise. * hppa-hpux-nat.c (hppa_hpux_fetch_register): Likewise. (hppa_hpux_fetch_inferior_registers): Likewise. (hppa_hpux_store_register): Likewise. (hppa_hpux_store_inferior_registers): Likewise. * hppa-linux-nat.c (fetch_register, store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * hpux-thread.c (hpux_thread_fetch_registers): Likewise. (hpux_thread_store_registers): Likewise. * i386bsd-nat.c (i386bsd_fetch_inferior_registers): Likewise. (i386bsd_store_inferior_registers): Likewise. * i386gnu-nat.c (fetch_fpregs, gnu_fetch_registers, store_fpregs, gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register, store_register, fetch_regs, store_regs, fetch_fpregs, store_fpregs, fetch_fpxregs, store_fpxregs): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_register): Likewise. (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_register): Likewise. (ia64_linux_store_registers): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. (inf_child_store_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register): Likewise. (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_register): Likewise. (inf_ptrace_store_registers): Likewise. * infptrace.c (fetch_register, store_register): Likewise. (fetch_inferior_registers, store_inferior_registers): Likewise. * m32r-linux-nat.c (fetch_regs, store_regs): Likewise. (m32r_linux_fetch_inferior_registers): Likewise. (m32r_linux_store_inferior_registers): Likewise. * m68kbsd-nat.c (m68kbsd_fetch_inferior_registers): Likewise. (m68kbsd_store_inferior_registers): Likewise. * m68klinux-nat.c (fetch_register, old_fetch_inferior_registers, store_register, old_store_inferior_registers, fetch_regs, store_regs, fetch_fpregs, store_fpregs): Likewise. (m68k_linux_fetch_inferior_registers): Likewise. (m68k_linux_store_inferior_registers): Likewise. * m88kbsd-nat.c (m88kbsd_fetch_inferior_registers): Likewise. (m88kbsd_store_inferior_registers): Likewise. * mips64obsd-nat.c (mips64obsd_fetch_inferior_registers): Likewise. (mips64obsd_store_inferior_registers): Likewise. * mips-linux-nat.c (mips64_linux_regsets_fetch_registers): Likewise. (mips64_linux_regsets_store_registers): Likewise. (mips64_linux_fetch_registers): Likewise. (mips64_linux_store_registers): Likewise. * mipsnbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * monitor.c (monitor_fetch_register, monitor_store_register): Likewise. (monitor_fetch_registers, monitor_store_registers): Likewise. * nto-procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register, fetch_register, supply_vrregset, fetch_altivec_registers, fetch_ppc_registers, ppc_linux_fetch_inferior_registers): Likewise. (store_altivec_register, store_spe_register, store_register, fill_vrregset, store_altivec_registers, store_ppc_registers, ppc_linux_store_inferior_registers): Likewise. * ppcnbsd-nat.c (ppcnbsd_fetch_inferior_registers): Likewise. (ppcnbsd_store_inferior_registers): Likewise. * ppcobsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote.c (fetch_register_using_p, process_g_packet, fetch_registers_using_g, remote_fetch_registers): Likewise. (store_register_using_P, store_registers_using_G, remote_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers, m32r_fetch_register, m32r_store_register, m32r_store_register): Likewise. * remote-mips.c (mips_fetch_registers, mips_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * rs6000-nat.c (fetch_register, store_register): Likewise. (rs6000_fetch_inferior_registers): Likewise. (rs6000_store_inferior_registers): Likewise. * s390-nat.c (fetch_regs, store_regs): Likewise. (fetch_fpregs, store_fpregs): Likewise. (s390_linux_fetch_inferior_registers): Likewise. (s390_linux_store_inferior_registers): Likewise. * shnbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sol-thread.c (sol_thread_fetch_registers): Likewise. (sol_thread_store_registers): Likewise. * sparc-nat.c (fetch_inferior_registers): Likewise. (store_inferior_registers): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. (spu_store_inferior_registers): Likewise. * target.c (debug_print_register): Likewise. (debug_to_fetch_registers, debug_to_store_registers): Likewise. * vaxbsd-nat.c (vaxbsd_fetch_inferior_registers): Likewise. (vaxbsd_store_inferior_registers): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers): Likewise. (win32_fetch_inferior_registers): Likewise. (win32_store_inferior_registers): Likewise.
2007-05-06 22:34:38 +08:00
store_register (regcache, tid, tdep->ppc_fpscr_regnum);
ChangeLog: * Makefile.in (ppc_linux_tdep_h): New macro. (powerpc_32l_c, powerpc_altivec32_c, powerpc_altivec32l_c): Likewise. (powerpc_64l_c, powerpc_altivec64_c, powerpc_altivec64l_c): Likewise. (powerpc_e500l_c): Likewise. (ppc-linux-nat.o): Update dependencies. (ppc-linux-tdep.o): Update dependencies. (rs6000-tdep.o): Update dependencies. * ppc-tdep.h (ppc_linux_memory_remove_breakpoint): Remove. (ppc_linux_svr4_fetch_link_map_offsets): Remove. (ppc_linux_gregset, ppc_linux_fpregset): Move to ppc-linux-tdep.h (ppc_supply_reg, ppc_collect_reg): Add prototypes. (tdesc_powerpc_e500): Remove. * rs6000.c: Include "features/rs6000/powerpc-altivec32.c" and "features/rs6000/powerpc-altivec64.c". (ppc_supply_reg, ppc_collect_reg): Make global. (variants): Use tdesc_powerpc_32 for "powerpc" and tdesc_powerpc_altivec64 for "powerpc64". (_initialize_rs6000_tdep): Initialize AltiVec descriptions. * ppc-linux-tdep.h: New file. * ppc-linux-tdep.c: Include "ppc-linux-tdep.c". Include "features/rs6000/powerpc-32l.c". Include "features/rs6000/powerpc-altivec32l.c". Include "features/rs6000/powerpc-64l.c". Include "features/rs6000/powerpc-altivec64l.c". Include "features/rs6000/powerpc-e500l.c". (ppc_linux_supply_gregset): New function. (ppc_linux_collect_gregset): Handle orig_r3 and trap registers. (ppc32_linux_gregset): Use ppc_linux_supply_gregset. (ppc64_linux_gregset): Likewise. (ppc_linux_sigtramp_cache): Handle orig_r3 and trap registers. (ppc_linux_trap_reg_p): New function. (ppc_linux_write_pc): New function. (ppc_linux_core_read_description): New function. (ppc_linux_init_abi): Install ppc_linux_write_pc and ppc_linux_core_read_description. Install orig_r3 and trap registers if present in the target description. (_initialize_ppc_linux_tdep): Initialize Linux target descriptions. * ppc-linux-nat.c: Include "ppc-linux-tdep.h". (PT_ORIG_R3, PT_TRAP): Define if necessary. (ppc_register_u_addr): Handle orig_r3 and trap registers. (fetch_ppc_registers): Likewise. (store_ppc_registers): Likewise. (store_register): Likewise. (ppc_linux_read_description): Check whether AltiVec is supported. Check whether inferior is 32-bit or 64-bit. Return the appropriate Linux target description. * features/Makefile (WHICH): Use rs6000/powerpc-32l and rs6000/powerpc-altivec32l instead of rs6000/powerpc-32. Use rs6000/powerpc-64l and rs6000/powerpc-altivec64l instead of rs6000/powerpc-64. Use rs6000/powerpc-e500l instead of rs6000/powerpc-e500. Update -expedite variables accordingly. * features/rs6000/power-spe.xml: Use regnum 73 for "acc". * features/rs6000/powerpc-32.xml: Do not include power-altivec.xml. * features/rs6000/powerpc-64.xml: Do not include power-altivec.xml. * features/rs6000/powerpc-e500.c: Regenerate. * features/rs6000/powerpc-32.c: Regenerate. * features/rs6000/powerpc-64.c: Regenerate. * features/rs6000/power-linux.xml: New file. * features/rs6000/power64-linux.xml: New file. * features/rs6000/powerpc-32l.xml: New file. * features/rs6000/powerpc-altivec32l.xml: New file. * features/rs6000/powerpc-64l.xml: New file. * features/rs6000/powerpc-altivec64l.xml: New file. * features/rs6000/powerpc-e500l.xml: New file. * features/rs6000/powerpc-32l.c: New (generated) file. * features/rs6000/powerpc-altivec32l.c: New (generated) file. * features/rs6000/powerpc-64l.c: New (generated) file. * features/rs6000/powerpc-altivec64l.c: New (generated) file. * features/rs6000/powerpc-e500l.xml: New (generated) file. * regformats/reg-ppc.dat: Remove. * regformats/reg-ppc64.dat: Remove. * regformats/rs6000/powerpc-32.dat: Remove. * regformats/rs6000/powerpc-64.dat: Remove. * regformats/rs6000/powerpc-e500.dat: Remove. * regformats/rs6000/powerpc-32l.dat: New (generated) file. * regformats/rs6000/powerpc-altivec32l.dat: New (generated) file. * regformats/rs6000/powerpc-64l.dat: New (generated) file. * regformats/rs6000/powerpc-altivec64l.dat: New (generated) file. * regformats/rs6000/powerpc-e500l.dat: New (generated) file. gdbserver/ChangeLog: * configure.srv (powerpc*-*-linux*): Set srv_regobj to powerpc-32l.o, powerpc-altivec32l.o, powerpc-e500l.o, powerpc-64l.o, and powerpc-altivec64l.o. Remove rs6000/powerpc-32.xml, rs6000/powerpc-64.xml, and rs6000/powerpc-e500.xml; add rs6000/powerpc-32l.xml, rs6000/powerpc-altivec32l.xml, rs6000/powerpc-e500l.xml, rs6000/powerpc-64l.xml, rs6000/powerpc-altivec64l.xml, rs6000/power-linux.xml, and rs6000/power64-linux.xml to srv_xmlfiles. * Makefile.in (reg-ppc.o, reg-ppc.c): Remove, replace by ... (powerpc-32l.o, powerpc-32l.c): ... these new rules. (powerpc-32.o, powerpc-32.c): Remove, replace by ... (powerpc-altivec32l.o, powerpc-altivec32l.c): ... these new rules. (powerpc-e500.o, powerpc-e500.c): Remove, replace by ... (powerpc-e500l.o, powerpc-e500l.c): ... these new rules. (reg-ppc64.o, reg-ppc64.c): Remove, replace by ... (powerpc-64l.o, powerpc-64l.c): ... these new rules. (powerpc-64.o, powerpc-64.c): Remove, replace by ... (powerpc-altivec64l.o, powerpc-altivec64l.c): ... these new rules. (clean): Update. * linux-ppc-low.c (init_registers_ppc): Remove, replace by ... (init_registers_powerpc_32l): ... this new prototype. (init_registers_powerpc_32): Remove, replace by ... (init_registers_powerpc_altivec32l): ... this new prototype. (init_registers_powerpc_e500): Remove, replace by ... (init_registers_powerpc_e500l): ... this new prototype. (init_registers_ppc64): Remove, replace by ... (init_registers_powerpc_64l): ... this new prototype. (init_registers_powerpc_64): Remove, replace by ... (init_registers_powerpc_altivec64l): ... this new prototype. (ppc_num_regs): Set to 73. (PT_ORIG_R3, PT_TRAP): Define if necessary. (ppc_regmap, ppc_regmap_e500): Add values for orig_r3 and trap. (ppc_cannot_store_register): Handle orig_r3 and trap. (ppc_arch_setup): Update init_registers_... calls. (ppc_fill_gregset): Handle orig_r3 and trap. * inferiors.c (clear_inferiors): Reset current_inferior.
2008-05-04 01:16:44 +08:00
if (ppc_linux_trap_reg_p (gdbarch))
{
store_register (regcache, tid, PPC_ORIG_R3_REGNUM);
store_register (regcache, tid, PPC_TRAP_REGNUM);
}
if (have_ptrace_getvrregs)
if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1)
[PowerPC] Fix access to VSCR in linux targets The 4-byte VSCR register is found inside a 16-byte field in the regset returned by ptrace and in core files. The position of VSCR depends on the endianess of the target, which was previously assumed to be big-endian for the purpose of getting VSCR. This patch removes this assumption to fix access to VSCR in little-endian mode. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-tdep.h (struct ppc_reg_offsets): Remove vector register offset fields. * ppc-fbsd-tdep.c (ppc32_fbsd_reg_offsets): Remove initializers for vector register offset fields. (ppc64_fbsd_reg_offsets): Likewise. * ppc-nbsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment to vector register offset fields. * ppc-obsd-nat.c (_initialize_ppcobsd_nat): Remove assignment to vector register offset fields. * rs6000-aix-tdep.c (rs6000_aix32_reg_offsets): Remove initializers for vector register offset fields. (rs6000_aix64_reg_offsets): Likewise. * rs6000-tdep.c (ppc_vrreg_offset): Remove. (ppc_supply_vrregset): Remove. (ppc_collect_vrregset): Remove. * ppc-linux-tdep.c (ppc_linux_collect_vrregset): New function. (ppc_linux_vrregset) : New function. (ppc32_le_linux_vrregmap, ppc32_be_linux_vrregmap) (ppc32_le_linux_vrregset, ppc32_be_linux_vrregset): New globals. (ppc32_linux_vrregset): Remove. (ppc_linux_iterate_over_regset_sections): Call ppc_linux_vrregset and use result instead of ppc32_linux_vrregset. (ppc32_linux_reg_offsets): Remove initializers for vector register offset fields. (ppc64_linux_reg_offsets): Likewise. * ppc-linux-tdep.h (ppc_linux_vrregset): New declaration. * ppc-linux-nat.c: Include regset.h. (gdb_vrregset_t): Adjust comment to account for little-endian mode. (supply_vrregset, fill_vrregset): Remove. (fetch_altivec_register, store_altivec_register): Remove. (fetch_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to supply registers. (store_altivec_registers): Add regno parameter. Get regset using ppc_linux_vrregset. Use regset to collect registers. (fetch_register): Call fetch_altivec_registers instead of fetch_altivec_register. (store_register): Call store_altivec_registers instead of store_altivec_register. (fetch_ppc_registers): Call fetch_altivec_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_altivec_registers with -1 for the new regno parameter. gdb/gdbserver/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * linux-ppc-low.c (ppc_fill_vrregset): Add vscr_offset variable. Set vscr_offset to 0 in little-endian mode and 12 in big-endian mode. Call collect_register_by_name with vscr using vscr_offset. Zero-pad vscr and vrsave fields in collector buffer. (ppc_store_vrregset): Add and set vscr_offset variable as in ppc_fill_vrregset. Call supply_register_by_name with vscr using vscr_offset.
2018-05-22 22:09:05 +08:00
store_altivec_registers (regcache, tid, -1);
* rs6000-tdep: Include "features/rs6000/powerpc-vsx32.c". Include "features/rs6000/powerpc-vsx64.c". (ppc_supply_vsxregset): New function. (ppc_collect_vsxregset): New function. (IS_VSX_PSEUDOREG): New macro. (IS_EFP_PSEUDOREG): New macro. (vsx_register_p): New function. (ppc_vsx_support_p): New function. (rs6000_builtin_type_vec128): New function. (rs6000_register_name): Hide upper halves of vs0~vs31. Return correct names for VSX registers and EFPR registers. (rs6000_pseudo_register_type): Return correct types for VSX and EFPR registers. (rs6000_pseudo_register_reggroup_p): Return correct group for VSX and EFPR registers. (ppc_pseudo_register_read): Rename to dfp_pseudo_register_read. (ppc_pseudo_register_write): Rename to dfp_pseudo_register_write. (vsx_pseudo_register_read): New function. (vsx_pseudo_register_write): New function. (efpr_pseudo_register_read): New function. (efpr_pseudo_register_write): New function. (rs6000_pseudo_register_read): Call new VSX and EFPR read functions. (rs6000_pseudo_register_write): Call new VSX and EFPR write functions. (rs6000_gdbarch_init): Declare have_vsx. Initialize new upper half VSX registers. Initialize VSX-related and EFPR-related pseudo-registers variables. Adjust the number of pseudo registers accordingly. * ppc-linux-nat.c: Define PTRACE_GETVSXREGS, PTRACE_SETVSXREGS and SIZEOF_VSRREGS. (gdb_vsxregset_t): New type. (have_ptrace_getsetvsxregs): New variable. (fetch_vsx_register): New function. (fetch_register): Handle VSX registers. (fetch_vsx_registers): New function. (fetch_ppc_registers): Handle VSX registers. (store_ppc_registers): Handle VSX registers. (store_vsx_register): New function. (store_register): Handle VSX registers. (store_vsx_registers): New function. (ppc_linux_read_description): Handle VSX-enabled inferiors. (gdb_vsxregset_t): New type. (supply_vsxregset): New function. (fill_vsxregset): New function. * ppc-tdep.h (vsx_register_p): New prototype. (vsx_support_p): New prototype. (ppc_vsr0_regnum): New variable. (ppc_vsr0_upper_regnum): Likewise. (ppc_efpr0_regnum): Likewise. (ppc_builtin_type_vec128): New type. (ppc_num_vsrs): New constant. (ppc_num_vshrs): New constant. (ppc_num_efprs): Likewise. Define POWERPC_VEC_VSX PPC_VSR0_UPPER_REGNUM and PPC_VSR31_UPPER_REGNUM. (ppc_supply_vsxregset): New prototype. (ppc_collect_vsxregset): New prototype. * ppc-linux-tdep.c: Include "features/rs6000/powerpc-vsx32l.c" Include "features/rs6000/powerpc-vsx64l.c". (_initialize_ppc_linux_tdep): Initialize VSX-enabled targets. (ppc_linux_regset_sections): Add new ".reg-ppc-vsx" field. (ppc32_linux_vsxregset): New 32-bit VSX-enabled regset. (ppc_linux_regset_from_core_section): Handle VSX core section. (ppc_linux_core_read_description): Support VSX-enabled core files. * ppc-linux-tdep.h: Declare *tdesc_powerpc_vsx32l Declare tdesc_powerpc_vsx64l * corelow.c (get_core_register_section): Support VSX-enabled core files. * features/rs6000/power-vsx.xml: New VSX descriptions. * features/rs6000/powerpc-vsx32.xml: New file. * features/rs6000/powerpc-vsx32l.xml: New file. * features/rs6000/powerpc-vsx64.xml: New file. * features/rs6000/powerpc-vsx64l.xml: New file. * features/rs6000/powerpc-vsx32.c: New file (generated). * features/rs6000/powerpc-vsx32l.c: New file (generated). * features/rs6000/powerpc-vsx64.c: New file (generated). * features/rs6000/powerpc-vsx64l.c: New file (generated). * features/Makefile: Updated with new descriptions. * regformats/rs6000/powerpc-vsx32l.dat: New file (generated). * regformats/rs6000/powerpc-vsx64l.dat: New file (generated). * testsuite/gdb.arch/vsx-regs.c: New source file. * testsuite/gdb.arch/vsx-regs.exp: New testcase. * testsuite/lib/gdb.exp (skip_vsx_tests): New function.
2008-08-15 23:18:34 +08:00
if (have_ptrace_getsetvsxregs)
if (tdep->ppc_vsr0_upper_regnum != -1)
[PowerPC] Fix VSX registers in linux core files The functions used by the VSX regset to collect and supply registers from core files where incorrect. This patch changes the regset to use the standard regset collect/supply functions to fix this. The native target is also changed to use the same regset. gdb/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * ppc-linux-tdep.c (ppc_linux_vsxregset): New function. (ppc32_linux_vsxregmap): New global. (ppc32_linux_vsxregset): Initialize with ppc32_linux_vsxregmap, regcache_supply_regset, and regcache_collect_regset. * ppc-linux-tdep.h (ppc_linux_vsxregset): Declare. * ppc-linux-nat.c (supply_vsxregset, fill_vsxregset): Remove. (fetch_vsx_register, store_vsx_register): Remove. (fetch_vsx_registers): Add regno parameter. Get regset using ppc_linux_vsxregset. Use regset to supply registers. (store_vsx_registers): Add regno parameter. Get regset using ppc_linux_vsxregset. Use regset to collect registers. (fetch_register): Call fetch_vsx_registers instead of fetch_vsx_register. (store_register): Call store_vsx_registers instead of store_vsx_register. (fetch_ppc_registers): Call fetch_vsx_registers with -1 for the new regno parameter. (store_ppc_registers): Call store_vsx_registers with -1 for the new regno parameter. * rs6000-tdep.c (ppc_vsx_support_p, ppc_supply_vsxreget) (ppc_collect_vsxregset): Remove. gdb/testsuite/ChangeLog: 2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> * gdb.arch/powerpc-vsx-gcore.exp: New file.
2018-05-22 22:09:05 +08:00
store_vsx_registers (regcache, tid, -1);
Change the layout of the PowerPC E500 raw register cache to allow the lower 32-bit halves of the GPRS to be their own raw registers, not pseudoregisters. * ppc-tdep.h (struct gdbarch_tdep): Remove ppc_gprs_pseudo_p flag; add ppc_ev0_upper_regnum flag. * rs6000-tdep.c: #include "reggroups.h". (spe_register_p): Recognize the ev upper half registers as SPE registers. (init_sim_regno_table): Build gdb->sim mappings for the upper-half registers. (e500_move_ev_register): New function. (e500_pseudo_register_read, e500_pseudo_register_write): The 'ev' vector registers are the pseudo-registers now, formed by splicing together the gprs and the upper-half registers. (e500_register_reggroup_p): New function. (P): Macro deleted. (P8, A4): New macro. (PPC_EV_REGS, PPC_GPRS_PSEUDO_REGS): Macros deleted. (PPC_SPE_GP_REGS, PPC_SPE_UPPER_GP_REGS, PPC_EV_PSEUDO_REGS): New macros. (registers_e500): Rearrange register set so that the raw register set contains 32-bit GPRs and upper-half registers, and the SPE vector registers become pseudo-registers. (rs6000_gdbarch_init): Don't initialize tdep->ppc_gprs_pseudo_p; it has been deleted. Initialize ppc_ev0_upper_regnum. Many other register numbers are now the same for the E500 as they are for other PowerPC variants. Register e500_register_reggroup_p as the register group function for the E500. * Makefile.in (rs6000-tdep.o): Update dependencies. Adapt PPC E500 native support to the new raw regcache layout. * ppc-linux-nat.c (struct gdb_evrregset_t): Doc fixes. (read_spliced_spe_reg, write_spliced_spe_reg): Deleted. (fetch_spe_register, store_spe_register): Handle fetching/storing all the SPE registers at once, if regno == -1. These now take over the job of fetch_spe_registers and store_spe_registers. (fetch_spe_registers, store_spe_registers): Deleted. (fetch_ppc_registers, store_ppc_registers): Fetch/store gprs unconditionally; they're always raw. Fetch/store SPE upper half registers, if present, instead of ev registers. (fetch_register, store_register): Remove sanity checks: gprs are never pseudo-registers now, so we never need to even mention any registers that are ever pseudoregisters.
2004-08-05 01:17:55 +08:00
if (tdep->ppc_ev0_upper_regnum >= 0)
* target.h (struct regcache): Add forward declaration. (struct target_ops): Add REGCACHE parameter to to_fetch_registers and to_store_registers target operations. (target_fetch_registers, target_store_registers): Update. * regcache.c (regcache_raw_read): Replace register_cached by regcache_valid_p. Pass regcache to target_fetch_registers. (regcache_raw_write): Pass regcache to target_store_registers. * arm-linux-nat.c (store_fpregister, store_fpregs, store_register, store_regs, store_wmmx_regs): Replace register_cached by regcache_valid_p. * bsd-kvm.c (bsd_kvm_open, bsd_kvm_proc_cmd): Pass current_regcache to target_fetch_registers calls. * corelow.c (core_open): Likewise. * linux-nat.c (linux_nat_corefile_thread_callback): Likewise. * proc-service.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * sol-thread.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Likewise. * win32-nat.c (win32_resume): Likewise. * ia64-tdep.c (ia64_store_return_value): Pass current_regcache to target_store_registers call. * rs6000-tdep.c (rs6000_push_dummy_call): Likewise. * inferior.h (store_inferior_registers): Update prototype. (fetch_inferior_registers): Likewise. * gnu-nat.c (gnu_store_registers, gnu_fetch_registers): Likewise. * mips-linux-nat.c (super_fetch_registers, super_store_registers): Update function pointer signatures. * aix-thread.c (aix_thread_fetch_registers): Add REGCACHE parameter, use it instead of current_regcache, update calls. (aix_thread_store_registers): Likewise. * alphabsd-nat.c (alphabsd_fetch_inferior_registers): Likewise. (alphabsd_store_inferior_registers): Likewise. * amd64bsd-nat.c (amd64bsd_fetch_inferior_registers): Likewise. (amd64bsd_store_inferior_registers): Likewise. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Likewise. (amd64_linux_store_inferior_registers): Likewise. * arm-linux-nat.c (fetch_fpregister, fetch_fpregs, store_fpregister, store_fpregs, fetch_register, fetch_regs, store_register, store_regs, fetch_wmmx_regs, store_wmmx_regs): Likewise. (arm_linux_fetch_inferior_registers): Likewise. (arm_linux_store_inferior_registers): Likewise. * armnbsd-nat.c (fetch_register, fetch_regs, fetch_fp_register, fetch_fp_regs, armnbsd_fetch_registers): Likewise. (store_register, store_regs, store_fp_register, store_fp_regs, armnbsd_store_registers): Likewise. * bsd-kvm.c (bsd_kvm_fetch_pcb, bsd_kvm_fetch_registers): Likewise. * bsd-uthread.c (bsd_uthread_fetch_registers): Likewise. (bsd_uthread_store_registers): Likewise. * corelow.c (get_core_registers): Likewise. * go32-nat.c (fetch_register, go32_fetch_registers, store_register, go32_store_registers): Likewise. * hppabsd-nat.c (hppabsd_fetch_registers): Likewise. (hppabsd_store_registers): Likewise. * hppa-hpux-nat.c (hppa_hpux_fetch_register): Likewise. (hppa_hpux_fetch_inferior_registers): Likewise. (hppa_hpux_store_register): Likewise. (hppa_hpux_store_inferior_registers): Likewise. * hppa-linux-nat.c (fetch_register, store_register): Likewise. (hppa_linux_fetch_inferior_registers): Likewise. (hppa_linux_store_inferior_registers): Likewise. * hpux-thread.c (hpux_thread_fetch_registers): Likewise. (hpux_thread_store_registers): Likewise. * i386bsd-nat.c (i386bsd_fetch_inferior_registers): Likewise. (i386bsd_store_inferior_registers): Likewise. * i386gnu-nat.c (fetch_fpregs, gnu_fetch_registers, store_fpregs, gnu_store_registers): Likewise. * i386-linux-nat.c (fetch_register, store_register, fetch_regs, store_regs, fetch_fpregs, store_fpregs, fetch_fpxregs, store_fpxregs): Likewise. (i386_linux_fetch_inferior_registers): Likewise. (i386_linux_store_inferior_registers): Likewise. * ia64-linux-nat.c (ia64_linux_fetch_register): Likewise. (ia64_linux_fetch_registers): Likewise. (ia64_linux_store_register): Likewise. (ia64_linux_store_registers): Likewise. * inf-child.c (inf_child_fetch_inferior_registers): Likewise. (inf_child_store_inferior_registers): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register): Likewise. (inf_ptrace_fetch_registers): Likewise. (inf_ptrace_store_register): Likewise. (inf_ptrace_store_registers): Likewise. * infptrace.c (fetch_register, store_register): Likewise. (fetch_inferior_registers, store_inferior_registers): Likewise. * m32r-linux-nat.c (fetch_regs, store_regs): Likewise. (m32r_linux_fetch_inferior_registers): Likewise. (m32r_linux_store_inferior_registers): Likewise. * m68kbsd-nat.c (m68kbsd_fetch_inferior_registers): Likewise. (m68kbsd_store_inferior_registers): Likewise. * m68klinux-nat.c (fetch_register, old_fetch_inferior_registers, store_register, old_store_inferior_registers, fetch_regs, store_regs, fetch_fpregs, store_fpregs): Likewise. (m68k_linux_fetch_inferior_registers): Likewise. (m68k_linux_store_inferior_registers): Likewise. * m88kbsd-nat.c (m88kbsd_fetch_inferior_registers): Likewise. (m88kbsd_store_inferior_registers): Likewise. * mips64obsd-nat.c (mips64obsd_fetch_inferior_registers): Likewise. (mips64obsd_store_inferior_registers): Likewise. * mips-linux-nat.c (mips64_linux_regsets_fetch_registers): Likewise. (mips64_linux_regsets_store_registers): Likewise. (mips64_linux_fetch_registers): Likewise. (mips64_linux_store_registers): Likewise. * mipsnbsd-nat.c (mipsnbsd_fetch_inferior_registers): Likewise. (mipsnbsd_store_inferior_registers): Likewise. * monitor.c (monitor_fetch_register, monitor_store_register): Likewise. (monitor_fetch_registers, monitor_store_registers): Likewise. * nto-procfs.c (procfs_fetch_registers): Likewise. (procfs_store_registers): Likewise. * ppc-linux-nat.c (fetch_altivec_register, fetch_spe_register, fetch_register, supply_vrregset, fetch_altivec_registers, fetch_ppc_registers, ppc_linux_fetch_inferior_registers): Likewise. (store_altivec_register, store_spe_register, store_register, fill_vrregset, store_altivec_registers, store_ppc_registers, ppc_linux_store_inferior_registers): Likewise. * ppcnbsd-nat.c (ppcnbsd_fetch_inferior_registers): Likewise. (ppcnbsd_store_inferior_registers): Likewise. * ppcobsd-nat.c (ppcobsd_fetch_registers): Likewise. (ppcobsd_store_registers): Likewise. * procfs.c (procfs_fetch_registers, procfs_store_registers): Likewise. * remote.c (fetch_register_using_p, process_g_packet, fetch_registers_using_g, remote_fetch_registers): Likewise. (store_register_using_P, store_registers_using_G, remote_store_registers): Likewise. * remote-m32r-sdi.c (m32r_fetch_registers, m32r_fetch_register, m32r_store_register, m32r_store_register): Likewise. * remote-mips.c (mips_fetch_registers, mips_store_registers): Likewise. * remote-sim.c (gdbsim_fetch_register): Likewise. (gdbsim_store_register): Likewise. * rs6000-nat.c (fetch_register, store_register): Likewise. (rs6000_fetch_inferior_registers): Likewise. (rs6000_store_inferior_registers): Likewise. * s390-nat.c (fetch_regs, store_regs): Likewise. (fetch_fpregs, store_fpregs): Likewise. (s390_linux_fetch_inferior_registers): Likewise. (s390_linux_store_inferior_registers): Likewise. * shnbsd-nat.c (shnbsd_fetch_inferior_registers): Likewise. (shnbsd_store_inferior_registers): Likewise. * sol-thread.c (sol_thread_fetch_registers): Likewise. (sol_thread_store_registers): Likewise. * sparc-nat.c (fetch_inferior_registers): Likewise. (store_inferior_registers): Likewise. * spu-linux-nat.c (spu_fetch_inferior_registers): Likewise. (spu_store_inferior_registers): Likewise. * target.c (debug_print_register): Likewise. (debug_to_fetch_registers, debug_to_store_registers): Likewise. * vaxbsd-nat.c (vaxbsd_fetch_inferior_registers): Likewise. (vaxbsd_store_inferior_registers): Likewise. * win32-nat.c (do_win32_fetch_inferior_registers): Likewise. (win32_fetch_inferior_registers): Likewise. (win32_store_inferior_registers): Likewise.
2007-05-06 22:34:38 +08:00
store_spe_register (regcache, tid, -1);
[PowerPC] Add support for PPR and DSCR This patch adds gdb support for the Program Priorty Register and the Data Stream Control Register, for the powerpc linux native and core file targets, and for the powerpc linux server stub. gdb/ChangeLog: 2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * arch/ppc-linux-tdesc.h (tdesc_powerpc_isa205_ppr_dscr_vsx32l) (tdesc_powerpc_isa205_ppr_dscr_vsx64l): Declare. * arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_PPRREGSET) (PPC_LINUX_SIZEOF_DSCRREGSET): Define. (struct ppc_linux_features) <ppr_dscr>: New field. (ppc_linux_no_features): Add initializer for ppr_dscr field. * arch/ppc-linux-common.c (ppc_linux_match_description): Return new tdescs. * nat/ppc-linux.h (PPC_FEATURE2_DSCR, NT_PPC_PPR, NT_PPC_DSCR): Define if not already defined. * features/Makefile (WHICH): Add rs6000/powerpc-isa205-ppr-dscr-vsx32l and rs6000/powerpc-isa205-ppr-dscr-vsx64l. (XMLTOC): Add rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml and rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml. * features/rs6000/power-dscr.xml: New file. * features/rs6000/power-ppr.xml: New file. * features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml: New file. * features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml: New file. * features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.c: Generate. * features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.c: Generate. * regformats/rs6000/powerpc-isa205-ppr-dscr-vsx32l.dat: Generate. * regformats/rs6000/powerpc-isa205-ppr-dscr-vsx64l.dat: Generate. * ppc-linux-nat.c: Include <sys/uio.h>. (fetch_regset, store_regset, check_regset): New functions. (fetch_register, fetch_ppc_registers): Call fetch_regset with DSCR and PPR regsets. (store_register, store_ppc_registers): Call store_regset with DSCR and PPR regsets. (ppc_linux_get_hwcap2): New function. (ppc_linux_nat_target::read_description): Call ppc_linux_get_hwcap2 and check_regset, set ppr_dscr field in the features struct if needed. * ppc-linux-tdep.c: Include features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.c and features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.c. (ppc32_regmap_ppr, ppc32_regmap_dscr, ppc32_linux_pprregset) (ppc32_linux_dscrregset): New globals. (ppc_linux_iterate_over_regset_sections): Call back with the ppr and dscr regsets. (ppc_linux_core_read_description): Check if the ppr and dscr sections are present and set ppr_dscr in the features struct. (_initialize_ppc_linux_tdep): Call initialize_tdesc_powerpc_isa205_ppr_dscr_vsx32l and initialize_tdesc_powerpc_isa205_ppr_dscr_vsx64l. * ppc-linux-tdep.h (ppc32_linux_pprregset) (ppc32_linux_dscrregset): Declare. * ppc-tdep.h (struct gdbarch_tdep) <ppc_ppr_regnum>: New field. <ppc_dscr_regnum>: New field. (enum) <PPC_PPR_REGNUM, PPC_DSCR_REGNUM>: New enum values. * rs6000-tdep.c (rs6000_gdbarch_init): Look for and validate ppr and dscr features. (ppc_process_record_op31): Record changes to PPR and DSCR. gdb/gdbserver/ChangeLog: 2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * configure.srv (ipa_ppc_linux_regobj): Add powerpc-isa205-ppr-dscr-vsx32l-ipa.o and powerpc-isa205-ppr-dscr-vsx64l-ipa.o. (powerpc*-*-linux*): Add powerpc-isa205-ppr-dscr-vsx32l.o and powerpc-isa205-ppr-dscr-vsx64l.o to srv_regobj, add rs6000/power-dscr.xml, rs6000/power-ppr.xml, rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml and rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml to srv_xmlfiles. * linux-ppc-tdesc-init.h (enum ppc_linux_tdesc) <PPC_TDESC_ISA205_PPR_DSCR_VSX>: New enum value. (init_registers_powerpc_isa205_ppr_dscr_vsx32l) (init_registers_powerpc_isa205_ppr_dscr_vsx64l): Declare. * linux-ppc-low.c: Include "elf/common.h" and <sys/uio.h>. (ppc_hwcap): Add comment. (ppc_hwcap2): New global. (ppc_check_regset, ppc_fill_pprregset, ppc_store_pprregset) (ppc_fill_dscrregset, ppc_store_dscrregset): New functions. (ppc_regsets): Add entries for the DSCR and PPR regsets. (ppc_arch_setup): Get AT_HWCAP2. Set ppr_dscr in features struct when needed. Set sizes for the the DSCR and PPR regsets. (ppc_get_ipa_tdesc_idx): Return PPC_TDESC_ISA205_PPR_DSCR_VSX. (initialize_low_arch): Call init_registers_powerpc_isa205_ppr_dscr_vsx32l and init_registers_powerpc_isa205_ppr_dscr_vsx64l. * linux-ppc-ipa.c (get_ipa_tdesc): Handle PPC_TDESC_ISA205_PPR_DSCR_VSX. (initialize_low_tracepoint): Call init_registers_powerpc_isa205_ppr_dscr_vsx32l and init_registers_powerpc_isa205_ppr_dscr_vsx64l. gdb/testsuite/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.arch/powerpc-ppr-dscr.c: New file. * gdb.arch/powerpc-ppr-dscr.exp: New file. gdb/doc/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.texinfo (PowerPC Features): Describe new features "org.gnu.gdb.power.ppr" and "org.gnu.gdb.power.dscr".
2018-10-26 20:37:54 +08:00
if (tdep->ppc_ppr_regnum != -1)
store_regset (regcache, tid, -1, NT_PPC_PPR,
PPC_LINUX_SIZEOF_PPRREGSET,
&ppc32_linux_pprregset);
if (tdep->ppc_dscr_regnum != -1)
store_regset (regcache, tid, -1, NT_PPC_DSCR,
PPC_LINUX_SIZEOF_DSCRREGSET,
&ppc32_linux_dscrregset);
[PowerPC] Add support for TAR This patch adds support for the Target Address Register for powerpc linux native and core file targets, and in the powerpc linux server stub. gdb/ChangeLog: 2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * arch/ppc-linux-tdesc.h (tdesc_powerpc_isa207_vsx32l) (tdesc_powerpc_isa207_vsx64l): Declare. * arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_TARREGSET): Define. (struct ppc_linux_features) <isa207>: New field. (ppc_linux_no_features): Add initializer for isa207 field. * arch/ppc-linux-common.c (ppc_linux_match_description): Return new tdescs. * nat/ppc-linux.h (PPC_FEATURE2_ARCH_2_07, PPC_FEATURE2_TAR) (NT_PPC_TAR): Define if not already defined. * features/Makefile (WHICH): Add rs6000/powerpc-isa207-vsx32l and rs6000/powerpc-isa207-vsx64l. (XMLTOC): Add rs6000/powerpc-isa207-vsx32l.xml and rs6000/powerpc-isa207-vsx64l.xml. * features/rs6000/power-tar.xml: New file. * features/rs6000/powerpc-isa207-vsx32l.xml: New file. * features/rs6000/powerpc-isa207-vsx64l.xml: New file. * features/rs6000/powerpc-isa207-vsx32l.c: Generate. * features/rs6000/powerpc-isa207-vsx64l.c: Generate. * regformats/rs6000/powerpc-isa207-vsx32l.dat: Generate. * regformats/rs6000/powerpc-isa207-vsx64l.dat: Generate. * ppc-linux-nat.c (fetch_register, fetch_ppc_registers): Call fetch_regset with the TAR regset. (store_register, store_ppc_registers): Call store_regset with the TAR regset. (ppc_linux_nat_target::read_description): Set isa207 field in the features struct if needed. * ppc-linux-tdep.c: Include features/rs6000/powerpc-isa207-vsx32l.c and features/rs6000/powerpc-isa207-vsx64l.c. (ppc32_regmap_tar, ppc32_linux_tarregset): New globals. (ppc_linux_iterate_over_regset_sections): Call back with the tar regset. (ppc_linux_core_read_description): Check if the tar section is present and set isa207 in the features struct. (_initialize_ppc_linux_tdep): Call initialize_tdesc_powerpc_isa207_vsx32l and initialize_tdesc_powerpc_isa207_vsx64l. * ppc-linux-tdep.h (ppc32_linux_tarregset): Declare. * ppc-tdep.h (gdbarch_tdep) <ppc_tar_regnum>: New field. (enum) <PPC_TAR_REGNUM>: New enum value. * rs6000-tdep.c (rs6000_gdbarch_init): Look for and validate tar feature. (ppc_process_record_op31): Record changes to TAR. gdb/gdbserver/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * configure.srv (ipa_ppc_linux_regobj): Add powerpc-isa207-vsx64l-ipa.o and powerpc-isa207-vsx32l-ipa.o. (powerpc*-*-linux*): Add powerpc-isa207-vsx32l.o and powerpc-isa207-vsx64l.o to srv_regobj, add rs6000/power-tar.xml, rs6000/powerpc-isa207-vsx32l.xml, and rs6000/powerpc-isa207-vsx64l.xml to srv_xmlfiles. * linux-ppc-tdesc-init.h (enum ppc_linux_tdesc) <PPC_TDESC_ISA207_VSX>: New enum value. (init_registers_powerpc_isa207_vsx32l): Declare. (init_registers_powerpc_isa207_vsx64l): Declare. * linux-ppc-low.c (ppc_fill_tarregset): New function. (ppc_store_tarregset): New function. (ppc_regsets): Add entry for the TAR regset. (ppc_arch_setup): Set isa207 in features struct when needed. Set size for the TAR regsets. (ppc_get_ipa_tdesc_idx): Return PPC_TDESC_ISA207_VSX. (initialize_low_arch): Call init_registers_powerpc_isa207_vsx32l and init_registers_powerpc_isa207_vsx64l. * linux-ppc-ipa.c (get_ipa_tdesc): Handle PPC_TDESC_ISA207_VSX. (initialize_low_tracepoint): Call init_registers_powerpc_isa207_vsx32l and init_registers_powerpc_isa207_vsx64l. gdb/testsuite/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.arch/powerpc-tar.c: New file. * gdb.arch/powerpc-tar.exp: New file. gdb/doc/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.texinfo (PowerPC Features): Describe new feature "org.gnu.gdb.power.tar".
2018-10-26 20:37:54 +08:00
if (tdep->ppc_tar_regnum != -1)
store_regset (regcache, tid, -1, NT_PPC_TAR,
PPC_LINUX_SIZEOF_TARREGSET,
&ppc32_linux_tarregset);
[PowerPC] Add support for EBB and PMU registers This patch adds support for registers of the Event Based Branching and Performance Monitoring Units for the powerpc linux native and core file targets, and for the powerpc linux server stub. All three EBB registers are accessible. Only a subset of the PMU registers can be accessed through ptrace. Because of this, the PMU registers are enumerated individually in gdbarch_tdep, as opposed to having a single "have_pmu" flag. This is intended to make it easier to add additional PMU registers in the future, since checking a "have_pmu" flag elsewhere in the code would no longer be correct. The tdesc feature is named org.gnu.gdb.power.linux.pmu because of this. It's unclear if it makes sense to save and restore these registers across function calls, since some of them can be modified asynchronously. They are also not tracked in record-replay mode. The kernel can return ENODATA when ptrace is used to get the EBB registers, unless a linux performance event that uses EBB is open in the inferior. For this reason, the "fill" functions in the server stub for the ebb register sets is not implemented. Since gdbserver writes all registers in one go before resuming the inferior, this error would not be detected at the time the user tries to write to one of the registers on the client side, and gdbserver would print out warnings every time it resumes the inferior when no ebb performance event is opened, so there is currently no straightforward way to handle this case. This means the ebb registers in the client-side regcache can become dirty when the user tries to write to them, until the inferior is resumed and stopped again. A related issue is that 'G' packets used to write to unrelated registers will include bad data for the EBB registers if they are unavailable, since no register status information is included in the 'G' packet. This data won't be written to the inferior by the gdbserver stub because the "fill" functions are not implemented, and currently the gdbserver stub doesn't change the status of the registers in its own regcache in response to 'G' packets. Another limitation for the ebb registers is that traceframes don't record if registers are available or not, so if these registers are collected when a tracepoint is hit and the inferior has no ebb event opened, the user will see zero values for all of them, instead of the usual <unavailable>. Because these registers are often unavailable, trying to store them with target_store_registers with -1 for the regno argument (all registers) would almost always fail, so they are ignored in this case. gdb/ChangeLog: 2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_EBBREGSET) (PPC_LINUX_SIZEOF_PMUREGSET): Declare. * nat/ppc-linux.h (PPC_FEATURE2_EBB, NT_PPC_EBB, NT_PPC_PMU): Define if not already defined. * features/rs6000/power-ebb.xml: New file. * features/rs6000/power-linux-pmu.xml: New file. * features/rs6000/powerpc-isa207-vsx32l.xml: Include ebb and pmu features. * features/rs6000/powerpc-isa207-vsx64l.xml: Likewise. * features/rs6000/powerpc-isa207-vsx32l.c: Re-generate. * features/rs6000/powerpc-isa207-vsx64l.c: Re-generate. * regformats/rs6000/powerpc-isa207-vsx32l.dat: Re-generate. * regformats/rs6000/powerpc-isa207-vsx64l.dat: Re-generate. * ppc-linux-nat.c (fetch_register, fetch_ppc_registers): Call fetch_regset with ebb and pmu regsets. (store_register, store_ppc_registers): Call store_regset with ebb and pmu regsets. (ppc_linux_nat_target::read_description): Set isa207 field in the features struct if ebb and pmu are avaiable. * ppc-linux-tdep.c (ppc32_regmap_ebb, ppc32_regmap_pmu) (ppc32_linux_ebbregset, ppc32_linux_pmuregset): New globals. (ppc_linux_iterate_over_regset_sections): Call back with the ebb and pmu regsets. (ppc_linux_core_read_description): Check if the pmu section is present and set isa207 in the features struct. * ppc-linux-tdep.h (ppc32_linux_ebbregset) (ppc32_linux_pmuregset): Declare. * ppc-tdep.h (struct gdbarch_tdep) <ppc_mmcr0_regnum>: New field. <ppc_mmcr2_regnum, ppc_siar_regnum, ppc_sdar_regnum>: New fields. <ppc_sier_regnum>: New field. (enum): <PPC_BESCR_REGNUM, PPC_EBBHR_REGNUM, PPC_EBBRR_REGNUM>: New enum values. <PPC_MMCR0_REGNUM, PPC_MMCR2_REGNUM, PPC_SIAR_REGNUM>: New enum values. <PPC_SDAR_REGNUM, PPC_SIER_REGNUM>: New enum values. (PPC_IS_EBB_REGNUM, PPC_IS_PMU_REGNUM): Define. * rs6000-tdep.c (rs6000_gdbarch_init): Look for and validate the ebb and pmu features. gdb/gdbserver/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * configure.srv (powerpc*-*-linux*): Add rs6000/power-ebb.xml and rs6000/power-linux-pmu.xml to srv_xmlfiles. * linux-ppc-low.c (ppc_store_ebbregset, ppc_fill_pmuregset) (ppc_store_pmuregset): New functions. (ppc_regsets): Add entries for ebb and pmu regsets. (ppc_arch_setup): Set isa207 in features struct if the ebb and pmu regsets are available. Set sizes for these regsets. gdb/doc/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.texinfo (PowerPC Features): Describe new features "org.gnu.gdb.power.ebb" and "org.gnu.gdb.power.linux.pmu".
2018-10-26 20:37:54 +08:00
if (tdep->ppc_mmcr0_regnum != -1)
store_regset (regcache, tid, -1, NT_PPC_PMU,
PPC_LINUX_SIZEOF_PMUREGSET,
&ppc32_linux_pmuregset);
[PowerPC] Add support for HTM registers This patch adds support for Hardware Transactional Memory registers for the powerpc linux native and core file targets, and for the pwoerpc linux server stub. These registers include both the HTM special-purpose registers (TFHAR, TEXASR and TFIAR) as well as the set of registers that are checkpointed (saved) when a transaction is initiated, which the processor restores in the event of a transaction failure. The set of checkpointed general-purpose registers is returned by the linux kernel in the same format as the regular general-purpose registers, defined in struct pt_regs. However, the architecture specifies that only some of the registers present in pt_regs are checkpointed (GPRs 0-31, CR, XER, LR and CTR). The kernel fills the slots for MSR and NIP with other info. The other fields usually don't have meaningful values. GDB doesn't define registers that are not checkpointed in the architecture, but when generating a core file, GDB fills the slot for the checkpointed MSR with the regular MSR. These are usually similar, although some bits might be different, and in some cases the checkpointed MSR will have a value of 0 in a kernel-generated core-file. The checkpointed NIP is filled with TFHAR by GDB in the core-file, which is what the kernel does. The other fields are set to 0 by GDB. Core files generated by the kernel have a note section for checkpointed GPRs with the same size for both 32-bit and 64-bit threads, and the values for the registers of a 32-bit thread are squeezed in the first half, with no useful data in the second half. GDB generates a smaller note section for 32-bit threads, but can read both sizes. The checkpointed XER is required to be 32-bit in the target description documentation, even though the more recent ISAs define it as 64-bit wide, since the high-order 32-bits are reserved, and because in Linux there is no way to get a 64-bit checkpointed XER for 32-bit threads. If this changes in the future, the target description feature requirement can be relaxed to allow for a 64-bit checkpointed XER. Access to the checkpointed CR (condition register) can be confusing. The architecture only specifies that CR fields 1 to 7 (the 24 least significant bits) are checkpointed, but the kernel provides all 8 fields (32 bits). The value of field 0 is not masked by ptrace, so it will sometimes show the result of some kernel operation, probably treclaim., which sets this field. The checkpointed registers are marked not to be saved and restored. Inferior function calls during an active transaction don't work well, and it's unclear what should be done in this case. TEXASR and TFIAR can be altered asynchronously, during transaction failure recording, so they are also not saved and restored. For consistency neither is TFHAR. Record and replay also doesn't work well when transactions are involved. This patch doesn't address this, so the values of the HTM SPRs will sometimes be innacurate when the record/relay target is enabled. For instance, executing a "tbegin." alters TFHAR and TEXASR, but these changes are not currently recorded. Because the checkpointed registers are only available when a transaction is active (or suspended), ptrace can return ENODATA when gdb tries to read these registers and the inferior is not in a transactional state. The registers are set to the unavailable state when this happens. When gbd tries to write to one of these registers, and it is unavailable, an error is raised. The "fill" functions for checkpointed register sets in the server stub are not implemented for the same reason as for the EBB register set, since ptrace can also return ENODATA for checkpointed regsets. The same issues with 'G' packets apply here. Just like for the EBB registers, tracepoints will not mark the checkpointed registers as unavailable if the inferior was not in a transaction, so their content will also show 0 instead of <unavailable> when inspecting trace data. The new tests record the values of the regular registers before stepping the inferior through a "tbegin." instruction to start a transaction, then the checkpointed registers are checked against the recorded pre-transactional values. New values are written to the checkpointed registers and recorded, the inferior continues until the transaction aborts (which is usually immediately when it is resumed), and the regular registers are checked against the recorded values, because the abort should have reverted the registers to these values. Like for the EBB registers, target_store_registers will ignore the checkpointed registers when called with -1 as the regno argument (store all registers in one go). gdb/ChangeLog: 2018-10-26 Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com> Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * arch/ppc-linux-tdesc.h (tdesc_powerpc_isa207_htm_vsx32l) (tdesc_powerpc_isa207_htm_vsx64l): Declare. * arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_TM_SPRREGSET) (PPC32_LINUX_SIZEOF_CGPRREGSET, PPC64_LINUX_SIZEOF_CGPRREGSET) (PPC_LINUX_SIZEOF_CFPRREGSET, PPC_LINUX_SIZEOF_CVMXREGSET) (PPC_LINUX_SIZEOF_CVSXREGSET, PPC_LINUX_SIZEOF_CPPRREGSET) (PPC_LINUX_SIZEOF_CDSCRREGSET, PPC_LINUX_SIZEOF_CTARREGSET): Define. (struct ppc_linux_features) <htm>: New field. (ppc_linux_no_features): Add initializer for htm field. * arch/ppc-linux-common.c (ppc_linux_match_description): Return new tdescs. * nat/ppc-linux.h (PPC_FEATURE2_HTM, NT_PPC_TM_CGPR) (NT_PPC_TM_CFPR, NT_PPC_TM_CVMX, NT_PPC_TM_CVSX) (NT_PPC_TM_SPR, NT_PPC_TM_CTAR, NT_PPC_TM_CPPR, NT_PPC_TM_CDSCR): Define if not already defined. * features/Makefile (WHICH): Add rs6000/powerpc-isa207-htm-vsx32l and rs6000/powerpc-isa207-htm-vsx64l. (XMLTOC): Add rs6000/powerpc-isa207-htm-vsx32l.xml and rs6000/powerpc-isa207-htm-vsx64l.xml. * features/rs6000/power-htm-spr.xml: New file. * features/rs6000/power-htm-core.xml: New file. * features/rs6000/power64-htm-core.xml: New file. * features/rs6000/power-htm-fpu.xml: New file. * features/rs6000/power-htm-altivec.xml: New file. * features/rs6000/power-htm-vsx.xml: New file. * features/rs6000/power-htm-ppr.xml: New file. * features/rs6000/power-htm-dscr.xml: New file. * features/rs6000/power-htm-tar.xml: New file. * features/rs6000/powerpc-isa207-htm-vsx32l.xml: New file. * features/rs6000/powerpc-isa207-htm-vsx64l.xml: New file. * features/rs6000/powerpc-isa207-htm-vsx32l.c: Generate. * features/rs6000/powerpc-isa207-htm-vsx64l.c: Generate. * regformats/rs6000/powerpc-isa207-htm-vsx32l.dat: Generate. * regformats/rs6000/powerpc-isa207-htm-vsx64l.dat: Generate. * ppc-linux-nat.c (fetch_register, fetch_ppc_registers): Call fetch_regset with HTM regsets. (store_register, store_ppc_registers): Call store_regset with HTM regsets. (ppc_linux_nat_target::read_description): Set htm field in the features struct if needed. * ppc-linux-tdep.c: Include features/rs6000/powerpc-isa207-htm-vsx32l.c and features/rs6000/powerpc-isa207-htm-vsx64l.c. (ppc32_regmap_tm_spr, ppc32_regmap_cgpr, ppc64_le_regmap_cgpr) (ppc64_be_regmap_cgpr, ppc32_regmap_cfpr, ppc32_le_regmap_cvmx) (ppc32_be_regmap_cvmx, ppc32_regmap_cvsx, ppc32_regmap_cppr) (ppc32_regmap_cdscr, ppc32_regmap_ctar): New globals. (ppc32_linux_tm_sprregset, ppc32_linux_cgprregset) (ppc64_be_linux_cgprregset, ppc64_le_linux_cgprregset) (ppc32_linux_cfprregset, ppc32_le_linux_cvmxregset) (ppc32_be_linux_cvmxregset, ppc32_linux_cvsxregset) (ppc32_linux_cpprregset, ppc32_linux_cdscrregset) (ppc32_linux_ctarregset): New globals. (ppc_linux_cgprregset, ppc_linux_cvmxregset): New functions. (ppc_linux_collect_core_cpgrregset): New function. (ppc_linux_iterate_over_regset_sections): Call back with the htm regsets. (ppc_linux_core_read_description): Check if the tm spr section is present and set htm in the features struct. (_initialize_ppc_linux_tdep): Call initialize_tdesc_powerpc_isa207_htm_vsx32l and initialize_tdesc_powerpc_isa207_htm_vsx64l. * ppc-linux-tdep.h (ppc_linux_cgprregset, ppc_linux_cvmxregset): Declare. (ppc32_linux_tm_sprregset, ppc32_linux_cfprregset) (ppc32_linux_cvsxregset, ppc32_linux_cpprregset) (ppc32_linux_cdscrregset, ppc32_linux_ctarregset): Declare. * ppc-tdep.h (struct gdbarch_tdep) <have_htm_spr, have_htm_core>: New fields. <have_htm_fpu, have_htm_altivec, have_htm_vsx>: Likewise. <ppc_cppr_regnum, ppc_cdscr_regnum, ppc_ctar_regnum>: Likewise. <ppc_cdl0_regnum, ppc_cvsr0_regnum, ppc_cefpr0_regnum>: Likewise. (enum) <PPC_TFHAR_REGNUM, PPC_TEXASR_REGNUM, PPC_TFIAR_REGNUM>: New enum fields. <PPC_CR0_REGNUM, PPC_CCR_REGNUM, PPC_CXER_REGNUM>: Likewise. <PPC_CLR_REGNUM, PPC_CCTR_REGNUM, PPC_CF0_REGNUM>: Likewise. <PPC_CFPSCR_REGNUM, PPC_CVR0_REGNUM, PPC_CVSCR_REGNUM>: Likewise. <PPC_CVRSAVE_REGNUM, PPC_CVSR0_UPPER_REGNUM>: Likewise. <PPC_CPPR_REGNUM, PPC_CDSCR_REGNUM>: Likewise. <PPC_CTAR_REGNUM>: Likewise. (PPC_IS_TMSPR_REGNUM, PPC_IS_CKPTGP_REGNUM, PPC_IS_CKPTFP_REGNUM) (PPC_IS_CKPTVMX_REGNUM, PPC_IS_CKPTVSX_REGNUM): Define. * rs6000-tdep.c (IS_CDFP_PSEUDOREG, IS_CVSX_PSEUDOREG) (IS_CEFP_PSEUDOREG): Define. (rs6000_register_name): Hide the upper halves of checkpointed VSX registers. Return names for the checkpointed DFP, VSX, and EFP pseudo registers. (rs6000_pseudo_register_type): Remove initial assert and raise an internal error in the else clause instead. Return types for the checkpointed DFP, VSX, and EFP pseudo registers. (dfp_pseudo_register_read, dfp_pseudo_register_write): Handle checkpointed DFP pseudo registers. (vsx_pseudo_register_read, vsx_pseudo_register_write): Handle checkpointed VSX pseudo registers. (efp_pseudo_register_read, efp_pseudo_register_write): Rename from efpr_pseudo_register_read and efpr_pseudo_register_write. Handle checkpointed EFP pseudo registers. (rs6000_pseudo_register_read, rs6000_pseudo_register_write): Handle checkpointed DFP, VSX, and EFP registers. (dfp_ax_pseudo_register_collect, vsx_ax_pseudo_register_collect) (efp_ax_pseudo_register_collect): New functions. (rs6000_ax_pseudo_register_collect): Move DFP, VSX and EFP pseudo register logic to new functions. Handle checkpointed DFP, VSX, and EFP pseudo registers. (rs6000_gdbarch_init): Look for and validate the htm features. Include checkpointed DFP, VSX and EFP pseudo-registers. * NEWS: Mention access to PPR, DSCR, TAR, EBB/PMU registers and HTM registers. gdb/gdbserver/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * configure.srv (ipa_ppc_linux_regobj): Add powerpc-isa207-htm-vsx32l-ipa.o and powerpc-isa207-htm-vsx64l-ipa.o. (powerpc*-*-linux*): Add powerpc-isa207-htm-vsx32l.o and powerpc-isa207-htm-vsx64l.o to srv_regobj. Add rs6000/power-htm-spr.xml, rs6000/power-htm-core.xml, rs6000/power64-htm-core.xml, rs6000/power-htm-fpu.xml, rs6000/power-htm-altivec.xml, rs6000/power-htm-vsx.xml, rs6000/power-htm-ppr.xml, rs6000/power-htm-dscr.xml, rs6000/power-htm-tar.xml, rs6000/powerpc-isa207-htm-vsx32l.xml, and rs6000/powerpc-isa207-htm-vsx64l.xml to srv_xmlfiles. * linux-ppc-tdesc-init.h (enum ppc_linux_tdesc) <PPC_TDESC_ISA207_HTM_VSX>: New enum value. (init_registers_powerpc_isa207_htm_vsx32l) (init_registers_powerpc_isa207_htm_vsx64l): Declare. * linux-ppc-low.c (ppc_fill_tm_sprregset, ppc_store_tm_sprregset) (ppc_store_tm_cgprregset, ppc_store_tm_cfprregset) (ppc_store_tm_cvrregset, ppc_store_tm_cvsxregset) (ppc_store_tm_cpprregset, ppc_store_tm_cdscrregset) (ppc_store_tm_ctarregset): New functions. (ppc_regsets): Add entries for HTM regsets. (ppc_arch_setup): Set htm in features struct when needed. Set sizes for the HTM regsets. (ppc_get_ipa_tdesc_idx): Return PPC_TDESC_ISA207_HTM_VSX. (initialize_low_arch): Call init_registers_powerpc_isa207_htm_vsx32l and init_registers_powerpc_isa207_htm_vsx64l. * linux-ppc-ipa.c (get_ipa_tdesc): Handle PPC_TDESC_ISA207_HTM_VSX. (initialize_low_tracepoint): Call init_registers_powerpc_isa207_htm_vsx32l and init_registers_powerpc_isa207_htm_vsx64l. gdb/testsuite/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.arch/powerpc-htm-regs.c: New file. * gdb.arch/powerpc-htm-regs.exp: New file. gdb/doc/ChangeLog: 2018-10-26 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * gdb.texinfo (PowerPC Features): Describe new features "org.gnu.gdb.power.htm.spr", "org.gnu.gdb.power.htm.core", "org.gnu.gdb.power.htm.fpu", "org.gnu.gdb.power.htm.altivec", "org.gnu.gdb.power.htm.vsx", "org.gnu.gdb.power.htm.ppr", "org.gnu.gdb.power.htm.dscr", "org.gnu.gdb.power.htm.tar".
2018-10-26 20:37:55 +08:00
if (tdep->have_htm_spr)
store_regset (regcache, tid, -1, NT_PPC_TM_SPR,
PPC_LINUX_SIZEOF_TM_SPRREGSET,
&ppc32_linux_tm_sprregset);
/* Because the EBB and checkpointed HTM registers can be
unavailable, attempts to store them here would cause this
function to fail most of the time, so we ignore them. */
}
void
ppc_linux_nat_target::store_registers (struct regcache *regcache, int regno)
{
pid_t tid = get_ptrace_pid (regcache->ptid ());
if (regno >= 0)
store_register (regcache, tid, regno);
else
store_ppc_registers (regcache, tid);
}
/* Functions for transferring registers between a gregset_t or fpregset_t
(see sys/ucontext.h) and gdb's regcache. The word size is that used
by the ptrace interface, not the current program's ABI. Eg. if a
powerpc64-linux gdb is being used to debug a powerpc32-linux app, we
read or write 64-bit gregsets. This is to suit the host libthread_db. */
void
supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp)
{
const struct regset *regset = ppc_linux_gregset (sizeof (long));
ppc_supply_gregset (regset, regcache, -1, gregsetp, sizeof (*gregsetp));
}
void
fill_gregset (const struct regcache *regcache,
gdb_gregset_t *gregsetp, int regno)
{
const struct regset *regset = ppc_linux_gregset (sizeof (long));
if (regno == -1)
memset (gregsetp, 0, sizeof (*gregsetp));
ppc_collect_gregset (regset, regcache, regno, gregsetp, sizeof (*gregsetp));
}
void
supply_fpregset (struct regcache *regcache, const gdb_fpregset_t * fpregsetp)
{
const struct regset *regset = ppc_linux_fpregset ();
ppc_supply_fpregset (regset, regcache, -1,
fpregsetp, sizeof (*fpregsetp));
}
void
fill_fpregset (const struct regcache *regcache,
gdb_fpregset_t *fpregsetp, int regno)
{
const struct regset *regset = ppc_linux_fpregset ();
ppc_collect_fpregset (regset, regcache, regno,
fpregsetp, sizeof (*fpregsetp));
}
int
ppc_linux_nat_target::auxv_parse (gdb_byte **readptr,
gdb_byte *endptr, CORE_ADDR *typep,
CORE_ADDR *valp)
{
int tid = inferior_ptid.lwp ();
if (tid == 0)
tid = inferior_ptid.pid ();
int sizeof_auxv_field = ppc_linux_target_wordsize (tid);
enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
gdb_byte *ptr = *readptr;
if (endptr == ptr)
return 0;
if (endptr - ptr < sizeof_auxv_field * 2)
return -1;
*typep = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order);
ptr += sizeof_auxv_field;
*valp = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order);
ptr += sizeof_auxv_field;
*readptr = ptr;
return 1;
}
const struct target_desc *
ppc_linux_nat_target::read_description ()
{
int tid = inferior_ptid.lwp ();
if (tid == 0)
tid = inferior_ptid.pid ();
if (have_ptrace_getsetevrregs)
{
struct gdb_evrregset_t evrregset;
if (ptrace (PTRACE_GETEVRREGS, tid, 0, &evrregset) >= 0)
return tdesc_powerpc_e500l;
/* EIO means that the PTRACE_GETEVRREGS request isn't supported.
Anything else needs to be reported. */
else if (errno != EIO)
perror_with_name (_("Unable to fetch SPE registers"));
}
struct ppc_linux_features features = ppc_linux_no_features;
features.wordsize = ppc_linux_target_wordsize (tid);
CORE_ADDR hwcap = linux_get_hwcap (current_top_target ());
CORE_ADDR hwcap2 = linux_get_hwcap2 (current_top_target ());
if (have_ptrace_getsetvsxregs
&& (hwcap & PPC_FEATURE_HAS_VSX))
{
gdb_vsxregset_t vsxregset;
if (ptrace (PTRACE_GETVSXREGS, tid, 0, &vsxregset) >= 0)
features.vsx = true;
/* EIO means that the PTRACE_GETVSXREGS request isn't supported.
Anything else needs to be reported. */
else if (errno != EIO)
perror_with_name (_("Unable to fetch VSX registers"));
}
if (have_ptrace_getvrregs
&& (hwcap & PPC_FEATURE_HAS_ALTIVEC))
{
gdb_vrregset_t vrregset;
if (ptrace (PTRACE_GETVRREGS, tid, 0, &vrregset) >= 0)
features.altivec = true;
/* EIO means that the PTRACE_GETVRREGS request isn't supported.
Anything else needs to be reported. */
else if (errno != EIO)
perror_with_name (_("Unable to fetch AltiVec registers"));
}
features.isa205 = ppc_linux_has_isa205 (hwcap);
if ((hwcap2 & PPC_FEATURE2_DSCR)
&& check_regset (tid, NT_PPC_PPR, PPC_LINUX_SIZEOF_PPRREGSET)
&& check_regset (tid, NT_PPC_DSCR, PPC_LINUX_SIZEOF_DSCRREGSET))
{
features.ppr_dscr = true;
if ((hwcap2 & PPC_FEATURE2_ARCH_2_07)
&& (hwcap2 & PPC_FEATURE2_TAR)
&& (hwcap2 & PPC_FEATURE2_EBB)
&& check_regset (tid, NT_PPC_TAR, PPC_LINUX_SIZEOF_TARREGSET)
&& check_regset (tid, NT_PPC_EBB, PPC_LINUX_SIZEOF_EBBREGSET)
&& check_regset (tid, NT_PPC_PMU, PPC_LINUX_SIZEOF_PMUREGSET))
{
features.isa207 = true;
if ((hwcap2 & PPC_FEATURE2_HTM)
&& check_regset (tid, NT_PPC_TM_SPR,
PPC_LINUX_SIZEOF_TM_SPRREGSET))
features.htm = true;
}
}
return ppc_linux_match_description (features);
}
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
/* Routines for installing hardware watchpoints and breakpoints. When
GDB requests a hardware watchpoint or breakpoint to be installed, we
register the request for the pid of inferior_ptid in a map with one
entry per process. We then issue a stop request to all the threads of
this process, and mark a per-thread flag indicating that their debug
registers should be updated. Right before they are next resumed, we
remove all previously installed debug registers and install all the
ones GDB requested. We then update a map with one entry per thread
that keeps track of what debug registers were last installed in each
thread.
We use this second map to remove installed registers before installing
the ones requested by GDB, and to copy the debug register state after
a thread clones or forks, since depending on the kernel configuration,
debug registers can be inherited. */
/* Check if we support and have enough resources to install a hardware
watchpoint or breakpoint. See the description in target.h. */
Convert struct target_ops to C++ I.e., use C++ virtual methods and inheritance instead of tables of function pointers. Unfortunately, there's no way to do a smooth transition. ALL native targets in the tree must be converted at the same time. I've tested all I could with cross compilers and with help from GCC compile farm, but naturally I haven't been able to test many of the ports. Still, I made a best effort to port everything over, and while I expect some build problems due to typos and such, which should be trivial to fix, I don't expect any design problems. * Implementation notes: - The flattened current_target is gone. References to current_target or current_target.beneath are replaced with references to target_stack (the top of the stack) directly. - To keep "set debug target" working, this adds a new debug_stratum layer that sits on top of the stack, prints the debug, and delegates to the target beneath. In addition, this makes the shortname and longname properties of target_ops be virtual methods instead of data fields, and makes the debug target defer those to the target beneath. This is so that debug code sprinkled around that does "if (debugtarget) ..." can transparently print the name of the target beneath. A patch later in the series actually splits out the shortname/longname methods to a separate structure, but I preferred to keep that chance separate as it is associated with changing a bit the design of how targets are registered and open. - Since you can't check whether a C++ virtual method is overridden, the old method of checking whether a target_ops implements a method by comparing the function pointer must be replaced with something else. Some cases are fixed by adding a parallel "can_do_foo" target_ops methods. E.g.,: + for (t = target_stack; t != NULL; t = t->beneath) { - if (t->to_create_inferior != NULL) + if (t->can_create_inferior ()) break; } Others are fixed by changing void return type to bool or int return type, and have the default implementation return false or -1, to indicate lack of support. - make-target-delegates was adjusted to generate C++ classes and methods. It needed tweaks to grok "virtual" in front of the target method name, and for the fact that methods are no longer function pointers. (In particular, the current code parsing the return type was simple because it could simply parse up until the '(' in '(*to_foo)'. It now generates a couple C++ classes that inherit target_ops: dummy_target and debug_target. Since we need to generate the class declarations as well, i.e., we need to emit methods twice, we now generate the code in two passes. - The core_target global is renamed to avoid conflict with the "core_target" class. - ctf/tfile targets init_tracefile_ops is replaced by a base class that is inherited by both ctf and tfile. - bsd-uthread The bsd_uthread_ops_hack hack is gone. It's not needed because nothing was extending a target created by bsd_uthread_target. - remote/extended-remote targets This is a first pass, just enough to C++ify target_ops. A later pass will convert more free functions to methods, and make remote_state be truly per remote instance, allowing multiple simultaneous instances of remote targets. - inf-child/"native" is converted to an actual base class (inf_child_target), that is inherited by all native targets. - GNU/Linux The old weird double-target linux_ops mechanism in linux-nat.c, is gone, replaced by adding a few virtual methods to linux-nat.h's target_ops, called low_XXX, that the concrete linux-nat implementations override. Sort of like gdbserver's linux_target_ops, but simpler, for requiring only one target_ops-like hierarchy, which spares implementing the same method twice when we need to forward the method to a low implementation. The low target simply reimplements the target_ops method directly in that case. There are a few remaining linux-nat.c hooks that would be better converted to low_ methods like above too. E.g.: linux_nat_set_new_thread (t, x86_linux_new_thread); linux_nat_set_new_fork (t, x86_linux_new_fork); linux_nat_set_forget_process That'll be done in a follow up patch. - We can no longer use functions like x86_use_watchpoints to install custom methods on an arbitrary base target. The patch replaces instances of such a pattern with template mixins. For example memory_breakpoint_target defined in target.h, or x86_nat_target in x86-nat.h. - linux_trad_target, MIPS and Alpha GNU/Linux The code in the new linux-nat-trad.h/c files which was split off of inf-ptrace.h/c recently, is converted to a C++ base class, and used by the MIPS and Alpha GNU/Linux ports. - BSD targets The $architecture x NetBSD/OpenBSD/FreeBSD support matrix complicates things a bit. There's common BSD target code, and there's common architecture-specific code shared between the different BSDs. Currently, all that is stiched together to form a final target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target functions etc. This introduces new fbsd_nat_target, obsd_nat_target and nbsd_nat_target classes that serve as base/prototype target for the corresponding BSD variant. And introduces generic i386/AMD64 BSD targets, to be used as template mixin to build a final target. Similarly, a generic SPARC target is added, used by both BSD and Linux ports. - bsd_kvm_add_target, BSD libkvm target I considered making bsd_kvm_supply_pcb a virtual method, and then have each port inherit bsd_kvm_target and override that method, but that was resulting in lots of unjustified churn, so I left the function pointer mechanism alone. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> John Baldwin <jhb@freebsd.org> * target.h (enum strata) <debug_stratum>: New. (struct target_ops) <all delegation methods>: Replace by C++ virtual methods, and drop "to_" prefix. All references updated throughout. <to_shortname, to_longname, to_doc, to_data, to_have_steppable_watchpoint, to_have_continuable_watchpoint, to_has_thread_control, to_attach_no_wait>: Delete, replaced by virtual methods. All references updated throughout. <can_attach, supports_terminal_ours, can_create_inferior, get_thread_control_capabilities, attach_no_wait>: New virtual methods. <insert_breakpoint, remove_breakpoint>: Now TARGET_DEFAULT_NORETURN methods. <info_proc>: Now returns bool. <to_magic>: Delete. (OPS_MAGIC): Delete. (current_target): Delete. All references replaced by references to ... (target_stack): ... this. New. (target_shortname, target_longname): Adjust. (target_can_run): Now a function declaration. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (memory_breakpoint_target): New template class. (test_target_ops): Refactor as a C++ class with virtual methods. * make-target-delegates (NAME_PART): Tighten. (POINTER_PART, CP_SYMBOL): New. (SIMPLE_RETURN_PART): Reimplement. (VEC_RETURN_PART): Expect less. (RETURN_PART, VIRTUAL_PART): New. (METHOD): Adjust to C++ virtual methods. (scan_target_h): Remove reference to C99. (dname): Output "target_ops::" prefix. (write_function_header): Adjust to output a C++ class method. (write_declaration): New. (write_delegator): Adjust to output a C++ class method. (tdname): Output "dummy_target::" prefix. (write_tdefault, write_debugmethod): Adjust to output a C++ class method. (tdefault_names, debug_names): Delete. (return_types, tdefaults, styles, argtypes_array): New. (top level): All methods are delegators. (print_class): New. (top level): Print dummy_target and debug_target classes. * target-delegates.c: Regenerate. * target-debug.h (target_debug_print_enum_info_proc_what) (target_debug_print_thread_control_capabilities) (target_debug_print_thread_info_p): New. * target.c (dummy_target): Delete. (the_dummy_target, the_debug_target): New. (target_stack): Now extern. (set_targetdebug): Push/unpush debug target. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (add_target_with_completer): No longer call complete_target_initialization. (target_supports_terminal_ours): Use regular delegation. (update_current_target): Delete. (push_target): No longer check magic number. Don't call update_current_target. (unpush_target): Don't call update_current_target. (target_is_pushed): No longer check magic number. (target_require_runnable): Skip for all stratums over process_stratum. (target_ops::info_proc): New. (target_info_proc): Use find_target_at and find_default_run_target. (target_supports_disable_randomization): Use regular delegation. (target_get_osdata): Use find_target_at. (target_ops::open, target_ops::close, target_ops::can_attach) (target_ops::attach, target_ops::can_create_inferior) (target_ops::create_inferior, target_ops::can_run) (target_can_run): New. (default_fileio_target): Use regular delegation. (target_ops::fileio_open, target_ops::fileio_pwrite) (target_ops::fileio_pread, target_ops::fileio_fstat) (target_ops::fileio_close, target_ops::fileio_unlink) (target_ops::fileio_readlink): New. (target_fileio_open_1, target_fileio_unlink) (target_fileio_readlink): Always call the target method. Handle FILEIO_ENOSYS. (return_zero, return_zero_has_execution): Delete. (init_dummy_target): Delete. (dummy_target::dummy_target, dummy_target::shortname) (dummy_target::longname, dummy_target::doc) (debug_target::debug_target, debug_target::shortname) (debug_target::longname, debug_target::doc): New. (target_supports_delete_record): Use regular delegation. (setup_target_debug): Delete. (maintenance_print_target_stack): Skip debug_stratum. (initialize_targets): Instantiate the_dummy_target and the_debug_target. * auxv.c (target_auxv_parse): Remove 'ops' parameter. Adjust to use target_stack. (target_auxv_search, fprint_target_auxv): Adjust. (info_auxv_command): Adjust to use target_stack. * auxv.h (target_auxv_parse): Remove 'ops' parameter. * exceptions.c (print_flush): Handle a NULL target_stack. * regcache.c (target_ops_no_register): Refactor as class with virtual methods. * exec.c (exec_target): New class. (exec_ops): Now an exec_target. (exec_open, exec_close_1, exec_get_section_table) (exec_xfer_partial, exec_files_info, exec_has_memory) (exec_make_note_section): Refactor as exec_target methods. (exec_file_clear, ignore, exec_remove_breakpoint, init_exec_ops): Delete. (exec_target::find_memory_regions): New. (_initialize_exec): Don't call init_exec_ops. * gdbcore.h (exec_file_clear): Delete. * corefile.c (core_target): Delete. (core_file_command): Adjust. * corelow.c (core_target): New class. (the_core_target): New. (core_close): Remove target_ops parameter. (core_close_cleanup): Adjust. (core_target::close): New. (core_open, core_detach, get_core_registers, core_files_info) (core_xfer_partial, core_thread_alive, core_read_description) (core_pid_to_str, core_thread_name, core_has_memory) (core_has_stack, core_has_registers, core_info_proc): Rework as core_target methods. (ignore, core_remove_breakpoint, init_core_ops): Delete. (_initialize_corelow): Initialize the_core_target. * gdbcore.h (core_target): Delete. (the_core_target): New. * ctf.c: (ctf_target): New class. (ctf_ops): Now a ctf_target. (ctf_open, ctf_close, ctf_files_info, ctf_fetch_registers) (ctf_xfer_partial, ctf_get_trace_state_variable_value) (ctf_trace_find, ctf_traceframe_info): Refactor as ctf_target methods. (init_ctf_ops): Delete. (_initialize_ctf): Don't call it. * tracefile-tfile.c (tfile_target): New class. (tfile_ops): Now a tfile_target. (tfile_open, tfile_close, tfile_files_info) (tfile_get_tracepoint_status, tfile_trace_find) (tfile_fetch_registers, tfile_xfer_partial) (tfile_get_trace_state_variable_value, tfile_traceframe_info): Refactor as tfile_target methods. (tfile_xfer_partial_features): Remove target_ops parameter. (init_tfile_ops): Delete. (_initialize_tracefile_tfile): Don't call it. * tracefile.c (tracefile_has_all_memory, tracefile_has_memory) (tracefile_has_stack, tracefile_has_registers) (tracefile_thread_alive, tracefile_get_trace_status): Refactor as tracefile_target methods. (init_tracefile_ops): Delete. (tracefile_target::tracefile_target): New. * tracefile.h: Include "target.h". (tracefile_target): New class. (init_tracefile_ops): Delete. * spu-multiarch.c (spu_multiarch_target): New class. (spu_ops): Now a spu_multiarch_target. (spu_thread_architecture, spu_region_ok_for_hw_watchpoint) (spu_fetch_registers, spu_store_registers, spu_xfer_partial) (spu_search_memory, spu_mourn_inferior): Refactor as spu_multiarch_target methods. (init_spu_ops): Delete. (_initialize_spu_multiarch): Remove references to init_spu_ops, complete_target_initialization. * ravenscar-thread.c (ravenscar_thread_target): New class. (ravenscar_ops): Now a ravenscar_thread_target. (ravenscar_resume, ravenscar_wait, ravenscar_update_thread_list) (ravenscar_thread_alive, ravenscar_pid_to_str) (ravenscar_fetch_registers, ravenscar_store_registers) (ravenscar_prepare_to_store, ravenscar_stopped_by_sw_breakpoint) (ravenscar_stopped_by_hw_breakpoint) (ravenscar_stopped_by_watchpoint, ravenscar_stopped_data_address) (ravenscar_mourn_inferior, ravenscar_core_of_thread) (ravenscar_get_ada_task_ptid): Refactor as ravenscar_thread_target methods. (init_ravenscar_thread_ops): Delete. (_initialize_ravenscar): Remove references to init_ravenscar_thread_ops and complete_target_initialization. * bsd-uthread.c (bsd_uthread_ops_hack): Delete. (bsd_uthread_target): New class. (bsd_uthread_ops): Now a bsd_uthread_target. (bsd_uthread_activate): Adjust to refer to bsd_uthread_ops. (bsd_uthread_close, bsd_uthread_mourn_inferior) (bsd_uthread_fetch_registers, bsd_uthread_store_registers) (bsd_uthread_wait, bsd_uthread_resume, bsd_uthread_thread_alive) (bsd_uthread_update_thread_list, bsd_uthread_extra_thread_info) (bsd_uthread_pid_to_str): Refactor as bsd_uthread_target methods. (bsd_uthread_target): Delete function. (_initialize_bsd_uthread): Remove reference to complete_target_initialization. * bfd-target.c (target_bfd_data): Delete. Fields folded into ... (target_bfd): ... this new class. (target_bfd_xfer_partial, target_bfd_get_section_table) (target_bfd_close): Refactor as target_bfd methods. (target_bfd::~target_bfd): New. (target_bfd_reopen): Adjust. (target_bfd::close): New. * record-btrace.c (record_btrace_target): New class. (record_btrace_ops): Now a record_btrace_target. (record_btrace_open, record_btrace_stop_recording) (record_btrace_disconnect, record_btrace_close) (record_btrace_async, record_btrace_info) (record_btrace_insn_history, record_btrace_insn_history_range) (record_btrace_insn_history_from, record_btrace_call_history) (record_btrace_call_history_range) (record_btrace_call_history_from, record_btrace_record_method) (record_btrace_is_replaying, record_btrace_will_replay) (record_btrace_xfer_partial, record_btrace_insert_breakpoint) (record_btrace_remove_breakpoint, record_btrace_fetch_registers) (record_btrace_store_registers, record_btrace_prepare_to_store) (record_btrace_to_get_unwinder) (record_btrace_to_get_tailcall_unwinder, record_btrace_resume) (record_btrace_commit_resume, record_btrace_wait) (record_btrace_stop, record_btrace_can_execute_reverse) (record_btrace_stopped_by_sw_breakpoint) (record_btrace_supports_stopped_by_sw_breakpoint) (record_btrace_stopped_by_hw_breakpoint) (record_btrace_supports_stopped_by_hw_breakpoint) (record_btrace_update_thread_list, record_btrace_thread_alive) (record_btrace_goto_begin, record_btrace_goto_end) (record_btrace_goto, record_btrace_stop_replaying_all) (record_btrace_execution_direction) (record_btrace_prepare_to_generate_core) (record_btrace_done_generating_core): Refactor as record_btrace_target methods. (init_record_btrace_ops): Delete. (_initialize_record_btrace): Remove reference to init_record_btrace_ops. * record-full.c (RECORD_FULL_IS_REPLAY): Adjust to always refer to the execution_direction global. (record_full_base_target, record_full_target) (record_full_core_target): New classes. (record_full_ops): Now a record_full_target. (record_full_core_ops): Now a record_full_core_target. (record_full_target::detach, record_full_target::disconnect) (record_full_core_target::disconnect) (record_full_target::mourn_inferior, record_full_target::kill): New. (record_full_open, record_full_close, record_full_async): Refactor as methods of the record_full_base_target class. (record_full_resume, record_full_commit_resume): Refactor as methods of the record_full_target class. (record_full_wait, record_full_stopped_by_watchpoint) (record_full_stopped_data_address) (record_full_stopped_by_sw_breakpoint) (record_full_supports_stopped_by_sw_breakpoint) (record_full_stopped_by_hw_breakpoint) (record_full_supports_stopped_by_hw_breakpoint): Refactor as methods of the record_full_base_target class. (record_full_store_registers, record_full_xfer_partial) (record_full_insert_breakpoint, record_full_remove_breakpoint): Refactor as methods of the record_full_target class. (record_full_can_execute_reverse, record_full_get_bookmark) (record_full_goto_bookmark, record_full_execution_direction) (record_full_record_method, record_full_info, record_full_delete) (record_full_is_replaying, record_full_will_replay) (record_full_goto_begin, record_full_goto_end, record_full_goto) (record_full_stop_replaying): Refactor as methods of the record_full_base_target class. (record_full_core_resume, record_full_core_kill) (record_full_core_fetch_registers) (record_full_core_prepare_to_store) (record_full_core_store_registers, record_full_core_xfer_partial) (record_full_core_insert_breakpoint) (record_full_core_remove_breakpoint) (record_full_core_has_execution): Refactor as methods of the record_full_core_target class. (record_full_base_target::supports_delete_record): New. (init_record_full_ops): Delete. (init_record_full_core_ops): Delete. (record_full_save): Refactor as method of the record_full_base_target class. (_initialize_record_full): Remove references to init_record_full_ops and init_record_full_core_ops. * remote.c (remote_target, extended_remote_target): New classes. (remote_ops): Now a remote_target. (extended_remote_ops): Now an extended_remote_target. (remote_insert_fork_catchpoint, remote_remove_fork_catchpoint) (remote_insert_vfork_catchpoint, remote_remove_vfork_catchpoint) (remote_insert_exec_catchpoint, remote_remove_exec_catchpoint) (remote_pass_signals, remote_set_syscall_catchpoint) (remote_program_signals, ) (remote_thread_always_alive): Remove target_ops parameter. (remote_thread_alive, remote_thread_name) (remote_update_thread_list, remote_threads_extra_info) (remote_static_tracepoint_marker_at) (remote_static_tracepoint_markers_by_strid) (remote_get_ada_task_ptid, remote_close, remote_start_remote) (remote_open): Refactor as methods of remote_target. (extended_remote_open, extended_remote_detach) (extended_remote_attach, extended_remote_post_attach): (extended_remote_supports_disable_randomization) (extended_remote_create_inferior): : Refactor as method of extended_remote_target. (remote_set_permissions, remote_open_1, remote_detach) (remote_follow_fork, remote_follow_exec, remote_disconnect) (remote_resume, remote_commit_resume, remote_stop) (remote_interrupt, remote_pass_ctrlc, remote_terminal_inferior) (remote_terminal_ours, remote_wait, remote_fetch_registers) (remote_prepare_to_store, remote_store_registers) (remote_flash_erase, remote_flash_done, remote_files_info) (remote_kill, remote_mourn, remote_insert_breakpoint) (remote_remove_breakpoint, remote_insert_watchpoint) (remote_watchpoint_addr_within_range) (remote_remove_watchpoint, remote_region_ok_for_hw_watchpoint) (remote_check_watch_resources, remote_stopped_by_sw_breakpoint) (remote_supports_stopped_by_sw_breakpoint) (remote_stopped_by_hw_breakpoint) (remote_supports_stopped_by_hw_breakpoint) (remote_stopped_by_watchpoint, remote_stopped_data_address) (remote_insert_hw_breakpoint, remote_remove_hw_breakpoint) (remote_verify_memory): Refactor as methods of remote_target. (remote_write_qxfer, remote_read_qxfer): Remove target_ops parameter. (remote_xfer_partial, remote_get_memory_xfer_limit) (remote_search_memory, remote_rcmd, remote_memory_map) (remote_pid_to_str, remote_get_thread_local_address) (remote_get_tib_address, remote_read_description): Refactor as methods of remote_target. (remote_target::fileio_open, remote_target::fileio_pwrite) (remote_target::fileio_pread, remote_target::fileio_close): New. (remote_hostio_readlink, remote_hostio_fstat) (remote_filesystem_is_local, remote_can_execute_reverse) (remote_supports_non_stop, remote_supports_disable_randomization) (remote_supports_multi_process, remote_supports_cond_breakpoints) (remote_supports_enable_disable_tracepoint) (remote_supports_string_tracing) (remote_can_run_breakpoint_commands, remote_trace_init) (remote_download_tracepoint, remote_can_download_tracepoint) (remote_download_trace_state_variable, remote_enable_tracepoint) (remote_disable_tracepoint, remote_trace_set_readonly_regions) (remote_trace_start, remote_get_trace_status) (remote_get_tracepoint_status, remote_trace_stop) (remote_trace_find, remote_get_trace_state_variable_value) (remote_save_trace_data, remote_get_raw_trace_data) (remote_set_disconnected_tracing, remote_core_of_thread) (remote_set_circular_trace_buffer, remote_traceframe_info) (remote_get_min_fast_tracepoint_insn_len) (remote_set_trace_buffer_size, remote_set_trace_notes) (remote_use_agent, remote_can_use_agent, remote_enable_btrace) (remote_disable_btrace, remote_teardown_btrace) (remote_read_btrace, remote_btrace_conf) (remote_augmented_libraries_svr4_read, remote_load) (remote_pid_to_exec_file, remote_can_do_single_step) (remote_execution_direction, remote_thread_handle_to_thread_info): Refactor as methods of remote_target. (init_remote_ops, init_extended_remote_ops): Delete. (remote_can_async_p, remote_is_async_p, remote_async) (remote_thread_events, remote_upload_tracepoints) (remote_upload_trace_state_variables): Refactor as methods of remote_target. (_initialize_remote): Remove references to init_remote_ops and init_extended_remote_ops. * remote-sim.c (gdbsim_target): New class. (gdbsim_fetch_register, gdbsim_store_register, gdbsim_kill) (gdbsim_load, gdbsim_create_inferior, gdbsim_open, gdbsim_close) (gdbsim_detach, gdbsim_resume, gdbsim_interrupt) (gdbsim_wait, gdbsim_prepare_to_store, gdbsim_xfer_partial) (gdbsim_files_info, gdbsim_mourn_inferior, gdbsim_thread_alive) (gdbsim_pid_to_str, gdbsim_has_all_memory, gdbsim_has_memory): Refactor as methods of gdbsim_target. (gdbsim_ops): Now a gdbsim_target. (init_gdbsim_ops): Delete. (gdbsim_cntrl_c): Adjust. (_initialize_remote_sim): Remove reference to init_gdbsim_ops. * amd64-linux-nat.c (amd64_linux_nat_target): New class. (the_amd64_linux_nat_target): New. (amd64_linux_fetch_inferior_registers) (amd64_linux_store_inferior_registers): Refactor as methods of amd64_linux_nat_target. (_initialize_amd64_linux_nat): Adjust. Set linux_target. * i386-linux-nat.c: Don't include "linux-nat.h". (i386_linux_nat_target): New class. (the_i386_linux_nat_target): New. (i386_linux_fetch_inferior_registers) (i386_linux_store_inferior_registers, i386_linux_resume): Refactor as methods of i386_linux_nat_target. (_initialize_i386_linux_nat): Adjust. Set linux_target. * inf-child.c (inf_child_ops): Delete. (inf_child_fetch_inferior_registers) (inf_child_store_inferior_registers): Delete. (inf_child_post_attach, inf_child_prepare_to_store): Refactor as methods of inf_child_target. (inf_child_target::supports_terminal_ours) (inf_child_target::terminal_init) (inf_child_target::terminal_inferior) (inf_child_target::terminal_ours_for_output) (inf_child_target::terminal_ours, inf_child_target::interrupt) (inf_child_target::pass_ctrlc, inf_child_target::terminal_info): New. (inf_child_open, inf_child_disconnect, inf_child_close) (inf_child_mourn_inferior, inf_child_maybe_unpush_target) (inf_child_post_startup_inferior, inf_child_can_run) (inf_child_pid_to_exec_file): Refactor as methods of inf_child_target. (inf_child_follow_fork): Delete. (inf_child_target::can_create_inferior) (inf_child_target::can_attach): New. (inf_child_target::has_all_memory, inf_child_target::has_memory) (inf_child_target::has_stack, inf_child_target::has_registers) (inf_child_target::has_execution): New. (inf_child_fileio_open, inf_child_fileio_pwrite) (inf_child_fileio_pread, inf_child_fileio_fstat) (inf_child_fileio_close, inf_child_fileio_unlink) (inf_child_fileio_readlink, inf_child_use_agent) (inf_child_can_use_agent): Refactor as methods of inf_child_target. (return_zero, inf_child_target): Delete. (inf_child_target::inf_child_target): New. * inf-child.h: Include "target.h". (inf_child_target): Delete function prototype. (inf_child_target): New class. (inf_child_open_target, inf_child_mourn_inferior) (inf_child_maybe_unpush_target): Delete. * inf-ptrace.c (inf_ptrace_target::~inf_ptrace_target): New. (inf_ptrace_follow_fork, inf_ptrace_insert_fork_catchpoint) (inf_ptrace_remove_fork_catchpoint, inf_ptrace_create_inferior) (inf_ptrace_post_startup_inferior, inf_ptrace_mourn_inferior) (inf_ptrace_attach, inf_ptrace_post_attach, inf_ptrace_detach) (inf_ptrace_detach_success, inf_ptrace_kill, inf_ptrace_resume) (inf_ptrace_wait, inf_ptrace_xfer_partial) (inf_ptrace_thread_alive, inf_ptrace_files_info) (inf_ptrace_pid_to_str, inf_ptrace_auxv_parse): Refactor as methods of inf_ptrace_target. (inf_ptrace_target): Delete function. * inf-ptrace.h: Include "inf-child.h". (inf_ptrace_target): Delete function declaration. (inf_ptrace_target): New class. (inf_ptrace_trad_target, inf_ptrace_detach_success): Delete. * linux-nat.c (linux_target): New. (linux_ops, linux_ops_saved, super_xfer_partial): Delete. (linux_nat_target::~linux_nat_target): New. (linux_child_post_attach, linux_child_post_startup_inferior) (linux_child_follow_fork, linux_child_insert_fork_catchpoint) (linux_child_remove_fork_catchpoint) (linux_child_insert_vfork_catchpoint) (linux_child_remove_vfork_catchpoint) (linux_child_insert_exec_catchpoint) (linux_child_remove_exec_catchpoint) (linux_child_set_syscall_catchpoint, linux_nat_pass_signals) (linux_nat_create_inferior, linux_nat_attach, linux_nat_detach) (linux_nat_resume, linux_nat_stopped_by_watchpoint) (linux_nat_stopped_data_address) (linux_nat_stopped_by_sw_breakpoint) (linux_nat_supports_stopped_by_sw_breakpoint) (linux_nat_stopped_by_hw_breakpoint) (linux_nat_supports_stopped_by_hw_breakpoint, linux_nat_wait) (linux_nat_kill, linux_nat_mourn_inferior) (linux_nat_xfer_partial, linux_nat_thread_alive) (linux_nat_update_thread_list, linux_nat_pid_to_str) (linux_nat_thread_name, linux_child_pid_to_exec_file) (linux_child_static_tracepoint_markers_by_strid) (linux_nat_is_async_p, linux_nat_can_async_p) (linux_nat_supports_non_stop, linux_nat_always_non_stop_p) (linux_nat_supports_multi_process) (linux_nat_supports_disable_randomization, linux_nat_async) (linux_nat_stop, linux_nat_close, linux_nat_thread_address_space) (linux_nat_core_of_thread, linux_nat_filesystem_is_local) (linux_nat_fileio_open, linux_nat_fileio_readlink) (linux_nat_fileio_unlink, linux_nat_thread_events): Refactor as methods of linux_nat_target. (linux_nat_wait_1, linux_xfer_siginfo, linux_proc_xfer_partial) (linux_proc_xfer_spu, linux_nat_xfer_osdata): Remove target_ops parameter. (check_stopped_by_watchpoint): Adjust. (linux_xfer_partial): Delete. (linux_target_install_ops, linux_target, linux_nat_add_target): Delete. (linux_nat_target::linux_nat_target): New. * linux-nat.h: Include "inf-ptrace.h". (linux_nat_target): New. (linux_target, linux_target_install_ops, linux_nat_add_target): Delete function declarations. (linux_target): Declare global. * linux-thread-db.c (thread_db_target): New. (thread_db_target::thread_db_target): New. (thread_db_ops): Delete. (the_thread_db_target): New. (thread_db_detach, thread_db_wait, thread_db_mourn_inferior) (thread_db_update_thread_list, thread_db_pid_to_str) (thread_db_extra_thread_info) (thread_db_thread_handle_to_thread_info) (thread_db_get_thread_local_address, thread_db_get_ada_task_ptid) (thread_db_resume): Refactor as methods of thread_db_target. (init_thread_db_ops): Delete. (_initialize_thread_db): Remove reference to init_thread_db_ops. * x86-linux-nat.c: Don't include "linux-nat.h". (super_post_startup_inferior): Delete. (x86_linux_nat_target::~x86_linux_nat_target): New. (x86_linux_child_post_startup_inferior) (x86_linux_read_description, x86_linux_enable_btrace) (x86_linux_disable_btrace, x86_linux_teardown_btrace) (x86_linux_read_btrace, x86_linux_btrace_conf): Refactor as methods of x86_linux_nat_target. (x86_linux_create_target): Delete. Bits folded ... (x86_linux_add_target): ... here. Now takes a linux_nat_target pointer. * x86-linux-nat.h: Include "linux-nat.h" and "x86-nat.h". (x86_linux_nat_target): New class. (x86_linux_create_target): Delete. (x86_linux_add_target): Now takes a linux_nat_target pointer. * x86-nat.c (x86_insert_watchpoint, x86_remove_watchpoint) (x86_region_ok_for_watchpoint, x86_stopped_data_address) (x86_stopped_by_watchpoint, x86_insert_hw_breakpoint) (x86_remove_hw_breakpoint, x86_can_use_hw_breakpoint) (x86_stopped_by_hw_breakpoint): Remove target_ops parameter and make extern. (x86_use_watchpoints): Delete. * x86-nat.h: Include "breakpoint.h" and "target.h". (x86_use_watchpoints): Delete. (x86_can_use_hw_breakpoint, x86_region_ok_for_hw_watchpoint) (x86_stopped_by_watchpoint, x86_stopped_data_address) (x86_insert_watchpoint, x86_remove_watchpoint) (x86_insert_hw_breakpoint, x86_remove_hw_breakpoint) (x86_stopped_by_hw_breakpoint): New declarations. (x86_nat_target): New template class. * ppc-linux-nat.c (ppc_linux_nat_target): New class. (the_ppc_linux_nat_target): New. (ppc_linux_fetch_inferior_registers) (ppc_linux_can_use_hw_breakpoint) (ppc_linux_region_ok_for_hw_watchpoint) (ppc_linux_ranged_break_num_registers) (ppc_linux_insert_hw_breakpoint, ppc_linux_remove_hw_breakpoint) (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_can_accel_watchpoint_condition) (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint) (ppc_linux_stopped_data_address, ppc_linux_stopped_by_watchpoint) (ppc_linux_watchpoint_addr_within_range) (ppc_linux_masked_watch_num_registers) (ppc_linux_store_inferior_registers, ppc_linux_auxv_parse) (ppc_linux_read_description): Refactor as methods of ppc_linux_nat_target. (_initialize_ppc_linux_nat): Adjust. Set linux_target. * procfs.c (procfs_xfer_partial): Delete forward declaration. (procfs_target): New class. (the_procfs_target): New. (procfs_target): Delete function. (procfs_auxv_parse, procfs_attach, procfs_detach) (procfs_fetch_registers, procfs_store_registers, procfs_wait) (procfs_xfer_partial, procfs_resume, procfs_pass_signals) (procfs_files_info, procfs_kill_inferior, procfs_mourn_inferior) (procfs_create_inferior, procfs_update_thread_list) (procfs_thread_alive, procfs_pid_to_str) (procfs_can_use_hw_breakpoint, procfs_stopped_by_watchpoint) (procfs_stopped_data_address, procfs_insert_watchpoint) (procfs_remove_watchpoint, procfs_region_ok_for_hw_watchpoint) (proc_find_memory_regions, procfs_info_proc) (procfs_make_note_section): Refactor as methods of procfs_target. (_initialize_procfs): Adjust. * sol-thread.c (sol_thread_target): New class. (sol_thread_ops): Now a sol_thread_target. (sol_thread_detach, sol_thread_resume, sol_thread_wait) (sol_thread_fetch_registers, sol_thread_store_registers) (sol_thread_xfer_partial, sol_thread_mourn_inferior) (sol_thread_alive, solaris_pid_to_str, sol_update_thread_list) (sol_get_ada_task_ptid): Refactor as methods of sol_thread_target. (init_sol_thread_ops): Delete. (_initialize_sol_thread): Adjust. Remove references to init_sol_thread_ops and complete_target_initialization. * windows-nat.c (windows_nat_target): New class. (windows_fetch_inferior_registers) (windows_store_inferior_registers, windows_resume, windows_wait) (windows_attach, windows_detach, windows_pid_to_exec_file) (windows_files_info, windows_create_inferior) (windows_mourn_inferior, windows_interrupt, windows_kill_inferior) (windows_close, windows_pid_to_str, windows_xfer_partial) (windows_get_tib_address, windows_get_ada_task_ptid) (windows_thread_name, windows_thread_alive): Refactor as windows_nat_target methods. (do_initial_windows_stuff): Adjust. (windows_target): Delete function. (_initialize_windows_nat): Adjust. * darwin-nat.c (darwin_resume, darwin_wait_to, darwin_interrupt) (darwin_mourn_inferior, darwin_kill_inferior) (darwin_create_inferior, darwin_attach, darwin_detach) (darwin_pid_to_str, darwin_thread_alive, darwin_xfer_partial) (darwin_pid_to_exec_file, darwin_get_ada_task_ptid) (darwin_supports_multi_process): Refactor as darwin_nat_target methods. (darwin_resume_to, darwin_files_info): Delete. (_initialize_darwin_inferior): Rename to ... (_initialize_darwin_nat): ... this. Adjust to C++ification. * darwin-nat.h: Include "inf-child.h". (darwin_nat_target): New class. (darwin_complete_target): Delete. * i386-darwin-nat.c (i386_darwin_nat_target): New class. (darwin_target): New. (i386_darwin_fetch_inferior_registers) (i386_darwin_store_inferior_registers): Refactor as methods of darwin_nat_target. (darwin_complete_target): Delete, with ... (_initialize_i386_darwin_nat): ... bits factored out here. * alpha-linux-nat.c (alpha_linux_nat_target): New class. (the_alpha_linux_nat_target): New. (alpha_linux_register_u_offset): Refactor as alpha_linux_nat_target method. (_initialize_alpha_linux_nat): Adjust. * linux-nat-trad.c (inf_ptrace_register_u_offset): Delete. (inf_ptrace_fetch_register, inf_ptrace_fetch_registers) (inf_ptrace_store_register, inf_ptrace_store_registers): Refact as methods of linux_nat_trad_target. (linux_trad_target): Delete. * linux-nat-trad.h (linux_trad_target): Delete function. (linux_nat_trad_target): New class. * mips-linux-nat.c (mips_linux_nat_target): New class. (super_fetch_registers, super_store_registers, super_close): Delete. (the_mips_linux_nat_target): New. (mips64_linux_regsets_fetch_registers) (mips64_linux_regsets_store_registers) (mips64_linux_fetch_registers, mips64_linux_store_registers) (mips_linux_register_u_offset, mips_linux_read_description) (mips_linux_can_use_hw_breakpoint) (mips_linux_stopped_by_watchpoint) (mips_linux_stopped_data_address) (mips_linux_region_ok_for_hw_watchpoint) (mips_linux_insert_watchpoint, mips_linux_remove_watchpoint) (mips_linux_close): Refactor as methods of mips_linux_nat. (_initialize_mips_linux_nat): Adjust to C++ification. * aix-thread.c (aix_thread_target): New class. (aix_thread_ops): Now an aix_thread_target. (aix_thread_detach, aix_thread_resume, aix_thread_wait) (aix_thread_fetch_registers, aix_thread_store_registers) (aix_thread_xfer_partial, aix_thread_mourn_inferior) (aix_thread_thread_alive, aix_thread_pid_to_str) (aix_thread_extra_thread_info, aix_thread_get_ada_task_ptid): Refactor as methods of aix_thread_target. (init_aix_thread_ops): Delete. (_initialize_aix_thread): Remove references to init_aix_thread_ops and complete_target_initialization. * rs6000-nat.c (rs6000_xfer_shared_libraries): Delete. (rs6000_nat_target): New class. (the_rs6000_nat_target): New. (rs6000_fetch_inferior_registers, rs6000_store_inferior_registers) (rs6000_xfer_partial, rs6000_wait, rs6000_create_inferior) (rs6000_xfer_shared_libraries): Refactor as rs6000_nat_target methods. (super_create_inferior): Delete. (_initialize_rs6000_nat): Adjust to C++ification. * arm-linux-nat.c (arm_linux_nat_target): New class. (the_arm_linux_nat_target): New. (arm_linux_fetch_inferior_registers) (arm_linux_store_inferior_registers, arm_linux_read_description) (arm_linux_can_use_hw_breakpoint, arm_linux_insert_hw_breakpoint) (arm_linux_remove_hw_breakpoint) (arm_linux_region_ok_for_hw_watchpoint) (arm_linux_insert_watchpoint, arm_linux_remove_watchpoint) (arm_linux_stopped_data_address, arm_linux_stopped_by_watchpoint) (arm_linux_watchpoint_addr_within_range): Refactor as methods of arm_linux_nat_target. (_initialize_arm_linux_nat): Adjust to C++ification. * aarch64-linux-nat.c (aarch64_linux_nat_target): New class. (the_aarch64_linux_nat_target): New. (aarch64_linux_fetch_inferior_registers) (aarch64_linux_store_inferior_registers) (aarch64_linux_child_post_startup_inferior) (aarch64_linux_read_description) (aarch64_linux_can_use_hw_breakpoint) (aarch64_linux_insert_hw_breakpoint) (aarch64_linux_remove_hw_breakpoint) (aarch64_linux_insert_watchpoint, aarch64_linux_remove_watchpoint) (aarch64_linux_region_ok_for_hw_watchpoint) (aarch64_linux_stopped_data_address) (aarch64_linux_stopped_by_watchpoint) (aarch64_linux_watchpoint_addr_within_range) (aarch64_linux_can_do_single_step): Refactor as methods of aarch64_linux_nat_target. (super_post_startup_inferior): Delete. (_initialize_aarch64_linux_nat): Adjust to C++ification. * hppa-linux-nat.c (hppa_linux_nat_target): New class. (the_hppa_linux_nat_target): New. (hppa_linux_fetch_inferior_registers) (hppa_linux_store_inferior_registers): Refactor as methods of hppa_linux_nat_target. (_initialize_hppa_linux_nat): Adjust to C++ification. * ia64-linux-nat.c (ia64_linux_nat_target): New class. (the_ia64_linux_nat_target): New. (ia64_linux_insert_watchpoint, ia64_linux_remove_watchpoint) (ia64_linux_stopped_data_address) (ia64_linux_stopped_by_watchpoint, ia64_linux_fetch_registers) (ia64_linux_store_registers, ia64_linux_xfer_partial): Refactor as ia64_linux_nat_target methods. (super_xfer_partial): Delete. (_initialize_ia64_linux_nat): Adjust to C++ification. * m32r-linux-nat.c (m32r_linux_nat_target): New class. (the_m32r_linux_nat_target): New. (m32r_linux_fetch_inferior_registers) (m32r_linux_store_inferior_registers): Refactor as m32r_linux_nat_target methods. (_initialize_m32r_linux_nat): Adjust to C++ification. * m68k-linux-nat.c (m68k_linux_nat_target): New class. (the_m68k_linux_nat_target): New. (m68k_linux_fetch_inferior_registers) (m68k_linux_store_inferior_registers): Refactor as m68k_linux_nat_target methods. (_initialize_m68k_linux_nat): Adjust to C++ification. * s390-linux-nat.c (s390_linux_nat_target): New class. (the_s390_linux_nat_target): New. (s390_linux_fetch_inferior_registers) (s390_linux_store_inferior_registers, s390_stopped_by_watchpoint) (s390_insert_watchpoint, s390_remove_watchpoint) (s390_can_use_hw_breakpoint, s390_insert_hw_breakpoint) (s390_remove_hw_breakpoint, s390_region_ok_for_hw_watchpoint) (s390_auxv_parse, s390_read_description): Refactor as methods of s390_linux_nat_target. (_initialize_s390_nat): Adjust to C++ification. * sparc-linux-nat.c (sparc_linux_nat_target): New class. (the_sparc_linux_nat_target): New. (_initialize_sparc_linux_nat): Adjust to C++ification. * sparc-nat.c (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc64-linux-nat.c (sparc64_linux_nat_target): New class. (the_sparc64_linux_nat_target): New. (_initialize_sparc64_linux_nat): Adjust to C++ification. * spu-linux-nat.c (spu_linux_nat_target): New class. (the_spu_linux_nat_target): New. (spu_child_post_startup_inferior, spu_child_post_attach) (spu_child_wait, spu_fetch_inferior_registers) (spu_store_inferior_registers, spu_xfer_partial) (spu_can_use_hw_breakpoint): Refactor as spu_linux_nat_target methods. (_initialize_spu_nat): Adjust to C++ification. * tilegx-linux-nat.c (tilegx_linux_nat_target): New class. (the_tilegx_linux_nat_target): New. (fetch_inferior_registers, store_inferior_registers): Refactor as methods. (_initialize_tile_linux_nat): Adjust to C++ification. * xtensa-linux-nat.c (xtensa_linux_nat_target): New class. (the_xtensa_linux_nat_target): New. (xtensa_linux_fetch_inferior_registers) (xtensa_linux_store_inferior_registers): Refactor as xtensa_linux_nat_target methods. (_initialize_xtensa_linux_nat): Adjust to C++ification. * fbsd-nat.c (USE_SIGTRAP_SIGINFO): Delete. (fbsd_pid_to_exec_file, fbsd_find_memory_regions) (fbsd_find_memory_regions, fbsd_info_proc, fbsd_xfer_partial) (fbsd_thread_alive, fbsd_pid_to_str, fbsd_thread_name) (fbsd_update_thread_list, fbsd_resume, fbsd_wait) (fbsd_stopped_by_sw_breakpoint) (fbsd_supports_stopped_by_sw_breakpoint, fbsd_follow_fork) (fbsd_insert_fork_catchpoint, fbsd_remove_fork_catchpoint) (fbsd_insert_vfork_catchpoint, fbsd_remove_vfork_catchpoint) (fbsd_post_startup_inferior, fbsd_post_attach) (fbsd_insert_exec_catchpoint, fbsd_remove_exec_catchpoint) (fbsd_set_syscall_catchpoint) (super_xfer_partial, super_resume, super_wait) (fbsd_supports_stopped_by_hw_breakpoint): Delete. (fbsd_handle_debug_trap): Remove target_ops parameter. (fbsd_nat_add_target): Delete. * fbsd-nat.h: Include "inf-ptrace.h". (fbsd_nat_add_target): Delete. (USE_SIGTRAP_SIGINFO): Define. (fbsd_nat_target): New class. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers) (amd64bsd_store_inferior_registers): Remove target_ops parameter. (amd64bsd_target): Delete. * amd64-bsd-nat.h: New file. * amd64-fbsd-nat.c: Include "amd64-bsd-nat.h" instead of "x86-bsd-nat.h". (amd64_fbsd_nat_target): New class. (the_amd64_fbsd_nat_target): New. (amd64fbsd_read_description): Refactor as method of amd64_fbsd_nat_target. (amd64_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_amd64fbsd_nat): Adjust to C++ification. * amd64-nat.h (amd64bsd_target): Delete function declaration. * i386-bsd-nat.c (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Remove target_ops parameter. (i386bsd_target): Delete. * i386-bsd-nat.h (i386bsd_target): Delete function declaration. (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Declare. (i386_bsd_nat_target): New class. * i386-fbsd-nat.c (i386_fbsd_nat_target): New class. (the_i386_fbsd_nat_target): New. (i386fbsd_resume, i386fbsd_read_description): Refactor as i386_fbsd_nat_target methods. (i386_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_i386fbsd_nat): Adjust to C++ification. * x86-bsd-nat.c (super_mourn_inferior): Delete. (x86bsd_mourn_inferior, x86bsd_target): Delete. (_initialize_x86_bsd_nat): Adjust to C++ification. * x86-bsd-nat.h: Include "x86-nat.h". (x86bsd_target): Delete declaration. (x86bsd_nat_target): New class. * aarch64-fbsd-nat.c (aarch64_fbsd_nat_target): New class. (the_aarch64_fbsd_nat_target): New. (aarch64_fbsd_fetch_inferior_registers) (aarch64_fbsd_store_inferior_registers): Refactor as methods of aarch64_fbsd_nat_target. (_initialize_aarch64_fbsd_nat): Adjust to C++ification. * alpha-bsd-nat.c (alpha_bsd_nat_target): New class. (the_alpha_bsd_nat_target): New. (alphabsd_fetch_inferior_registers) (alphabsd_store_inferior_registers): Refactor as alpha_bsd_nat_target methods. (_initialize_alphabsd_nat): Refactor as methods of alpha_bsd_nat_target. * amd64-nbsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_nbsd_nat_target): New. (_initialize_amd64nbsd_nat): Adjust to C++ification. * amd64-obsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_obsd_nat_target): New. (_initialize_amd64obsd_nat): Adjust to C++ification. * arm-fbsd-nat.c (arm_fbsd_nat_target): New. (the_arm_fbsd_nat_target): New. (arm_fbsd_fetch_inferior_registers) (arm_fbsd_store_inferior_registers, arm_fbsd_read_description): (_initialize_arm_fbsd_nat): Refactor as methods of arm_fbsd_nat_target. (_initialize_arm_fbsd_nat): Adjust to C++ification. * arm-nbsd-nat.c (arm_netbsd_nat_target): New class. (the_arm_netbsd_nat_target): New. (armnbsd_fetch_registers, armnbsd_store_registers): Refactor as arm_netbsd_nat_target. (_initialize_arm_netbsd_nat): Adjust to C++ification. * hppa-nbsd-nat.c (hppa_nbsd_nat_target): New class. (the_hppa_nbsd_nat_target): New. (hppanbsd_fetch_registers, hppanbsd_store_registers): Refactor as hppa_nbsd_nat_target methods. (_initialize_hppanbsd_nat): Adjust to C++ification. * hppa-obsd-nat.c (hppa_obsd_nat_target): New class. (the_hppa_obsd_nat_target): New. (hppaobsd_fetch_registers, hppaobsd_store_registers): Refactor as methods of hppa_obsd_nat_target. (_initialize_hppaobsd_nat): Adjust to C++ification. Use add_target. * i386-nbsd-nat.c (the_i386_nbsd_nat_target): New. (_initialize_i386nbsd_nat): Adjust to C++ification. Use add_target. * i386-obsd-nat.c (the_i386_obsd_nat_target): New. (_initialize_i386obsd_nat): Use add_target. * m68k-bsd-nat.c (m68k_bsd_nat_target): New class. (the_m68k_bsd_nat_target): New. (m68kbsd_fetch_inferior_registers) (m68kbsd_store_inferior_registers): Refactor as methods of m68k_bsd_nat_target. (_initialize_m68kbsd_nat): Adjust to C++ification. * mips-fbsd-nat.c (mips_fbsd_nat_target): New class. (the_mips_fbsd_nat_target): New. (mips_fbsd_fetch_inferior_registers) (mips_fbsd_store_inferior_registers): Refactor as methods of mips_fbsd_nat_target. (_initialize_mips_fbsd_nat): Adjust to C++ification. Use add_target. * mips-nbsd-nat.c (mips_nbsd_nat_target): New class. (the_mips_nbsd_nat_target): New. (mipsnbsd_fetch_inferior_registers) (mipsnbsd_store_inferior_registers): Refactor as methods of mips_nbsd_nat_target. (_initialize_mipsnbsd_nat): Adjust to C++ification. * mips64-obsd-nat.c (mips64_obsd_nat_target): New class. (the_mips64_obsd_nat_target): New. (mips64obsd_fetch_inferior_registers) (mips64obsd_store_inferior_registers): Refactor as methods of mips64_obsd_nat_target. (_initialize_mips64obsd_nat): Adjust to C++ification. Use add_target. * nbsd-nat.c (nbsd_pid_to_exec_file): Refactor as method of nbsd_nat_target. * nbsd-nat.h: Include "inf-ptrace.h". (nbsd_nat_target): New class. * obsd-nat.c (obsd_pid_to_str, obsd_update_thread_list) (obsd_wait): Refactor as methods of obsd_nat_target. (obsd_add_target): Delete. * obsd-nat.h: Include "inf-ptrace.h". (obsd_nat_target): New class. * ppc-fbsd-nat.c (ppc_fbsd_nat_target): New class. (the_ppc_fbsd_nat_target): New. (ppcfbsd_fetch_inferior_registers) (ppcfbsd_store_inferior_registers): Refactor as methods of ppc_fbsd_nat_target. (_initialize_ppcfbsd_nat): Adjust to C++ification. Use add_target. * ppc-nbsd-nat.c (ppc_nbsd_nat_target): New class. (the_ppc_nbsd_nat_target): New. (ppcnbsd_fetch_inferior_registers) (ppcnbsd_store_inferior_registers): Refactor as methods of ppc_nbsd_nat_target. (_initialize_ppcnbsd_nat): Adjust to C++ification. * ppc-obsd-nat.c (ppc_obsd_nat_target): New class. (the_ppc_obsd_nat_target): New. (ppcobsd_fetch_registers, ppcobsd_store_registers): Refactor as methods of ppc_obsd_nat_target. (_initialize_ppcobsd_nat): Adjust to C++ification. Use add_target. * sh-nbsd-nat.c (sh_nbsd_nat_target): New class. (the_sh_nbsd_nat_target): New. (shnbsd_fetch_inferior_registers) (shnbsd_store_inferior_registers): Refactor as methods of sh_nbsd_nat_target. (_initialize_shnbsd_nat): Adjust to C++ification. * sparc-nat.c (sparc_xfer_wcookie): Make extern. (inf_ptrace_xfer_partial): Delete. (sparc_xfer_partial, sparc_target): Delete. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers, sparc_xfer_wcookie): Declare. (sparc_target): Delete function declaration. (sparc_target): New template class. * sparc-nbsd-nat.c (the_sparc_nbsd_nat_target): New. (_initialize_sparcnbsd_nat): Adjust to C++ification. * sparc64-fbsd-nat.c (the_sparc64_fbsd_nat_target): New. (_initialize_sparc64fbsd_nat): Adjust to C++ification. Use add_target. * sparc64-nbsd-nat.c (the_sparc64_nbsd_nat_target): New. (_initialize_sparc64nbsd_nat): Adjust to C++ification. * sparc64-obsd-nat.c (the_sparc64_obsd_nat_target): New. (_initialize_sparc64obsd_nat): Adjust to C++ification. Use add_target. * vax-bsd-nat.c (vax_bsd_nat_target): New class. (the_vax_bsd_nat_target): New. (vaxbsd_fetch_inferior_registers) (vaxbsd_store_inferior_registers): Refactor as vax_bsd_nat_target methods. (_initialize_vaxbsd_nat): Adjust to C++ification. * bsd-kvm.c (bsd_kvm_target): New class. (bsd_kvm_ops): Now a bsd_kvm_target. (bsd_kvm_open, bsd_kvm_close, bsd_kvm_xfer_partial) (bsd_kvm_files_info, bsd_kvm_fetch_registers) (bsd_kvm_thread_alive, bsd_kvm_pid_to_str): Refactor as methods of bsd_kvm_target. (bsd_kvm_return_one): Delete. (bsd_kvm_add_target): Adjust to C++ification. * nto-procfs.c (nto_procfs_target, nto_procfs_target_native) (nto_procfs_target_procfs): New classes. (procfs_open_1, procfs_thread_alive, procfs_update_thread_list) (procfs_files_info, procfs_pid_to_exec_file, procfs_attach) (procfs_post_attach, procfs_wait, procfs_fetch_registers) (procfs_xfer_partial, procfs_detach, procfs_insert_breakpoint) (procfs_remove_breakpoint, procfs_insert_hw_breakpoint) (procfs_remove_hw_breakpoint, procfs_resume) (procfs_mourn_inferior, procfs_create_inferior, procfs_interrupt) (procfs_kill_inferior, procfs_store_registers) (procfs_pass_signals, procfs_pid_to_str, procfs_can_run): Refactor as methods of nto_procfs_target. (nto_procfs_ops): Now an nto_procfs_target_procfs. (nto_native_ops): Delete. (procfs_open, procfs_native_open): Delete. (nto_native_ops): Now an nto_procfs_target_native. (init_procfs_targets): Adjust to C++ification. (procfs_can_use_hw_breakpoint, procfs_remove_hw_watchpoint) (procfs_insert_hw_watchpoint, procfs_stopped_by_watchpoint): Refactor as methods of nto_procfs_target. * go32-nat.c (go32_nat_target): New class. (the_go32_nat_target): New. (go32_attach, go32_resume, go32_wait, go32_fetch_registers) (go32_store_registers, go32_xfer_partial, go32_files_info) (go32_kill_inferior, go32_create_inferior, go32_mourn_inferior) (go32_terminal_init, go32_terminal_info, go32_terminal_inferior) (go32_terminal_ours, go32_pass_ctrlc, go32_thread_alive) (go32_pid_to_str): Refactor as methods of go32_nat_target. (go32_target): Delete. (_initialize_go32_nat): Adjust to C++ification. * gnu-nat.c (gnu_wait, gnu_resume, gnu_kill_inferior) (gnu_mourn_inferior, gnu_create_inferior, gnu_attach, gnu_detach) (gnu_stop, gnu_thread_alive, gnu_xfer_partial) (gnu_find_memory_regions, gnu_pid_to_str): Refactor as methods of gnu_nat_target. (gnu_target): Delete. * gnu-nat.h (gnu_target): Delete. (gnu_nat_target): New class. * i386-gnu-nat.c (gnu_base_target): New. (i386_gnu_nat_target): New class. (the_i386_gnu_nat_target): New. (_initialize_i386gnu_nat): Adjust to C++ification. gdb/testsuite/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * gdb.base/breakpoint-in-ro-region.exp: Adjust to to_resume and to_log_command renames. * gdb.base/sss-bp-on-user-bp-2.exp: Likewise.
2018-05-03 07:37:22 +08:00
int
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
ppc_linux_nat_target::can_use_hw_breakpoint (enum bptype type, int cnt,
int ot)
{
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
int total_hw_wp, total_hw_bp;
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
m_dreg_interface.detect (inferior_ptid);
if (m_dreg_interface.unavailable_p ())
return 0;
if (m_dreg_interface.hwdebug_p ())
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
{
/* When PowerPC HWDEBUG ptrace interface is available, the number of
available hardware watchpoints and breakpoints is stored at the
hwdebug_info struct. */
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
total_hw_bp = m_dreg_interface.hwdebug_info ().num_instruction_bps;
total_hw_wp = m_dreg_interface.hwdebug_info ().num_data_bps;
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
}
else
{
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
gdb_assert (m_dreg_interface.debugreg_p ());
/* With the DEBUGREG ptrace interface, we should consider having 1
hardware watchpoint and no hardware breakpoints. */
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
total_hw_bp = 0;
total_hw_wp = 1;
}
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
if (type == bp_hardware_watchpoint || type == bp_read_watchpoint
|| type == bp_access_watchpoint || type == bp_watchpoint)
{
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
if (total_hw_wp == 0)
return 0;
else if (cnt + ot > total_hw_wp)
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
return -1;
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
else
return 1;
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
}
else if (type == bp_hardware_breakpoint)
{
if (total_hw_bp == 0)
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
return 0;
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
else if (cnt > total_hw_bp)
return -1;
else
return 1;
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
}
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
return 0;
}
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
/* Returns 1 if we can watch LEN bytes at address ADDR, 0 otherwise. */
Convert struct target_ops to C++ I.e., use C++ virtual methods and inheritance instead of tables of function pointers. Unfortunately, there's no way to do a smooth transition. ALL native targets in the tree must be converted at the same time. I've tested all I could with cross compilers and with help from GCC compile farm, but naturally I haven't been able to test many of the ports. Still, I made a best effort to port everything over, and while I expect some build problems due to typos and such, which should be trivial to fix, I don't expect any design problems. * Implementation notes: - The flattened current_target is gone. References to current_target or current_target.beneath are replaced with references to target_stack (the top of the stack) directly. - To keep "set debug target" working, this adds a new debug_stratum layer that sits on top of the stack, prints the debug, and delegates to the target beneath. In addition, this makes the shortname and longname properties of target_ops be virtual methods instead of data fields, and makes the debug target defer those to the target beneath. This is so that debug code sprinkled around that does "if (debugtarget) ..." can transparently print the name of the target beneath. A patch later in the series actually splits out the shortname/longname methods to a separate structure, but I preferred to keep that chance separate as it is associated with changing a bit the design of how targets are registered and open. - Since you can't check whether a C++ virtual method is overridden, the old method of checking whether a target_ops implements a method by comparing the function pointer must be replaced with something else. Some cases are fixed by adding a parallel "can_do_foo" target_ops methods. E.g.,: + for (t = target_stack; t != NULL; t = t->beneath) { - if (t->to_create_inferior != NULL) + if (t->can_create_inferior ()) break; } Others are fixed by changing void return type to bool or int return type, and have the default implementation return false or -1, to indicate lack of support. - make-target-delegates was adjusted to generate C++ classes and methods. It needed tweaks to grok "virtual" in front of the target method name, and for the fact that methods are no longer function pointers. (In particular, the current code parsing the return type was simple because it could simply parse up until the '(' in '(*to_foo)'. It now generates a couple C++ classes that inherit target_ops: dummy_target and debug_target. Since we need to generate the class declarations as well, i.e., we need to emit methods twice, we now generate the code in two passes. - The core_target global is renamed to avoid conflict with the "core_target" class. - ctf/tfile targets init_tracefile_ops is replaced by a base class that is inherited by both ctf and tfile. - bsd-uthread The bsd_uthread_ops_hack hack is gone. It's not needed because nothing was extending a target created by bsd_uthread_target. - remote/extended-remote targets This is a first pass, just enough to C++ify target_ops. A later pass will convert more free functions to methods, and make remote_state be truly per remote instance, allowing multiple simultaneous instances of remote targets. - inf-child/"native" is converted to an actual base class (inf_child_target), that is inherited by all native targets. - GNU/Linux The old weird double-target linux_ops mechanism in linux-nat.c, is gone, replaced by adding a few virtual methods to linux-nat.h's target_ops, called low_XXX, that the concrete linux-nat implementations override. Sort of like gdbserver's linux_target_ops, but simpler, for requiring only one target_ops-like hierarchy, which spares implementing the same method twice when we need to forward the method to a low implementation. The low target simply reimplements the target_ops method directly in that case. There are a few remaining linux-nat.c hooks that would be better converted to low_ methods like above too. E.g.: linux_nat_set_new_thread (t, x86_linux_new_thread); linux_nat_set_new_fork (t, x86_linux_new_fork); linux_nat_set_forget_process That'll be done in a follow up patch. - We can no longer use functions like x86_use_watchpoints to install custom methods on an arbitrary base target. The patch replaces instances of such a pattern with template mixins. For example memory_breakpoint_target defined in target.h, or x86_nat_target in x86-nat.h. - linux_trad_target, MIPS and Alpha GNU/Linux The code in the new linux-nat-trad.h/c files which was split off of inf-ptrace.h/c recently, is converted to a C++ base class, and used by the MIPS and Alpha GNU/Linux ports. - BSD targets The $architecture x NetBSD/OpenBSD/FreeBSD support matrix complicates things a bit. There's common BSD target code, and there's common architecture-specific code shared between the different BSDs. Currently, all that is stiched together to form a final target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target functions etc. This introduces new fbsd_nat_target, obsd_nat_target and nbsd_nat_target classes that serve as base/prototype target for the corresponding BSD variant. And introduces generic i386/AMD64 BSD targets, to be used as template mixin to build a final target. Similarly, a generic SPARC target is added, used by both BSD and Linux ports. - bsd_kvm_add_target, BSD libkvm target I considered making bsd_kvm_supply_pcb a virtual method, and then have each port inherit bsd_kvm_target and override that method, but that was resulting in lots of unjustified churn, so I left the function pointer mechanism alone. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> John Baldwin <jhb@freebsd.org> * target.h (enum strata) <debug_stratum>: New. (struct target_ops) <all delegation methods>: Replace by C++ virtual methods, and drop "to_" prefix. All references updated throughout. <to_shortname, to_longname, to_doc, to_data, to_have_steppable_watchpoint, to_have_continuable_watchpoint, to_has_thread_control, to_attach_no_wait>: Delete, replaced by virtual methods. All references updated throughout. <can_attach, supports_terminal_ours, can_create_inferior, get_thread_control_capabilities, attach_no_wait>: New virtual methods. <insert_breakpoint, remove_breakpoint>: Now TARGET_DEFAULT_NORETURN methods. <info_proc>: Now returns bool. <to_magic>: Delete. (OPS_MAGIC): Delete. (current_target): Delete. All references replaced by references to ... (target_stack): ... this. New. (target_shortname, target_longname): Adjust. (target_can_run): Now a function declaration. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (memory_breakpoint_target): New template class. (test_target_ops): Refactor as a C++ class with virtual methods. * make-target-delegates (NAME_PART): Tighten. (POINTER_PART, CP_SYMBOL): New. (SIMPLE_RETURN_PART): Reimplement. (VEC_RETURN_PART): Expect less. (RETURN_PART, VIRTUAL_PART): New. (METHOD): Adjust to C++ virtual methods. (scan_target_h): Remove reference to C99. (dname): Output "target_ops::" prefix. (write_function_header): Adjust to output a C++ class method. (write_declaration): New. (write_delegator): Adjust to output a C++ class method. (tdname): Output "dummy_target::" prefix. (write_tdefault, write_debugmethod): Adjust to output a C++ class method. (tdefault_names, debug_names): Delete. (return_types, tdefaults, styles, argtypes_array): New. (top level): All methods are delegators. (print_class): New. (top level): Print dummy_target and debug_target classes. * target-delegates.c: Regenerate. * target-debug.h (target_debug_print_enum_info_proc_what) (target_debug_print_thread_control_capabilities) (target_debug_print_thread_info_p): New. * target.c (dummy_target): Delete. (the_dummy_target, the_debug_target): New. (target_stack): Now extern. (set_targetdebug): Push/unpush debug target. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (add_target_with_completer): No longer call complete_target_initialization. (target_supports_terminal_ours): Use regular delegation. (update_current_target): Delete. (push_target): No longer check magic number. Don't call update_current_target. (unpush_target): Don't call update_current_target. (target_is_pushed): No longer check magic number. (target_require_runnable): Skip for all stratums over process_stratum. (target_ops::info_proc): New. (target_info_proc): Use find_target_at and find_default_run_target. (target_supports_disable_randomization): Use regular delegation. (target_get_osdata): Use find_target_at. (target_ops::open, target_ops::close, target_ops::can_attach) (target_ops::attach, target_ops::can_create_inferior) (target_ops::create_inferior, target_ops::can_run) (target_can_run): New. (default_fileio_target): Use regular delegation. (target_ops::fileio_open, target_ops::fileio_pwrite) (target_ops::fileio_pread, target_ops::fileio_fstat) (target_ops::fileio_close, target_ops::fileio_unlink) (target_ops::fileio_readlink): New. (target_fileio_open_1, target_fileio_unlink) (target_fileio_readlink): Always call the target method. Handle FILEIO_ENOSYS. (return_zero, return_zero_has_execution): Delete. (init_dummy_target): Delete. (dummy_target::dummy_target, dummy_target::shortname) (dummy_target::longname, dummy_target::doc) (debug_target::debug_target, debug_target::shortname) (debug_target::longname, debug_target::doc): New. (target_supports_delete_record): Use regular delegation. (setup_target_debug): Delete. (maintenance_print_target_stack): Skip debug_stratum. (initialize_targets): Instantiate the_dummy_target and the_debug_target. * auxv.c (target_auxv_parse): Remove 'ops' parameter. Adjust to use target_stack. (target_auxv_search, fprint_target_auxv): Adjust. (info_auxv_command): Adjust to use target_stack. * auxv.h (target_auxv_parse): Remove 'ops' parameter. * exceptions.c (print_flush): Handle a NULL target_stack. * regcache.c (target_ops_no_register): Refactor as class with virtual methods. * exec.c (exec_target): New class. (exec_ops): Now an exec_target. (exec_open, exec_close_1, exec_get_section_table) (exec_xfer_partial, exec_files_info, exec_has_memory) (exec_make_note_section): Refactor as exec_target methods. (exec_file_clear, ignore, exec_remove_breakpoint, init_exec_ops): Delete. (exec_target::find_memory_regions): New. (_initialize_exec): Don't call init_exec_ops. * gdbcore.h (exec_file_clear): Delete. * corefile.c (core_target): Delete. (core_file_command): Adjust. * corelow.c (core_target): New class. (the_core_target): New. (core_close): Remove target_ops parameter. (core_close_cleanup): Adjust. (core_target::close): New. (core_open, core_detach, get_core_registers, core_files_info) (core_xfer_partial, core_thread_alive, core_read_description) (core_pid_to_str, core_thread_name, core_has_memory) (core_has_stack, core_has_registers, core_info_proc): Rework as core_target methods. (ignore, core_remove_breakpoint, init_core_ops): Delete. (_initialize_corelow): Initialize the_core_target. * gdbcore.h (core_target): Delete. (the_core_target): New. * ctf.c: (ctf_target): New class. (ctf_ops): Now a ctf_target. (ctf_open, ctf_close, ctf_files_info, ctf_fetch_registers) (ctf_xfer_partial, ctf_get_trace_state_variable_value) (ctf_trace_find, ctf_traceframe_info): Refactor as ctf_target methods. (init_ctf_ops): Delete. (_initialize_ctf): Don't call it. * tracefile-tfile.c (tfile_target): New class. (tfile_ops): Now a tfile_target. (tfile_open, tfile_close, tfile_files_info) (tfile_get_tracepoint_status, tfile_trace_find) (tfile_fetch_registers, tfile_xfer_partial) (tfile_get_trace_state_variable_value, tfile_traceframe_info): Refactor as tfile_target methods. (tfile_xfer_partial_features): Remove target_ops parameter. (init_tfile_ops): Delete. (_initialize_tracefile_tfile): Don't call it. * tracefile.c (tracefile_has_all_memory, tracefile_has_memory) (tracefile_has_stack, tracefile_has_registers) (tracefile_thread_alive, tracefile_get_trace_status): Refactor as tracefile_target methods. (init_tracefile_ops): Delete. (tracefile_target::tracefile_target): New. * tracefile.h: Include "target.h". (tracefile_target): New class. (init_tracefile_ops): Delete. * spu-multiarch.c (spu_multiarch_target): New class. (spu_ops): Now a spu_multiarch_target. (spu_thread_architecture, spu_region_ok_for_hw_watchpoint) (spu_fetch_registers, spu_store_registers, spu_xfer_partial) (spu_search_memory, spu_mourn_inferior): Refactor as spu_multiarch_target methods. (init_spu_ops): Delete. (_initialize_spu_multiarch): Remove references to init_spu_ops, complete_target_initialization. * ravenscar-thread.c (ravenscar_thread_target): New class. (ravenscar_ops): Now a ravenscar_thread_target. (ravenscar_resume, ravenscar_wait, ravenscar_update_thread_list) (ravenscar_thread_alive, ravenscar_pid_to_str) (ravenscar_fetch_registers, ravenscar_store_registers) (ravenscar_prepare_to_store, ravenscar_stopped_by_sw_breakpoint) (ravenscar_stopped_by_hw_breakpoint) (ravenscar_stopped_by_watchpoint, ravenscar_stopped_data_address) (ravenscar_mourn_inferior, ravenscar_core_of_thread) (ravenscar_get_ada_task_ptid): Refactor as ravenscar_thread_target methods. (init_ravenscar_thread_ops): Delete. (_initialize_ravenscar): Remove references to init_ravenscar_thread_ops and complete_target_initialization. * bsd-uthread.c (bsd_uthread_ops_hack): Delete. (bsd_uthread_target): New class. (bsd_uthread_ops): Now a bsd_uthread_target. (bsd_uthread_activate): Adjust to refer to bsd_uthread_ops. (bsd_uthread_close, bsd_uthread_mourn_inferior) (bsd_uthread_fetch_registers, bsd_uthread_store_registers) (bsd_uthread_wait, bsd_uthread_resume, bsd_uthread_thread_alive) (bsd_uthread_update_thread_list, bsd_uthread_extra_thread_info) (bsd_uthread_pid_to_str): Refactor as bsd_uthread_target methods. (bsd_uthread_target): Delete function. (_initialize_bsd_uthread): Remove reference to complete_target_initialization. * bfd-target.c (target_bfd_data): Delete. Fields folded into ... (target_bfd): ... this new class. (target_bfd_xfer_partial, target_bfd_get_section_table) (target_bfd_close): Refactor as target_bfd methods. (target_bfd::~target_bfd): New. (target_bfd_reopen): Adjust. (target_bfd::close): New. * record-btrace.c (record_btrace_target): New class. (record_btrace_ops): Now a record_btrace_target. (record_btrace_open, record_btrace_stop_recording) (record_btrace_disconnect, record_btrace_close) (record_btrace_async, record_btrace_info) (record_btrace_insn_history, record_btrace_insn_history_range) (record_btrace_insn_history_from, record_btrace_call_history) (record_btrace_call_history_range) (record_btrace_call_history_from, record_btrace_record_method) (record_btrace_is_replaying, record_btrace_will_replay) (record_btrace_xfer_partial, record_btrace_insert_breakpoint) (record_btrace_remove_breakpoint, record_btrace_fetch_registers) (record_btrace_store_registers, record_btrace_prepare_to_store) (record_btrace_to_get_unwinder) (record_btrace_to_get_tailcall_unwinder, record_btrace_resume) (record_btrace_commit_resume, record_btrace_wait) (record_btrace_stop, record_btrace_can_execute_reverse) (record_btrace_stopped_by_sw_breakpoint) (record_btrace_supports_stopped_by_sw_breakpoint) (record_btrace_stopped_by_hw_breakpoint) (record_btrace_supports_stopped_by_hw_breakpoint) (record_btrace_update_thread_list, record_btrace_thread_alive) (record_btrace_goto_begin, record_btrace_goto_end) (record_btrace_goto, record_btrace_stop_replaying_all) (record_btrace_execution_direction) (record_btrace_prepare_to_generate_core) (record_btrace_done_generating_core): Refactor as record_btrace_target methods. (init_record_btrace_ops): Delete. (_initialize_record_btrace): Remove reference to init_record_btrace_ops. * record-full.c (RECORD_FULL_IS_REPLAY): Adjust to always refer to the execution_direction global. (record_full_base_target, record_full_target) (record_full_core_target): New classes. (record_full_ops): Now a record_full_target. (record_full_core_ops): Now a record_full_core_target. (record_full_target::detach, record_full_target::disconnect) (record_full_core_target::disconnect) (record_full_target::mourn_inferior, record_full_target::kill): New. (record_full_open, record_full_close, record_full_async): Refactor as methods of the record_full_base_target class. (record_full_resume, record_full_commit_resume): Refactor as methods of the record_full_target class. (record_full_wait, record_full_stopped_by_watchpoint) (record_full_stopped_data_address) (record_full_stopped_by_sw_breakpoint) (record_full_supports_stopped_by_sw_breakpoint) (record_full_stopped_by_hw_breakpoint) (record_full_supports_stopped_by_hw_breakpoint): Refactor as methods of the record_full_base_target class. (record_full_store_registers, record_full_xfer_partial) (record_full_insert_breakpoint, record_full_remove_breakpoint): Refactor as methods of the record_full_target class. (record_full_can_execute_reverse, record_full_get_bookmark) (record_full_goto_bookmark, record_full_execution_direction) (record_full_record_method, record_full_info, record_full_delete) (record_full_is_replaying, record_full_will_replay) (record_full_goto_begin, record_full_goto_end, record_full_goto) (record_full_stop_replaying): Refactor as methods of the record_full_base_target class. (record_full_core_resume, record_full_core_kill) (record_full_core_fetch_registers) (record_full_core_prepare_to_store) (record_full_core_store_registers, record_full_core_xfer_partial) (record_full_core_insert_breakpoint) (record_full_core_remove_breakpoint) (record_full_core_has_execution): Refactor as methods of the record_full_core_target class. (record_full_base_target::supports_delete_record): New. (init_record_full_ops): Delete. (init_record_full_core_ops): Delete. (record_full_save): Refactor as method of the record_full_base_target class. (_initialize_record_full): Remove references to init_record_full_ops and init_record_full_core_ops. * remote.c (remote_target, extended_remote_target): New classes. (remote_ops): Now a remote_target. (extended_remote_ops): Now an extended_remote_target. (remote_insert_fork_catchpoint, remote_remove_fork_catchpoint) (remote_insert_vfork_catchpoint, remote_remove_vfork_catchpoint) (remote_insert_exec_catchpoint, remote_remove_exec_catchpoint) (remote_pass_signals, remote_set_syscall_catchpoint) (remote_program_signals, ) (remote_thread_always_alive): Remove target_ops parameter. (remote_thread_alive, remote_thread_name) (remote_update_thread_list, remote_threads_extra_info) (remote_static_tracepoint_marker_at) (remote_static_tracepoint_markers_by_strid) (remote_get_ada_task_ptid, remote_close, remote_start_remote) (remote_open): Refactor as methods of remote_target. (extended_remote_open, extended_remote_detach) (extended_remote_attach, extended_remote_post_attach): (extended_remote_supports_disable_randomization) (extended_remote_create_inferior): : Refactor as method of extended_remote_target. (remote_set_permissions, remote_open_1, remote_detach) (remote_follow_fork, remote_follow_exec, remote_disconnect) (remote_resume, remote_commit_resume, remote_stop) (remote_interrupt, remote_pass_ctrlc, remote_terminal_inferior) (remote_terminal_ours, remote_wait, remote_fetch_registers) (remote_prepare_to_store, remote_store_registers) (remote_flash_erase, remote_flash_done, remote_files_info) (remote_kill, remote_mourn, remote_insert_breakpoint) (remote_remove_breakpoint, remote_insert_watchpoint) (remote_watchpoint_addr_within_range) (remote_remove_watchpoint, remote_region_ok_for_hw_watchpoint) (remote_check_watch_resources, remote_stopped_by_sw_breakpoint) (remote_supports_stopped_by_sw_breakpoint) (remote_stopped_by_hw_breakpoint) (remote_supports_stopped_by_hw_breakpoint) (remote_stopped_by_watchpoint, remote_stopped_data_address) (remote_insert_hw_breakpoint, remote_remove_hw_breakpoint) (remote_verify_memory): Refactor as methods of remote_target. (remote_write_qxfer, remote_read_qxfer): Remove target_ops parameter. (remote_xfer_partial, remote_get_memory_xfer_limit) (remote_search_memory, remote_rcmd, remote_memory_map) (remote_pid_to_str, remote_get_thread_local_address) (remote_get_tib_address, remote_read_description): Refactor as methods of remote_target. (remote_target::fileio_open, remote_target::fileio_pwrite) (remote_target::fileio_pread, remote_target::fileio_close): New. (remote_hostio_readlink, remote_hostio_fstat) (remote_filesystem_is_local, remote_can_execute_reverse) (remote_supports_non_stop, remote_supports_disable_randomization) (remote_supports_multi_process, remote_supports_cond_breakpoints) (remote_supports_enable_disable_tracepoint) (remote_supports_string_tracing) (remote_can_run_breakpoint_commands, remote_trace_init) (remote_download_tracepoint, remote_can_download_tracepoint) (remote_download_trace_state_variable, remote_enable_tracepoint) (remote_disable_tracepoint, remote_trace_set_readonly_regions) (remote_trace_start, remote_get_trace_status) (remote_get_tracepoint_status, remote_trace_stop) (remote_trace_find, remote_get_trace_state_variable_value) (remote_save_trace_data, remote_get_raw_trace_data) (remote_set_disconnected_tracing, remote_core_of_thread) (remote_set_circular_trace_buffer, remote_traceframe_info) (remote_get_min_fast_tracepoint_insn_len) (remote_set_trace_buffer_size, remote_set_trace_notes) (remote_use_agent, remote_can_use_agent, remote_enable_btrace) (remote_disable_btrace, remote_teardown_btrace) (remote_read_btrace, remote_btrace_conf) (remote_augmented_libraries_svr4_read, remote_load) (remote_pid_to_exec_file, remote_can_do_single_step) (remote_execution_direction, remote_thread_handle_to_thread_info): Refactor as methods of remote_target. (init_remote_ops, init_extended_remote_ops): Delete. (remote_can_async_p, remote_is_async_p, remote_async) (remote_thread_events, remote_upload_tracepoints) (remote_upload_trace_state_variables): Refactor as methods of remote_target. (_initialize_remote): Remove references to init_remote_ops and init_extended_remote_ops. * remote-sim.c (gdbsim_target): New class. (gdbsim_fetch_register, gdbsim_store_register, gdbsim_kill) (gdbsim_load, gdbsim_create_inferior, gdbsim_open, gdbsim_close) (gdbsim_detach, gdbsim_resume, gdbsim_interrupt) (gdbsim_wait, gdbsim_prepare_to_store, gdbsim_xfer_partial) (gdbsim_files_info, gdbsim_mourn_inferior, gdbsim_thread_alive) (gdbsim_pid_to_str, gdbsim_has_all_memory, gdbsim_has_memory): Refactor as methods of gdbsim_target. (gdbsim_ops): Now a gdbsim_target. (init_gdbsim_ops): Delete. (gdbsim_cntrl_c): Adjust. (_initialize_remote_sim): Remove reference to init_gdbsim_ops. * amd64-linux-nat.c (amd64_linux_nat_target): New class. (the_amd64_linux_nat_target): New. (amd64_linux_fetch_inferior_registers) (amd64_linux_store_inferior_registers): Refactor as methods of amd64_linux_nat_target. (_initialize_amd64_linux_nat): Adjust. Set linux_target. * i386-linux-nat.c: Don't include "linux-nat.h". (i386_linux_nat_target): New class. (the_i386_linux_nat_target): New. (i386_linux_fetch_inferior_registers) (i386_linux_store_inferior_registers, i386_linux_resume): Refactor as methods of i386_linux_nat_target. (_initialize_i386_linux_nat): Adjust. Set linux_target. * inf-child.c (inf_child_ops): Delete. (inf_child_fetch_inferior_registers) (inf_child_store_inferior_registers): Delete. (inf_child_post_attach, inf_child_prepare_to_store): Refactor as methods of inf_child_target. (inf_child_target::supports_terminal_ours) (inf_child_target::terminal_init) (inf_child_target::terminal_inferior) (inf_child_target::terminal_ours_for_output) (inf_child_target::terminal_ours, inf_child_target::interrupt) (inf_child_target::pass_ctrlc, inf_child_target::terminal_info): New. (inf_child_open, inf_child_disconnect, inf_child_close) (inf_child_mourn_inferior, inf_child_maybe_unpush_target) (inf_child_post_startup_inferior, inf_child_can_run) (inf_child_pid_to_exec_file): Refactor as methods of inf_child_target. (inf_child_follow_fork): Delete. (inf_child_target::can_create_inferior) (inf_child_target::can_attach): New. (inf_child_target::has_all_memory, inf_child_target::has_memory) (inf_child_target::has_stack, inf_child_target::has_registers) (inf_child_target::has_execution): New. (inf_child_fileio_open, inf_child_fileio_pwrite) (inf_child_fileio_pread, inf_child_fileio_fstat) (inf_child_fileio_close, inf_child_fileio_unlink) (inf_child_fileio_readlink, inf_child_use_agent) (inf_child_can_use_agent): Refactor as methods of inf_child_target. (return_zero, inf_child_target): Delete. (inf_child_target::inf_child_target): New. * inf-child.h: Include "target.h". (inf_child_target): Delete function prototype. (inf_child_target): New class. (inf_child_open_target, inf_child_mourn_inferior) (inf_child_maybe_unpush_target): Delete. * inf-ptrace.c (inf_ptrace_target::~inf_ptrace_target): New. (inf_ptrace_follow_fork, inf_ptrace_insert_fork_catchpoint) (inf_ptrace_remove_fork_catchpoint, inf_ptrace_create_inferior) (inf_ptrace_post_startup_inferior, inf_ptrace_mourn_inferior) (inf_ptrace_attach, inf_ptrace_post_attach, inf_ptrace_detach) (inf_ptrace_detach_success, inf_ptrace_kill, inf_ptrace_resume) (inf_ptrace_wait, inf_ptrace_xfer_partial) (inf_ptrace_thread_alive, inf_ptrace_files_info) (inf_ptrace_pid_to_str, inf_ptrace_auxv_parse): Refactor as methods of inf_ptrace_target. (inf_ptrace_target): Delete function. * inf-ptrace.h: Include "inf-child.h". (inf_ptrace_target): Delete function declaration. (inf_ptrace_target): New class. (inf_ptrace_trad_target, inf_ptrace_detach_success): Delete. * linux-nat.c (linux_target): New. (linux_ops, linux_ops_saved, super_xfer_partial): Delete. (linux_nat_target::~linux_nat_target): New. (linux_child_post_attach, linux_child_post_startup_inferior) (linux_child_follow_fork, linux_child_insert_fork_catchpoint) (linux_child_remove_fork_catchpoint) (linux_child_insert_vfork_catchpoint) (linux_child_remove_vfork_catchpoint) (linux_child_insert_exec_catchpoint) (linux_child_remove_exec_catchpoint) (linux_child_set_syscall_catchpoint, linux_nat_pass_signals) (linux_nat_create_inferior, linux_nat_attach, linux_nat_detach) (linux_nat_resume, linux_nat_stopped_by_watchpoint) (linux_nat_stopped_data_address) (linux_nat_stopped_by_sw_breakpoint) (linux_nat_supports_stopped_by_sw_breakpoint) (linux_nat_stopped_by_hw_breakpoint) (linux_nat_supports_stopped_by_hw_breakpoint, linux_nat_wait) (linux_nat_kill, linux_nat_mourn_inferior) (linux_nat_xfer_partial, linux_nat_thread_alive) (linux_nat_update_thread_list, linux_nat_pid_to_str) (linux_nat_thread_name, linux_child_pid_to_exec_file) (linux_child_static_tracepoint_markers_by_strid) (linux_nat_is_async_p, linux_nat_can_async_p) (linux_nat_supports_non_stop, linux_nat_always_non_stop_p) (linux_nat_supports_multi_process) (linux_nat_supports_disable_randomization, linux_nat_async) (linux_nat_stop, linux_nat_close, linux_nat_thread_address_space) (linux_nat_core_of_thread, linux_nat_filesystem_is_local) (linux_nat_fileio_open, linux_nat_fileio_readlink) (linux_nat_fileio_unlink, linux_nat_thread_events): Refactor as methods of linux_nat_target. (linux_nat_wait_1, linux_xfer_siginfo, linux_proc_xfer_partial) (linux_proc_xfer_spu, linux_nat_xfer_osdata): Remove target_ops parameter. (check_stopped_by_watchpoint): Adjust. (linux_xfer_partial): Delete. (linux_target_install_ops, linux_target, linux_nat_add_target): Delete. (linux_nat_target::linux_nat_target): New. * linux-nat.h: Include "inf-ptrace.h". (linux_nat_target): New. (linux_target, linux_target_install_ops, linux_nat_add_target): Delete function declarations. (linux_target): Declare global. * linux-thread-db.c (thread_db_target): New. (thread_db_target::thread_db_target): New. (thread_db_ops): Delete. (the_thread_db_target): New. (thread_db_detach, thread_db_wait, thread_db_mourn_inferior) (thread_db_update_thread_list, thread_db_pid_to_str) (thread_db_extra_thread_info) (thread_db_thread_handle_to_thread_info) (thread_db_get_thread_local_address, thread_db_get_ada_task_ptid) (thread_db_resume): Refactor as methods of thread_db_target. (init_thread_db_ops): Delete. (_initialize_thread_db): Remove reference to init_thread_db_ops. * x86-linux-nat.c: Don't include "linux-nat.h". (super_post_startup_inferior): Delete. (x86_linux_nat_target::~x86_linux_nat_target): New. (x86_linux_child_post_startup_inferior) (x86_linux_read_description, x86_linux_enable_btrace) (x86_linux_disable_btrace, x86_linux_teardown_btrace) (x86_linux_read_btrace, x86_linux_btrace_conf): Refactor as methods of x86_linux_nat_target. (x86_linux_create_target): Delete. Bits folded ... (x86_linux_add_target): ... here. Now takes a linux_nat_target pointer. * x86-linux-nat.h: Include "linux-nat.h" and "x86-nat.h". (x86_linux_nat_target): New class. (x86_linux_create_target): Delete. (x86_linux_add_target): Now takes a linux_nat_target pointer. * x86-nat.c (x86_insert_watchpoint, x86_remove_watchpoint) (x86_region_ok_for_watchpoint, x86_stopped_data_address) (x86_stopped_by_watchpoint, x86_insert_hw_breakpoint) (x86_remove_hw_breakpoint, x86_can_use_hw_breakpoint) (x86_stopped_by_hw_breakpoint): Remove target_ops parameter and make extern. (x86_use_watchpoints): Delete. * x86-nat.h: Include "breakpoint.h" and "target.h". (x86_use_watchpoints): Delete. (x86_can_use_hw_breakpoint, x86_region_ok_for_hw_watchpoint) (x86_stopped_by_watchpoint, x86_stopped_data_address) (x86_insert_watchpoint, x86_remove_watchpoint) (x86_insert_hw_breakpoint, x86_remove_hw_breakpoint) (x86_stopped_by_hw_breakpoint): New declarations. (x86_nat_target): New template class. * ppc-linux-nat.c (ppc_linux_nat_target): New class. (the_ppc_linux_nat_target): New. (ppc_linux_fetch_inferior_registers) (ppc_linux_can_use_hw_breakpoint) (ppc_linux_region_ok_for_hw_watchpoint) (ppc_linux_ranged_break_num_registers) (ppc_linux_insert_hw_breakpoint, ppc_linux_remove_hw_breakpoint) (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_can_accel_watchpoint_condition) (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint) (ppc_linux_stopped_data_address, ppc_linux_stopped_by_watchpoint) (ppc_linux_watchpoint_addr_within_range) (ppc_linux_masked_watch_num_registers) (ppc_linux_store_inferior_registers, ppc_linux_auxv_parse) (ppc_linux_read_description): Refactor as methods of ppc_linux_nat_target. (_initialize_ppc_linux_nat): Adjust. Set linux_target. * procfs.c (procfs_xfer_partial): Delete forward declaration. (procfs_target): New class. (the_procfs_target): New. (procfs_target): Delete function. (procfs_auxv_parse, procfs_attach, procfs_detach) (procfs_fetch_registers, procfs_store_registers, procfs_wait) (procfs_xfer_partial, procfs_resume, procfs_pass_signals) (procfs_files_info, procfs_kill_inferior, procfs_mourn_inferior) (procfs_create_inferior, procfs_update_thread_list) (procfs_thread_alive, procfs_pid_to_str) (procfs_can_use_hw_breakpoint, procfs_stopped_by_watchpoint) (procfs_stopped_data_address, procfs_insert_watchpoint) (procfs_remove_watchpoint, procfs_region_ok_for_hw_watchpoint) (proc_find_memory_regions, procfs_info_proc) (procfs_make_note_section): Refactor as methods of procfs_target. (_initialize_procfs): Adjust. * sol-thread.c (sol_thread_target): New class. (sol_thread_ops): Now a sol_thread_target. (sol_thread_detach, sol_thread_resume, sol_thread_wait) (sol_thread_fetch_registers, sol_thread_store_registers) (sol_thread_xfer_partial, sol_thread_mourn_inferior) (sol_thread_alive, solaris_pid_to_str, sol_update_thread_list) (sol_get_ada_task_ptid): Refactor as methods of sol_thread_target. (init_sol_thread_ops): Delete. (_initialize_sol_thread): Adjust. Remove references to init_sol_thread_ops and complete_target_initialization. * windows-nat.c (windows_nat_target): New class. (windows_fetch_inferior_registers) (windows_store_inferior_registers, windows_resume, windows_wait) (windows_attach, windows_detach, windows_pid_to_exec_file) (windows_files_info, windows_create_inferior) (windows_mourn_inferior, windows_interrupt, windows_kill_inferior) (windows_close, windows_pid_to_str, windows_xfer_partial) (windows_get_tib_address, windows_get_ada_task_ptid) (windows_thread_name, windows_thread_alive): Refactor as windows_nat_target methods. (do_initial_windows_stuff): Adjust. (windows_target): Delete function. (_initialize_windows_nat): Adjust. * darwin-nat.c (darwin_resume, darwin_wait_to, darwin_interrupt) (darwin_mourn_inferior, darwin_kill_inferior) (darwin_create_inferior, darwin_attach, darwin_detach) (darwin_pid_to_str, darwin_thread_alive, darwin_xfer_partial) (darwin_pid_to_exec_file, darwin_get_ada_task_ptid) (darwin_supports_multi_process): Refactor as darwin_nat_target methods. (darwin_resume_to, darwin_files_info): Delete. (_initialize_darwin_inferior): Rename to ... (_initialize_darwin_nat): ... this. Adjust to C++ification. * darwin-nat.h: Include "inf-child.h". (darwin_nat_target): New class. (darwin_complete_target): Delete. * i386-darwin-nat.c (i386_darwin_nat_target): New class. (darwin_target): New. (i386_darwin_fetch_inferior_registers) (i386_darwin_store_inferior_registers): Refactor as methods of darwin_nat_target. (darwin_complete_target): Delete, with ... (_initialize_i386_darwin_nat): ... bits factored out here. * alpha-linux-nat.c (alpha_linux_nat_target): New class. (the_alpha_linux_nat_target): New. (alpha_linux_register_u_offset): Refactor as alpha_linux_nat_target method. (_initialize_alpha_linux_nat): Adjust. * linux-nat-trad.c (inf_ptrace_register_u_offset): Delete. (inf_ptrace_fetch_register, inf_ptrace_fetch_registers) (inf_ptrace_store_register, inf_ptrace_store_registers): Refact as methods of linux_nat_trad_target. (linux_trad_target): Delete. * linux-nat-trad.h (linux_trad_target): Delete function. (linux_nat_trad_target): New class. * mips-linux-nat.c (mips_linux_nat_target): New class. (super_fetch_registers, super_store_registers, super_close): Delete. (the_mips_linux_nat_target): New. (mips64_linux_regsets_fetch_registers) (mips64_linux_regsets_store_registers) (mips64_linux_fetch_registers, mips64_linux_store_registers) (mips_linux_register_u_offset, mips_linux_read_description) (mips_linux_can_use_hw_breakpoint) (mips_linux_stopped_by_watchpoint) (mips_linux_stopped_data_address) (mips_linux_region_ok_for_hw_watchpoint) (mips_linux_insert_watchpoint, mips_linux_remove_watchpoint) (mips_linux_close): Refactor as methods of mips_linux_nat. (_initialize_mips_linux_nat): Adjust to C++ification. * aix-thread.c (aix_thread_target): New class. (aix_thread_ops): Now an aix_thread_target. (aix_thread_detach, aix_thread_resume, aix_thread_wait) (aix_thread_fetch_registers, aix_thread_store_registers) (aix_thread_xfer_partial, aix_thread_mourn_inferior) (aix_thread_thread_alive, aix_thread_pid_to_str) (aix_thread_extra_thread_info, aix_thread_get_ada_task_ptid): Refactor as methods of aix_thread_target. (init_aix_thread_ops): Delete. (_initialize_aix_thread): Remove references to init_aix_thread_ops and complete_target_initialization. * rs6000-nat.c (rs6000_xfer_shared_libraries): Delete. (rs6000_nat_target): New class. (the_rs6000_nat_target): New. (rs6000_fetch_inferior_registers, rs6000_store_inferior_registers) (rs6000_xfer_partial, rs6000_wait, rs6000_create_inferior) (rs6000_xfer_shared_libraries): Refactor as rs6000_nat_target methods. (super_create_inferior): Delete. (_initialize_rs6000_nat): Adjust to C++ification. * arm-linux-nat.c (arm_linux_nat_target): New class. (the_arm_linux_nat_target): New. (arm_linux_fetch_inferior_registers) (arm_linux_store_inferior_registers, arm_linux_read_description) (arm_linux_can_use_hw_breakpoint, arm_linux_insert_hw_breakpoint) (arm_linux_remove_hw_breakpoint) (arm_linux_region_ok_for_hw_watchpoint) (arm_linux_insert_watchpoint, arm_linux_remove_watchpoint) (arm_linux_stopped_data_address, arm_linux_stopped_by_watchpoint) (arm_linux_watchpoint_addr_within_range): Refactor as methods of arm_linux_nat_target. (_initialize_arm_linux_nat): Adjust to C++ification. * aarch64-linux-nat.c (aarch64_linux_nat_target): New class. (the_aarch64_linux_nat_target): New. (aarch64_linux_fetch_inferior_registers) (aarch64_linux_store_inferior_registers) (aarch64_linux_child_post_startup_inferior) (aarch64_linux_read_description) (aarch64_linux_can_use_hw_breakpoint) (aarch64_linux_insert_hw_breakpoint) (aarch64_linux_remove_hw_breakpoint) (aarch64_linux_insert_watchpoint, aarch64_linux_remove_watchpoint) (aarch64_linux_region_ok_for_hw_watchpoint) (aarch64_linux_stopped_data_address) (aarch64_linux_stopped_by_watchpoint) (aarch64_linux_watchpoint_addr_within_range) (aarch64_linux_can_do_single_step): Refactor as methods of aarch64_linux_nat_target. (super_post_startup_inferior): Delete. (_initialize_aarch64_linux_nat): Adjust to C++ification. * hppa-linux-nat.c (hppa_linux_nat_target): New class. (the_hppa_linux_nat_target): New. (hppa_linux_fetch_inferior_registers) (hppa_linux_store_inferior_registers): Refactor as methods of hppa_linux_nat_target. (_initialize_hppa_linux_nat): Adjust to C++ification. * ia64-linux-nat.c (ia64_linux_nat_target): New class. (the_ia64_linux_nat_target): New. (ia64_linux_insert_watchpoint, ia64_linux_remove_watchpoint) (ia64_linux_stopped_data_address) (ia64_linux_stopped_by_watchpoint, ia64_linux_fetch_registers) (ia64_linux_store_registers, ia64_linux_xfer_partial): Refactor as ia64_linux_nat_target methods. (super_xfer_partial): Delete. (_initialize_ia64_linux_nat): Adjust to C++ification. * m32r-linux-nat.c (m32r_linux_nat_target): New class. (the_m32r_linux_nat_target): New. (m32r_linux_fetch_inferior_registers) (m32r_linux_store_inferior_registers): Refactor as m32r_linux_nat_target methods. (_initialize_m32r_linux_nat): Adjust to C++ification. * m68k-linux-nat.c (m68k_linux_nat_target): New class. (the_m68k_linux_nat_target): New. (m68k_linux_fetch_inferior_registers) (m68k_linux_store_inferior_registers): Refactor as m68k_linux_nat_target methods. (_initialize_m68k_linux_nat): Adjust to C++ification. * s390-linux-nat.c (s390_linux_nat_target): New class. (the_s390_linux_nat_target): New. (s390_linux_fetch_inferior_registers) (s390_linux_store_inferior_registers, s390_stopped_by_watchpoint) (s390_insert_watchpoint, s390_remove_watchpoint) (s390_can_use_hw_breakpoint, s390_insert_hw_breakpoint) (s390_remove_hw_breakpoint, s390_region_ok_for_hw_watchpoint) (s390_auxv_parse, s390_read_description): Refactor as methods of s390_linux_nat_target. (_initialize_s390_nat): Adjust to C++ification. * sparc-linux-nat.c (sparc_linux_nat_target): New class. (the_sparc_linux_nat_target): New. (_initialize_sparc_linux_nat): Adjust to C++ification. * sparc-nat.c (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc64-linux-nat.c (sparc64_linux_nat_target): New class. (the_sparc64_linux_nat_target): New. (_initialize_sparc64_linux_nat): Adjust to C++ification. * spu-linux-nat.c (spu_linux_nat_target): New class. (the_spu_linux_nat_target): New. (spu_child_post_startup_inferior, spu_child_post_attach) (spu_child_wait, spu_fetch_inferior_registers) (spu_store_inferior_registers, spu_xfer_partial) (spu_can_use_hw_breakpoint): Refactor as spu_linux_nat_target methods. (_initialize_spu_nat): Adjust to C++ification. * tilegx-linux-nat.c (tilegx_linux_nat_target): New class. (the_tilegx_linux_nat_target): New. (fetch_inferior_registers, store_inferior_registers): Refactor as methods. (_initialize_tile_linux_nat): Adjust to C++ification. * xtensa-linux-nat.c (xtensa_linux_nat_target): New class. (the_xtensa_linux_nat_target): New. (xtensa_linux_fetch_inferior_registers) (xtensa_linux_store_inferior_registers): Refactor as xtensa_linux_nat_target methods. (_initialize_xtensa_linux_nat): Adjust to C++ification. * fbsd-nat.c (USE_SIGTRAP_SIGINFO): Delete. (fbsd_pid_to_exec_file, fbsd_find_memory_regions) (fbsd_find_memory_regions, fbsd_info_proc, fbsd_xfer_partial) (fbsd_thread_alive, fbsd_pid_to_str, fbsd_thread_name) (fbsd_update_thread_list, fbsd_resume, fbsd_wait) (fbsd_stopped_by_sw_breakpoint) (fbsd_supports_stopped_by_sw_breakpoint, fbsd_follow_fork) (fbsd_insert_fork_catchpoint, fbsd_remove_fork_catchpoint) (fbsd_insert_vfork_catchpoint, fbsd_remove_vfork_catchpoint) (fbsd_post_startup_inferior, fbsd_post_attach) (fbsd_insert_exec_catchpoint, fbsd_remove_exec_catchpoint) (fbsd_set_syscall_catchpoint) (super_xfer_partial, super_resume, super_wait) (fbsd_supports_stopped_by_hw_breakpoint): Delete. (fbsd_handle_debug_trap): Remove target_ops parameter. (fbsd_nat_add_target): Delete. * fbsd-nat.h: Include "inf-ptrace.h". (fbsd_nat_add_target): Delete. (USE_SIGTRAP_SIGINFO): Define. (fbsd_nat_target): New class. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers) (amd64bsd_store_inferior_registers): Remove target_ops parameter. (amd64bsd_target): Delete. * amd64-bsd-nat.h: New file. * amd64-fbsd-nat.c: Include "amd64-bsd-nat.h" instead of "x86-bsd-nat.h". (amd64_fbsd_nat_target): New class. (the_amd64_fbsd_nat_target): New. (amd64fbsd_read_description): Refactor as method of amd64_fbsd_nat_target. (amd64_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_amd64fbsd_nat): Adjust to C++ification. * amd64-nat.h (amd64bsd_target): Delete function declaration. * i386-bsd-nat.c (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Remove target_ops parameter. (i386bsd_target): Delete. * i386-bsd-nat.h (i386bsd_target): Delete function declaration. (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Declare. (i386_bsd_nat_target): New class. * i386-fbsd-nat.c (i386_fbsd_nat_target): New class. (the_i386_fbsd_nat_target): New. (i386fbsd_resume, i386fbsd_read_description): Refactor as i386_fbsd_nat_target methods. (i386_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_i386fbsd_nat): Adjust to C++ification. * x86-bsd-nat.c (super_mourn_inferior): Delete. (x86bsd_mourn_inferior, x86bsd_target): Delete. (_initialize_x86_bsd_nat): Adjust to C++ification. * x86-bsd-nat.h: Include "x86-nat.h". (x86bsd_target): Delete declaration. (x86bsd_nat_target): New class. * aarch64-fbsd-nat.c (aarch64_fbsd_nat_target): New class. (the_aarch64_fbsd_nat_target): New. (aarch64_fbsd_fetch_inferior_registers) (aarch64_fbsd_store_inferior_registers): Refactor as methods of aarch64_fbsd_nat_target. (_initialize_aarch64_fbsd_nat): Adjust to C++ification. * alpha-bsd-nat.c (alpha_bsd_nat_target): New class. (the_alpha_bsd_nat_target): New. (alphabsd_fetch_inferior_registers) (alphabsd_store_inferior_registers): Refactor as alpha_bsd_nat_target methods. (_initialize_alphabsd_nat): Refactor as methods of alpha_bsd_nat_target. * amd64-nbsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_nbsd_nat_target): New. (_initialize_amd64nbsd_nat): Adjust to C++ification. * amd64-obsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_obsd_nat_target): New. (_initialize_amd64obsd_nat): Adjust to C++ification. * arm-fbsd-nat.c (arm_fbsd_nat_target): New. (the_arm_fbsd_nat_target): New. (arm_fbsd_fetch_inferior_registers) (arm_fbsd_store_inferior_registers, arm_fbsd_read_description): (_initialize_arm_fbsd_nat): Refactor as methods of arm_fbsd_nat_target. (_initialize_arm_fbsd_nat): Adjust to C++ification. * arm-nbsd-nat.c (arm_netbsd_nat_target): New class. (the_arm_netbsd_nat_target): New. (armnbsd_fetch_registers, armnbsd_store_registers): Refactor as arm_netbsd_nat_target. (_initialize_arm_netbsd_nat): Adjust to C++ification. * hppa-nbsd-nat.c (hppa_nbsd_nat_target): New class. (the_hppa_nbsd_nat_target): New. (hppanbsd_fetch_registers, hppanbsd_store_registers): Refactor as hppa_nbsd_nat_target methods. (_initialize_hppanbsd_nat): Adjust to C++ification. * hppa-obsd-nat.c (hppa_obsd_nat_target): New class. (the_hppa_obsd_nat_target): New. (hppaobsd_fetch_registers, hppaobsd_store_registers): Refactor as methods of hppa_obsd_nat_target. (_initialize_hppaobsd_nat): Adjust to C++ification. Use add_target. * i386-nbsd-nat.c (the_i386_nbsd_nat_target): New. (_initialize_i386nbsd_nat): Adjust to C++ification. Use add_target. * i386-obsd-nat.c (the_i386_obsd_nat_target): New. (_initialize_i386obsd_nat): Use add_target. * m68k-bsd-nat.c (m68k_bsd_nat_target): New class. (the_m68k_bsd_nat_target): New. (m68kbsd_fetch_inferior_registers) (m68kbsd_store_inferior_registers): Refactor as methods of m68k_bsd_nat_target. (_initialize_m68kbsd_nat): Adjust to C++ification. * mips-fbsd-nat.c (mips_fbsd_nat_target): New class. (the_mips_fbsd_nat_target): New. (mips_fbsd_fetch_inferior_registers) (mips_fbsd_store_inferior_registers): Refactor as methods of mips_fbsd_nat_target. (_initialize_mips_fbsd_nat): Adjust to C++ification. Use add_target. * mips-nbsd-nat.c (mips_nbsd_nat_target): New class. (the_mips_nbsd_nat_target): New. (mipsnbsd_fetch_inferior_registers) (mipsnbsd_store_inferior_registers): Refactor as methods of mips_nbsd_nat_target. (_initialize_mipsnbsd_nat): Adjust to C++ification. * mips64-obsd-nat.c (mips64_obsd_nat_target): New class. (the_mips64_obsd_nat_target): New. (mips64obsd_fetch_inferior_registers) (mips64obsd_store_inferior_registers): Refactor as methods of mips64_obsd_nat_target. (_initialize_mips64obsd_nat): Adjust to C++ification. Use add_target. * nbsd-nat.c (nbsd_pid_to_exec_file): Refactor as method of nbsd_nat_target. * nbsd-nat.h: Include "inf-ptrace.h". (nbsd_nat_target): New class. * obsd-nat.c (obsd_pid_to_str, obsd_update_thread_list) (obsd_wait): Refactor as methods of obsd_nat_target. (obsd_add_target): Delete. * obsd-nat.h: Include "inf-ptrace.h". (obsd_nat_target): New class. * ppc-fbsd-nat.c (ppc_fbsd_nat_target): New class. (the_ppc_fbsd_nat_target): New. (ppcfbsd_fetch_inferior_registers) (ppcfbsd_store_inferior_registers): Refactor as methods of ppc_fbsd_nat_target. (_initialize_ppcfbsd_nat): Adjust to C++ification. Use add_target. * ppc-nbsd-nat.c (ppc_nbsd_nat_target): New class. (the_ppc_nbsd_nat_target): New. (ppcnbsd_fetch_inferior_registers) (ppcnbsd_store_inferior_registers): Refactor as methods of ppc_nbsd_nat_target. (_initialize_ppcnbsd_nat): Adjust to C++ification. * ppc-obsd-nat.c (ppc_obsd_nat_target): New class. (the_ppc_obsd_nat_target): New. (ppcobsd_fetch_registers, ppcobsd_store_registers): Refactor as methods of ppc_obsd_nat_target. (_initialize_ppcobsd_nat): Adjust to C++ification. Use add_target. * sh-nbsd-nat.c (sh_nbsd_nat_target): New class. (the_sh_nbsd_nat_target): New. (shnbsd_fetch_inferior_registers) (shnbsd_store_inferior_registers): Refactor as methods of sh_nbsd_nat_target. (_initialize_shnbsd_nat): Adjust to C++ification. * sparc-nat.c (sparc_xfer_wcookie): Make extern. (inf_ptrace_xfer_partial): Delete. (sparc_xfer_partial, sparc_target): Delete. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers, sparc_xfer_wcookie): Declare. (sparc_target): Delete function declaration. (sparc_target): New template class. * sparc-nbsd-nat.c (the_sparc_nbsd_nat_target): New. (_initialize_sparcnbsd_nat): Adjust to C++ification. * sparc64-fbsd-nat.c (the_sparc64_fbsd_nat_target): New. (_initialize_sparc64fbsd_nat): Adjust to C++ification. Use add_target. * sparc64-nbsd-nat.c (the_sparc64_nbsd_nat_target): New. (_initialize_sparc64nbsd_nat): Adjust to C++ification. * sparc64-obsd-nat.c (the_sparc64_obsd_nat_target): New. (_initialize_sparc64obsd_nat): Adjust to C++ification. Use add_target. * vax-bsd-nat.c (vax_bsd_nat_target): New class. (the_vax_bsd_nat_target): New. (vaxbsd_fetch_inferior_registers) (vaxbsd_store_inferior_registers): Refactor as vax_bsd_nat_target methods. (_initialize_vaxbsd_nat): Adjust to C++ification. * bsd-kvm.c (bsd_kvm_target): New class. (bsd_kvm_ops): Now a bsd_kvm_target. (bsd_kvm_open, bsd_kvm_close, bsd_kvm_xfer_partial) (bsd_kvm_files_info, bsd_kvm_fetch_registers) (bsd_kvm_thread_alive, bsd_kvm_pid_to_str): Refactor as methods of bsd_kvm_target. (bsd_kvm_return_one): Delete. (bsd_kvm_add_target): Adjust to C++ification. * nto-procfs.c (nto_procfs_target, nto_procfs_target_native) (nto_procfs_target_procfs): New classes. (procfs_open_1, procfs_thread_alive, procfs_update_thread_list) (procfs_files_info, procfs_pid_to_exec_file, procfs_attach) (procfs_post_attach, procfs_wait, procfs_fetch_registers) (procfs_xfer_partial, procfs_detach, procfs_insert_breakpoint) (procfs_remove_breakpoint, procfs_insert_hw_breakpoint) (procfs_remove_hw_breakpoint, procfs_resume) (procfs_mourn_inferior, procfs_create_inferior, procfs_interrupt) (procfs_kill_inferior, procfs_store_registers) (procfs_pass_signals, procfs_pid_to_str, procfs_can_run): Refactor as methods of nto_procfs_target. (nto_procfs_ops): Now an nto_procfs_target_procfs. (nto_native_ops): Delete. (procfs_open, procfs_native_open): Delete. (nto_native_ops): Now an nto_procfs_target_native. (init_procfs_targets): Adjust to C++ification. (procfs_can_use_hw_breakpoint, procfs_remove_hw_watchpoint) (procfs_insert_hw_watchpoint, procfs_stopped_by_watchpoint): Refactor as methods of nto_procfs_target. * go32-nat.c (go32_nat_target): New class. (the_go32_nat_target): New. (go32_attach, go32_resume, go32_wait, go32_fetch_registers) (go32_store_registers, go32_xfer_partial, go32_files_info) (go32_kill_inferior, go32_create_inferior, go32_mourn_inferior) (go32_terminal_init, go32_terminal_info, go32_terminal_inferior) (go32_terminal_ours, go32_pass_ctrlc, go32_thread_alive) (go32_pid_to_str): Refactor as methods of go32_nat_target. (go32_target): Delete. (_initialize_go32_nat): Adjust to C++ification. * gnu-nat.c (gnu_wait, gnu_resume, gnu_kill_inferior) (gnu_mourn_inferior, gnu_create_inferior, gnu_attach, gnu_detach) (gnu_stop, gnu_thread_alive, gnu_xfer_partial) (gnu_find_memory_regions, gnu_pid_to_str): Refactor as methods of gnu_nat_target. (gnu_target): Delete. * gnu-nat.h (gnu_target): Delete. (gnu_nat_target): New class. * i386-gnu-nat.c (gnu_base_target): New. (i386_gnu_nat_target): New class. (the_i386_gnu_nat_target): New. (_initialize_i386gnu_nat): Adjust to C++ification. gdb/testsuite/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * gdb.base/breakpoint-in-ro-region.exp: Adjust to to_resume and to_log_command renames. * gdb.base/sss-bp-on-user-bp-2.exp: Likewise.
2018-05-03 07:37:22 +08:00
int
ppc_linux_nat_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
{
/* Handle sub-8-byte quantities. */
if (len <= 0)
return 0;
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
m_dreg_interface.detect (inferior_ptid);
if (m_dreg_interface.unavailable_p ())
return 0;
/* The PowerPC HWDEBUG ptrace interface tells if there are alignment
restrictions for watchpoints in the processors. In that case, we use that
information to determine the hardcoded watchable region for
watchpoints. */
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
if (m_dreg_interface.hwdebug_p ())
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
{
int region_size;
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
const struct ppc_debug_info &hwdebug_info = (m_dreg_interface
.hwdebug_info ());
/* Embedded DAC-based processors, like the PowerPC 440 have ranged
watchpoints and can watch any access within an arbitrary memory
region. This is useful to watch arrays and structs, for instance. It
takes two hardware watchpoints though. */
2011-01-11 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Implement support for PowerPC BookE ranged watchpoints. gdb/ * breakpoint.h (struct breakpoint_ops) <resources_needed>: New method. Initialize to NULL in all existing breakpoint_ops instances. (struct breakpoint) <exact>: New field. (target_exact_watchpoints): Declare external global. * breakpoint.c (target_exact_watchpoints): New global flag. (update_watchpoint): Set b->type to bp_hardware_watchpoint and b->enable_state to bp_enabled before calling hw_watchpoint_used_count. (hw_watchpoint_used_count): Iterate over all bp_locations in a watchpoint. Call breakpoint's breakpoint_ops.resources_needed if available. (insert_watchpoint, remove_watchpoint): Use fixed length of 1 byte if the watchpoint is exact. (resources_needed_watchpoint): New function. (watchpoint_breakpoint_ops): Add resources_needed_watchpoint. (watch_command_1): Set b->exact if the user asked for an exact watchpoint and one can be set. (can_use_hardware_watchpoint): Add exact_watchpoints argument. Pass fixed length of 1 to target_region_ok_for_hw_watchpoint if the user asks for an exact watchpoint and one can be set. Return number of needed debug registers to watch the expression. * gdbtypes.c (is_scalar_type): New function, based on valprint.c:scalar_type_p. (is_scalar_type_recursive): New function. * gdbtypes.h (is_scalar_type_recursive): Declare. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Always handle regions when ranged watchpoints are available. (create_watchpoint_request): New function. (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint): Use create_watchpoint_request. * rs6000-tdep.c (show_powerpc_exact_watchpoints): New function. (_initialize_rs6000_tdep): Add `exact-watchpoints' boolean to the `set powerpc' and `show powerpc' commands. * target.h (struct target_ops) <to_region_ok_for_hw_watchpoint>: Mention documentation comment in the target macro. (target_region_ok_for_hw_watchpoint): Document return value. gdb/doc/ * gdb.texinfo (PowerPC Embedded): Document ranged watchpoints and the "set powerpc exact-watchpoints" flag.
2011-01-12 03:23:03 +08:00
if (len > 1
&& hwdebug_info.features & PPC_DEBUG_FEATURE_DATA_BP_RANGE
&& linux_get_hwcap (current_top_target ()) & PPC_FEATURE_BOOKE)
2011-01-11 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Implement support for PowerPC BookE ranged watchpoints. gdb/ * breakpoint.h (struct breakpoint_ops) <resources_needed>: New method. Initialize to NULL in all existing breakpoint_ops instances. (struct breakpoint) <exact>: New field. (target_exact_watchpoints): Declare external global. * breakpoint.c (target_exact_watchpoints): New global flag. (update_watchpoint): Set b->type to bp_hardware_watchpoint and b->enable_state to bp_enabled before calling hw_watchpoint_used_count. (hw_watchpoint_used_count): Iterate over all bp_locations in a watchpoint. Call breakpoint's breakpoint_ops.resources_needed if available. (insert_watchpoint, remove_watchpoint): Use fixed length of 1 byte if the watchpoint is exact. (resources_needed_watchpoint): New function. (watchpoint_breakpoint_ops): Add resources_needed_watchpoint. (watch_command_1): Set b->exact if the user asked for an exact watchpoint and one can be set. (can_use_hardware_watchpoint): Add exact_watchpoints argument. Pass fixed length of 1 to target_region_ok_for_hw_watchpoint if the user asks for an exact watchpoint and one can be set. Return number of needed debug registers to watch the expression. * gdbtypes.c (is_scalar_type): New function, based on valprint.c:scalar_type_p. (is_scalar_type_recursive): New function. * gdbtypes.h (is_scalar_type_recursive): Declare. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Always handle regions when ranged watchpoints are available. (create_watchpoint_request): New function. (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint): Use create_watchpoint_request. * rs6000-tdep.c (show_powerpc_exact_watchpoints): New function. (_initialize_rs6000_tdep): Add `exact-watchpoints' boolean to the `set powerpc' and `show powerpc' commands. * target.h (struct target_ops) <to_region_ok_for_hw_watchpoint>: Mention documentation comment in the target macro. (target_region_ok_for_hw_watchpoint): Document return value. gdb/doc/ * gdb.texinfo (PowerPC Embedded): Document ranged watchpoints and the "set powerpc exact-watchpoints" flag.
2011-01-12 03:23:03 +08:00
return 2;
/* Check if the processor provides DAWR interface. */
if (hwdebug_info.features & PPC_DEBUG_FEATURE_DATA_BP_DAWR)
/* DAWR interface allows to watch up to 512 byte wide ranges which
can't cross a 512 byte boundary. */
region_size = 512;
else
region_size = hwdebug_info.data_bp_alignment;
/* Server processors provide one hardware watchpoint and addr+len should
fall in the watchable region provided by the ptrace interface. */
if (region_size
&& (addr + len > (addr & ~(region_size - 1)) + region_size))
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
return 0;
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
}
/* addr+len must fall in the 8 byte watchable region for DABR-based
processors (i.e., server processors). Without the new PowerPC HWDEBUG
ptrace interface, DAC-based processors (i.e., embedded processors) will
use addresses aligned to 4-bytes due to the way the read/write flags are
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
passed in the old ptrace interface. */
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
else
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
{
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
gdb_assert (m_dreg_interface.debugreg_p ());
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
if (((linux_get_hwcap (current_top_target ()) & PPC_FEATURE_BOOKE)
&& (addr + len) > (addr & ~3) + 4)
|| (addr + len) > (addr & ~7) + 8)
return 0;
}
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
return 1;
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
}
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
/* This function compares two ppc_hw_breakpoint structs
field-by-field. */
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
bool
ppc_linux_nat_target::hwdebug_point_cmp (const struct ppc_hw_breakpoint &a,
const struct ppc_hw_breakpoint &b)
{
return (a.trigger_type == b.trigger_type
&& a.addr_mode == b.addr_mode
&& a.condition_mode == b.condition_mode
&& a.addr == b.addr
&& a.addr2 == b.addr2
&& a.condition_value == b.condition_value);
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
}
* linux-nat.c (linux_nat_new_thread): New variable. (linux_child_follow_fork): Set inferior_ptid to include LWP ID. Use linux_nat_switch_fork. (lwp_list): Make public. (add_lwp): Call linux_nat_new_thread. (lin_lwp_attach_lwp, linux_nat_attach): Call add_lwp after stopping the new thread. (resume_callback): Clear lp->siginfo. Remove unused variable. (linux_nat_resume): Assert that the LWP list is already initialized. Clear lp->siginfo. (save_siginfo): New. (stop_wait_callback, linux_nat_wait): Call it. (linux_nat_set_new_thread, linux_nat_get_siginfo): New. * linux-nat.h (struct lwp_info): Add siginfo. (lwp_list, linux_nat_set_new_thread, linux_nat_get_siginfo): Declare. (ALL_LWPS): Define. * amd64-linux-nat.c (amd64_linux_dr): New. (amd64_linux_dr_get): Take a PTID argument. Correct typo. (amd64_linux_dr_set): Take a PTID argument. (amd64_linux_dr_set_control, amd64_linux_dr_set_addr): Use ALL_LWPS. (amd64_linux_dr_reset_addr): Use amd64_linux_dr_set_addr. (amd64_linux_dr_get_status): Pass inferior_ptid to amd64_linux_dr_get. (amd64_linux_new_thread): New. (_initialize_amd64_linux_nat): Call linux_nat_set_new_thread. * i386-linux-nat.c (i386_linux_dr): New. (i386_linux_dr_get, i386_linux_dr_set): Take a PTID argument. (i386_linux_dr_set_control, i386_linux_dr_set_addr): Use ALL_LWPS. (i386_linux_dr_reset_addr): Use i386_linux_dr_set_addr. (i386_linux_dr_get_status): Pass inferior_ptid to i386_linux_dr_get. (i386_linux_new_thread): New. (i386_linux_resume): Remove unnecessary PID check. (_initialize_i386_linux_nat): Call linux_nat_set_new_thread. * ia64-linux-nat.c (enable_watchpoints_in_psr): Take PTID argument. (fetch_debug_register, fetch_debug_register_pair): Delete. (debug_registers): New. (ia64_linux_insert_watchpoint, ia64_linux_remove_watchpoint): Use ALL_LWPS and debug_registers. (ia64_linux_new_thread): New. (ia64_linux_stopped_data_address): Use linux_nat_get_siginfo. (_initialize_ia64_linux_nat): Call linux_nat_set_new_thread. * ppc-linux-nat.c (last_stopped_data_address): Delete. (saved_dabr_value): New. (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint): Use ALL_LWPS. (ppc_linux_new_thread): New. (ppc_linux_stopped_data_address): Use linux_nat_get_siginfo. (ppc_linux_stopped_by_watchpoint): Call ppc_linux_stopped_data_address. (_initialize_ppc_linux_nat): Call linux_nat_set_new_thread. * s390-nat.c (s390_stopped_by_watchpoint): Clear the watchpoint status after reading it. (s390_fix_watch_points): Take a PTID argument. (s390_insert_watchpoint, s390_remove_watchpoint): Use ALL_LWPS. (_initialize_s390_nat): Call linux_nat_set_new_thread.
2007-10-01 08:22:50 +08:00
2011-03-31 Thiago Jung Bauermann <bauerman@br.ibm.com> Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Implement support for PowerPC BookE ranged breakpoints. gdb/ * NEWS: Mention support for ranged breakpoints on embedded PowerPC. * breakpoint.h (struct bp_target_info) <length>: New member variable. (struct breakpoint_ops) <breakpoint_hit>: Take struct bp_location instead of struct breakpoint as argument, and also add ASPACE and BP_ADDR arguments. Update all callers. (struct breakpoint_ops) <print_one_detail>: New method. (struct breakpoint) <addr_string_range_end>: New member variable. * breakpoint.c (breakpoint_location_address_match): Add function prototype. (insert_bp_location): Set bl->target_info.length. (breakpoint_here_p): Call breakpoint_location_address_match. (moribund_breakpoint_here_p): Likewise. (regular_breakpoint_inserted_here_p): Likewise. (breakpoint_thread_match): Likewise. (bpstat_stop_status): Likewise. (bpstat_check_location): Move call to breakpoint_ops.breakpoint_hit to the top. (print_one_breakpoint_location): Call breakpoint_ops.print_one_detail if available. (breakpoint_address_match_range): New function. (breakpoint_location_address_match): Likewise. (breakpoint_locations_match): Compare the length field of the locations too. (hw_breakpoint_used_count): Count resources used by all locations in a breakpoint, and use breakpoint_ops.resources_needed if available. (breakpoint_hit_ranged_breakpoint): New function. (resources_needed_ranged_breakpoint): Likewise. (print_it_ranged_breakpoint): Likewise. (print_one_ranged_breakpoint): Likewise. (print_one_detail_ranged_breakpoint): Likewise. (print_mention_ranged_breakpoint): Likewise. (print_recreate_ranged_breakpoint): Likewise. (ranged_breakpoint_ops): New structure. (find_breakpoint_range_end): New function. (break_range_command): Likewise. (delete_breakpoint): Free addr_string_range_end. (update_breakpoint_locations): Add SALS_END argument. Update all callers. Calculate breakpoint length if a non-zero SALS_END is given. Call breakpoint_locations_match instead of breakpoint_address_match. (reset_breakpoint): Find SaL of the end of the range if B is a ranged breakpoint. (_initialize_breakpoint): Register break-range command. * defs.h (print_core_address): Add function prototype. * ppc-linux-nat.c (ppc_linux_ranged_break_num_registers): New function. (ppc_linux_insert_hw_breakpoint): Support ranged breakpoints. (ppc_linux_remove_hw_breakpoint): Likewise. (_initialize_ppc_linux_nat): Initialize to_ranged_break_num_registers. * target.c (update_current_target): Add comment about to_ranged_break_num_registers. (target_ranged_break_num_registers): New function. * target.h (struct target_ops) <to_ranged_break_num_registers>: New method. (target_ranged_break_num_registers): Add function prototype. * ui-out.c (ui_out_field_core_addr): Move address-printing logic to ... * utils.c (print_core_address): ... here. gdb/doc/ * gdb.texinfo (PowerPC Embedded): Document ranged breakpoints.
2011-03-31 22:32:49 +08:00
/* Return the number of registers needed for a ranged breakpoint. */
Convert struct target_ops to C++ I.e., use C++ virtual methods and inheritance instead of tables of function pointers. Unfortunately, there's no way to do a smooth transition. ALL native targets in the tree must be converted at the same time. I've tested all I could with cross compilers and with help from GCC compile farm, but naturally I haven't been able to test many of the ports. Still, I made a best effort to port everything over, and while I expect some build problems due to typos and such, which should be trivial to fix, I don't expect any design problems. * Implementation notes: - The flattened current_target is gone. References to current_target or current_target.beneath are replaced with references to target_stack (the top of the stack) directly. - To keep "set debug target" working, this adds a new debug_stratum layer that sits on top of the stack, prints the debug, and delegates to the target beneath. In addition, this makes the shortname and longname properties of target_ops be virtual methods instead of data fields, and makes the debug target defer those to the target beneath. This is so that debug code sprinkled around that does "if (debugtarget) ..." can transparently print the name of the target beneath. A patch later in the series actually splits out the shortname/longname methods to a separate structure, but I preferred to keep that chance separate as it is associated with changing a bit the design of how targets are registered and open. - Since you can't check whether a C++ virtual method is overridden, the old method of checking whether a target_ops implements a method by comparing the function pointer must be replaced with something else. Some cases are fixed by adding a parallel "can_do_foo" target_ops methods. E.g.,: + for (t = target_stack; t != NULL; t = t->beneath) { - if (t->to_create_inferior != NULL) + if (t->can_create_inferior ()) break; } Others are fixed by changing void return type to bool or int return type, and have the default implementation return false or -1, to indicate lack of support. - make-target-delegates was adjusted to generate C++ classes and methods. It needed tweaks to grok "virtual" in front of the target method name, and for the fact that methods are no longer function pointers. (In particular, the current code parsing the return type was simple because it could simply parse up until the '(' in '(*to_foo)'. It now generates a couple C++ classes that inherit target_ops: dummy_target and debug_target. Since we need to generate the class declarations as well, i.e., we need to emit methods twice, we now generate the code in two passes. - The core_target global is renamed to avoid conflict with the "core_target" class. - ctf/tfile targets init_tracefile_ops is replaced by a base class that is inherited by both ctf and tfile. - bsd-uthread The bsd_uthread_ops_hack hack is gone. It's not needed because nothing was extending a target created by bsd_uthread_target. - remote/extended-remote targets This is a first pass, just enough to C++ify target_ops. A later pass will convert more free functions to methods, and make remote_state be truly per remote instance, allowing multiple simultaneous instances of remote targets. - inf-child/"native" is converted to an actual base class (inf_child_target), that is inherited by all native targets. - GNU/Linux The old weird double-target linux_ops mechanism in linux-nat.c, is gone, replaced by adding a few virtual methods to linux-nat.h's target_ops, called low_XXX, that the concrete linux-nat implementations override. Sort of like gdbserver's linux_target_ops, but simpler, for requiring only one target_ops-like hierarchy, which spares implementing the same method twice when we need to forward the method to a low implementation. The low target simply reimplements the target_ops method directly in that case. There are a few remaining linux-nat.c hooks that would be better converted to low_ methods like above too. E.g.: linux_nat_set_new_thread (t, x86_linux_new_thread); linux_nat_set_new_fork (t, x86_linux_new_fork); linux_nat_set_forget_process That'll be done in a follow up patch. - We can no longer use functions like x86_use_watchpoints to install custom methods on an arbitrary base target. The patch replaces instances of such a pattern with template mixins. For example memory_breakpoint_target defined in target.h, or x86_nat_target in x86-nat.h. - linux_trad_target, MIPS and Alpha GNU/Linux The code in the new linux-nat-trad.h/c files which was split off of inf-ptrace.h/c recently, is converted to a C++ base class, and used by the MIPS and Alpha GNU/Linux ports. - BSD targets The $architecture x NetBSD/OpenBSD/FreeBSD support matrix complicates things a bit. There's common BSD target code, and there's common architecture-specific code shared between the different BSDs. Currently, all that is stiched together to form a final target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target functions etc. This introduces new fbsd_nat_target, obsd_nat_target and nbsd_nat_target classes that serve as base/prototype target for the corresponding BSD variant. And introduces generic i386/AMD64 BSD targets, to be used as template mixin to build a final target. Similarly, a generic SPARC target is added, used by both BSD and Linux ports. - bsd_kvm_add_target, BSD libkvm target I considered making bsd_kvm_supply_pcb a virtual method, and then have each port inherit bsd_kvm_target and override that method, but that was resulting in lots of unjustified churn, so I left the function pointer mechanism alone. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> John Baldwin <jhb@freebsd.org> * target.h (enum strata) <debug_stratum>: New. (struct target_ops) <all delegation methods>: Replace by C++ virtual methods, and drop "to_" prefix. All references updated throughout. <to_shortname, to_longname, to_doc, to_data, to_have_steppable_watchpoint, to_have_continuable_watchpoint, to_has_thread_control, to_attach_no_wait>: Delete, replaced by virtual methods. All references updated throughout. <can_attach, supports_terminal_ours, can_create_inferior, get_thread_control_capabilities, attach_no_wait>: New virtual methods. <insert_breakpoint, remove_breakpoint>: Now TARGET_DEFAULT_NORETURN methods. <info_proc>: Now returns bool. <to_magic>: Delete. (OPS_MAGIC): Delete. (current_target): Delete. All references replaced by references to ... (target_stack): ... this. New. (target_shortname, target_longname): Adjust. (target_can_run): Now a function declaration. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (memory_breakpoint_target): New template class. (test_target_ops): Refactor as a C++ class with virtual methods. * make-target-delegates (NAME_PART): Tighten. (POINTER_PART, CP_SYMBOL): New. (SIMPLE_RETURN_PART): Reimplement. (VEC_RETURN_PART): Expect less. (RETURN_PART, VIRTUAL_PART): New. (METHOD): Adjust to C++ virtual methods. (scan_target_h): Remove reference to C99. (dname): Output "target_ops::" prefix. (write_function_header): Adjust to output a C++ class method. (write_declaration): New. (write_delegator): Adjust to output a C++ class method. (tdname): Output "dummy_target::" prefix. (write_tdefault, write_debugmethod): Adjust to output a C++ class method. (tdefault_names, debug_names): Delete. (return_types, tdefaults, styles, argtypes_array): New. (top level): All methods are delegators. (print_class): New. (top level): Print dummy_target and debug_target classes. * target-delegates.c: Regenerate. * target-debug.h (target_debug_print_enum_info_proc_what) (target_debug_print_thread_control_capabilities) (target_debug_print_thread_info_p): New. * target.c (dummy_target): Delete. (the_dummy_target, the_debug_target): New. (target_stack): Now extern. (set_targetdebug): Push/unpush debug target. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (add_target_with_completer): No longer call complete_target_initialization. (target_supports_terminal_ours): Use regular delegation. (update_current_target): Delete. (push_target): No longer check magic number. Don't call update_current_target. (unpush_target): Don't call update_current_target. (target_is_pushed): No longer check magic number. (target_require_runnable): Skip for all stratums over process_stratum. (target_ops::info_proc): New. (target_info_proc): Use find_target_at and find_default_run_target. (target_supports_disable_randomization): Use regular delegation. (target_get_osdata): Use find_target_at. (target_ops::open, target_ops::close, target_ops::can_attach) (target_ops::attach, target_ops::can_create_inferior) (target_ops::create_inferior, target_ops::can_run) (target_can_run): New. (default_fileio_target): Use regular delegation. (target_ops::fileio_open, target_ops::fileio_pwrite) (target_ops::fileio_pread, target_ops::fileio_fstat) (target_ops::fileio_close, target_ops::fileio_unlink) (target_ops::fileio_readlink): New. (target_fileio_open_1, target_fileio_unlink) (target_fileio_readlink): Always call the target method. Handle FILEIO_ENOSYS. (return_zero, return_zero_has_execution): Delete. (init_dummy_target): Delete. (dummy_target::dummy_target, dummy_target::shortname) (dummy_target::longname, dummy_target::doc) (debug_target::debug_target, debug_target::shortname) (debug_target::longname, debug_target::doc): New. (target_supports_delete_record): Use regular delegation. (setup_target_debug): Delete. (maintenance_print_target_stack): Skip debug_stratum. (initialize_targets): Instantiate the_dummy_target and the_debug_target. * auxv.c (target_auxv_parse): Remove 'ops' parameter. Adjust to use target_stack. (target_auxv_search, fprint_target_auxv): Adjust. (info_auxv_command): Adjust to use target_stack. * auxv.h (target_auxv_parse): Remove 'ops' parameter. * exceptions.c (print_flush): Handle a NULL target_stack. * regcache.c (target_ops_no_register): Refactor as class with virtual methods. * exec.c (exec_target): New class. (exec_ops): Now an exec_target. (exec_open, exec_close_1, exec_get_section_table) (exec_xfer_partial, exec_files_info, exec_has_memory) (exec_make_note_section): Refactor as exec_target methods. (exec_file_clear, ignore, exec_remove_breakpoint, init_exec_ops): Delete. (exec_target::find_memory_regions): New. (_initialize_exec): Don't call init_exec_ops. * gdbcore.h (exec_file_clear): Delete. * corefile.c (core_target): Delete. (core_file_command): Adjust. * corelow.c (core_target): New class. (the_core_target): New. (core_close): Remove target_ops parameter. (core_close_cleanup): Adjust. (core_target::close): New. (core_open, core_detach, get_core_registers, core_files_info) (core_xfer_partial, core_thread_alive, core_read_description) (core_pid_to_str, core_thread_name, core_has_memory) (core_has_stack, core_has_registers, core_info_proc): Rework as core_target methods. (ignore, core_remove_breakpoint, init_core_ops): Delete. (_initialize_corelow): Initialize the_core_target. * gdbcore.h (core_target): Delete. (the_core_target): New. * ctf.c: (ctf_target): New class. (ctf_ops): Now a ctf_target. (ctf_open, ctf_close, ctf_files_info, ctf_fetch_registers) (ctf_xfer_partial, ctf_get_trace_state_variable_value) (ctf_trace_find, ctf_traceframe_info): Refactor as ctf_target methods. (init_ctf_ops): Delete. (_initialize_ctf): Don't call it. * tracefile-tfile.c (tfile_target): New class. (tfile_ops): Now a tfile_target. (tfile_open, tfile_close, tfile_files_info) (tfile_get_tracepoint_status, tfile_trace_find) (tfile_fetch_registers, tfile_xfer_partial) (tfile_get_trace_state_variable_value, tfile_traceframe_info): Refactor as tfile_target methods. (tfile_xfer_partial_features): Remove target_ops parameter. (init_tfile_ops): Delete. (_initialize_tracefile_tfile): Don't call it. * tracefile.c (tracefile_has_all_memory, tracefile_has_memory) (tracefile_has_stack, tracefile_has_registers) (tracefile_thread_alive, tracefile_get_trace_status): Refactor as tracefile_target methods. (init_tracefile_ops): Delete. (tracefile_target::tracefile_target): New. * tracefile.h: Include "target.h". (tracefile_target): New class. (init_tracefile_ops): Delete. * spu-multiarch.c (spu_multiarch_target): New class. (spu_ops): Now a spu_multiarch_target. (spu_thread_architecture, spu_region_ok_for_hw_watchpoint) (spu_fetch_registers, spu_store_registers, spu_xfer_partial) (spu_search_memory, spu_mourn_inferior): Refactor as spu_multiarch_target methods. (init_spu_ops): Delete. (_initialize_spu_multiarch): Remove references to init_spu_ops, complete_target_initialization. * ravenscar-thread.c (ravenscar_thread_target): New class. (ravenscar_ops): Now a ravenscar_thread_target. (ravenscar_resume, ravenscar_wait, ravenscar_update_thread_list) (ravenscar_thread_alive, ravenscar_pid_to_str) (ravenscar_fetch_registers, ravenscar_store_registers) (ravenscar_prepare_to_store, ravenscar_stopped_by_sw_breakpoint) (ravenscar_stopped_by_hw_breakpoint) (ravenscar_stopped_by_watchpoint, ravenscar_stopped_data_address) (ravenscar_mourn_inferior, ravenscar_core_of_thread) (ravenscar_get_ada_task_ptid): Refactor as ravenscar_thread_target methods. (init_ravenscar_thread_ops): Delete. (_initialize_ravenscar): Remove references to init_ravenscar_thread_ops and complete_target_initialization. * bsd-uthread.c (bsd_uthread_ops_hack): Delete. (bsd_uthread_target): New class. (bsd_uthread_ops): Now a bsd_uthread_target. (bsd_uthread_activate): Adjust to refer to bsd_uthread_ops. (bsd_uthread_close, bsd_uthread_mourn_inferior) (bsd_uthread_fetch_registers, bsd_uthread_store_registers) (bsd_uthread_wait, bsd_uthread_resume, bsd_uthread_thread_alive) (bsd_uthread_update_thread_list, bsd_uthread_extra_thread_info) (bsd_uthread_pid_to_str): Refactor as bsd_uthread_target methods. (bsd_uthread_target): Delete function. (_initialize_bsd_uthread): Remove reference to complete_target_initialization. * bfd-target.c (target_bfd_data): Delete. Fields folded into ... (target_bfd): ... this new class. (target_bfd_xfer_partial, target_bfd_get_section_table) (target_bfd_close): Refactor as target_bfd methods. (target_bfd::~target_bfd): New. (target_bfd_reopen): Adjust. (target_bfd::close): New. * record-btrace.c (record_btrace_target): New class. (record_btrace_ops): Now a record_btrace_target. (record_btrace_open, record_btrace_stop_recording) (record_btrace_disconnect, record_btrace_close) (record_btrace_async, record_btrace_info) (record_btrace_insn_history, record_btrace_insn_history_range) (record_btrace_insn_history_from, record_btrace_call_history) (record_btrace_call_history_range) (record_btrace_call_history_from, record_btrace_record_method) (record_btrace_is_replaying, record_btrace_will_replay) (record_btrace_xfer_partial, record_btrace_insert_breakpoint) (record_btrace_remove_breakpoint, record_btrace_fetch_registers) (record_btrace_store_registers, record_btrace_prepare_to_store) (record_btrace_to_get_unwinder) (record_btrace_to_get_tailcall_unwinder, record_btrace_resume) (record_btrace_commit_resume, record_btrace_wait) (record_btrace_stop, record_btrace_can_execute_reverse) (record_btrace_stopped_by_sw_breakpoint) (record_btrace_supports_stopped_by_sw_breakpoint) (record_btrace_stopped_by_hw_breakpoint) (record_btrace_supports_stopped_by_hw_breakpoint) (record_btrace_update_thread_list, record_btrace_thread_alive) (record_btrace_goto_begin, record_btrace_goto_end) (record_btrace_goto, record_btrace_stop_replaying_all) (record_btrace_execution_direction) (record_btrace_prepare_to_generate_core) (record_btrace_done_generating_core): Refactor as record_btrace_target methods. (init_record_btrace_ops): Delete. (_initialize_record_btrace): Remove reference to init_record_btrace_ops. * record-full.c (RECORD_FULL_IS_REPLAY): Adjust to always refer to the execution_direction global. (record_full_base_target, record_full_target) (record_full_core_target): New classes. (record_full_ops): Now a record_full_target. (record_full_core_ops): Now a record_full_core_target. (record_full_target::detach, record_full_target::disconnect) (record_full_core_target::disconnect) (record_full_target::mourn_inferior, record_full_target::kill): New. (record_full_open, record_full_close, record_full_async): Refactor as methods of the record_full_base_target class. (record_full_resume, record_full_commit_resume): Refactor as methods of the record_full_target class. (record_full_wait, record_full_stopped_by_watchpoint) (record_full_stopped_data_address) (record_full_stopped_by_sw_breakpoint) (record_full_supports_stopped_by_sw_breakpoint) (record_full_stopped_by_hw_breakpoint) (record_full_supports_stopped_by_hw_breakpoint): Refactor as methods of the record_full_base_target class. (record_full_store_registers, record_full_xfer_partial) (record_full_insert_breakpoint, record_full_remove_breakpoint): Refactor as methods of the record_full_target class. (record_full_can_execute_reverse, record_full_get_bookmark) (record_full_goto_bookmark, record_full_execution_direction) (record_full_record_method, record_full_info, record_full_delete) (record_full_is_replaying, record_full_will_replay) (record_full_goto_begin, record_full_goto_end, record_full_goto) (record_full_stop_replaying): Refactor as methods of the record_full_base_target class. (record_full_core_resume, record_full_core_kill) (record_full_core_fetch_registers) (record_full_core_prepare_to_store) (record_full_core_store_registers, record_full_core_xfer_partial) (record_full_core_insert_breakpoint) (record_full_core_remove_breakpoint) (record_full_core_has_execution): Refactor as methods of the record_full_core_target class. (record_full_base_target::supports_delete_record): New. (init_record_full_ops): Delete. (init_record_full_core_ops): Delete. (record_full_save): Refactor as method of the record_full_base_target class. (_initialize_record_full): Remove references to init_record_full_ops and init_record_full_core_ops. * remote.c (remote_target, extended_remote_target): New classes. (remote_ops): Now a remote_target. (extended_remote_ops): Now an extended_remote_target. (remote_insert_fork_catchpoint, remote_remove_fork_catchpoint) (remote_insert_vfork_catchpoint, remote_remove_vfork_catchpoint) (remote_insert_exec_catchpoint, remote_remove_exec_catchpoint) (remote_pass_signals, remote_set_syscall_catchpoint) (remote_program_signals, ) (remote_thread_always_alive): Remove target_ops parameter. (remote_thread_alive, remote_thread_name) (remote_update_thread_list, remote_threads_extra_info) (remote_static_tracepoint_marker_at) (remote_static_tracepoint_markers_by_strid) (remote_get_ada_task_ptid, remote_close, remote_start_remote) (remote_open): Refactor as methods of remote_target. (extended_remote_open, extended_remote_detach) (extended_remote_attach, extended_remote_post_attach): (extended_remote_supports_disable_randomization) (extended_remote_create_inferior): : Refactor as method of extended_remote_target. (remote_set_permissions, remote_open_1, remote_detach) (remote_follow_fork, remote_follow_exec, remote_disconnect) (remote_resume, remote_commit_resume, remote_stop) (remote_interrupt, remote_pass_ctrlc, remote_terminal_inferior) (remote_terminal_ours, remote_wait, remote_fetch_registers) (remote_prepare_to_store, remote_store_registers) (remote_flash_erase, remote_flash_done, remote_files_info) (remote_kill, remote_mourn, remote_insert_breakpoint) (remote_remove_breakpoint, remote_insert_watchpoint) (remote_watchpoint_addr_within_range) (remote_remove_watchpoint, remote_region_ok_for_hw_watchpoint) (remote_check_watch_resources, remote_stopped_by_sw_breakpoint) (remote_supports_stopped_by_sw_breakpoint) (remote_stopped_by_hw_breakpoint) (remote_supports_stopped_by_hw_breakpoint) (remote_stopped_by_watchpoint, remote_stopped_data_address) (remote_insert_hw_breakpoint, remote_remove_hw_breakpoint) (remote_verify_memory): Refactor as methods of remote_target. (remote_write_qxfer, remote_read_qxfer): Remove target_ops parameter. (remote_xfer_partial, remote_get_memory_xfer_limit) (remote_search_memory, remote_rcmd, remote_memory_map) (remote_pid_to_str, remote_get_thread_local_address) (remote_get_tib_address, remote_read_description): Refactor as methods of remote_target. (remote_target::fileio_open, remote_target::fileio_pwrite) (remote_target::fileio_pread, remote_target::fileio_close): New. (remote_hostio_readlink, remote_hostio_fstat) (remote_filesystem_is_local, remote_can_execute_reverse) (remote_supports_non_stop, remote_supports_disable_randomization) (remote_supports_multi_process, remote_supports_cond_breakpoints) (remote_supports_enable_disable_tracepoint) (remote_supports_string_tracing) (remote_can_run_breakpoint_commands, remote_trace_init) (remote_download_tracepoint, remote_can_download_tracepoint) (remote_download_trace_state_variable, remote_enable_tracepoint) (remote_disable_tracepoint, remote_trace_set_readonly_regions) (remote_trace_start, remote_get_trace_status) (remote_get_tracepoint_status, remote_trace_stop) (remote_trace_find, remote_get_trace_state_variable_value) (remote_save_trace_data, remote_get_raw_trace_data) (remote_set_disconnected_tracing, remote_core_of_thread) (remote_set_circular_trace_buffer, remote_traceframe_info) (remote_get_min_fast_tracepoint_insn_len) (remote_set_trace_buffer_size, remote_set_trace_notes) (remote_use_agent, remote_can_use_agent, remote_enable_btrace) (remote_disable_btrace, remote_teardown_btrace) (remote_read_btrace, remote_btrace_conf) (remote_augmented_libraries_svr4_read, remote_load) (remote_pid_to_exec_file, remote_can_do_single_step) (remote_execution_direction, remote_thread_handle_to_thread_info): Refactor as methods of remote_target. (init_remote_ops, init_extended_remote_ops): Delete. (remote_can_async_p, remote_is_async_p, remote_async) (remote_thread_events, remote_upload_tracepoints) (remote_upload_trace_state_variables): Refactor as methods of remote_target. (_initialize_remote): Remove references to init_remote_ops and init_extended_remote_ops. * remote-sim.c (gdbsim_target): New class. (gdbsim_fetch_register, gdbsim_store_register, gdbsim_kill) (gdbsim_load, gdbsim_create_inferior, gdbsim_open, gdbsim_close) (gdbsim_detach, gdbsim_resume, gdbsim_interrupt) (gdbsim_wait, gdbsim_prepare_to_store, gdbsim_xfer_partial) (gdbsim_files_info, gdbsim_mourn_inferior, gdbsim_thread_alive) (gdbsim_pid_to_str, gdbsim_has_all_memory, gdbsim_has_memory): Refactor as methods of gdbsim_target. (gdbsim_ops): Now a gdbsim_target. (init_gdbsim_ops): Delete. (gdbsim_cntrl_c): Adjust. (_initialize_remote_sim): Remove reference to init_gdbsim_ops. * amd64-linux-nat.c (amd64_linux_nat_target): New class. (the_amd64_linux_nat_target): New. (amd64_linux_fetch_inferior_registers) (amd64_linux_store_inferior_registers): Refactor as methods of amd64_linux_nat_target. (_initialize_amd64_linux_nat): Adjust. Set linux_target. * i386-linux-nat.c: Don't include "linux-nat.h". (i386_linux_nat_target): New class. (the_i386_linux_nat_target): New. (i386_linux_fetch_inferior_registers) (i386_linux_store_inferior_registers, i386_linux_resume): Refactor as methods of i386_linux_nat_target. (_initialize_i386_linux_nat): Adjust. Set linux_target. * inf-child.c (inf_child_ops): Delete. (inf_child_fetch_inferior_registers) (inf_child_store_inferior_registers): Delete. (inf_child_post_attach, inf_child_prepare_to_store): Refactor as methods of inf_child_target. (inf_child_target::supports_terminal_ours) (inf_child_target::terminal_init) (inf_child_target::terminal_inferior) (inf_child_target::terminal_ours_for_output) (inf_child_target::terminal_ours, inf_child_target::interrupt) (inf_child_target::pass_ctrlc, inf_child_target::terminal_info): New. (inf_child_open, inf_child_disconnect, inf_child_close) (inf_child_mourn_inferior, inf_child_maybe_unpush_target) (inf_child_post_startup_inferior, inf_child_can_run) (inf_child_pid_to_exec_file): Refactor as methods of inf_child_target. (inf_child_follow_fork): Delete. (inf_child_target::can_create_inferior) (inf_child_target::can_attach): New. (inf_child_target::has_all_memory, inf_child_target::has_memory) (inf_child_target::has_stack, inf_child_target::has_registers) (inf_child_target::has_execution): New. (inf_child_fileio_open, inf_child_fileio_pwrite) (inf_child_fileio_pread, inf_child_fileio_fstat) (inf_child_fileio_close, inf_child_fileio_unlink) (inf_child_fileio_readlink, inf_child_use_agent) (inf_child_can_use_agent): Refactor as methods of inf_child_target. (return_zero, inf_child_target): Delete. (inf_child_target::inf_child_target): New. * inf-child.h: Include "target.h". (inf_child_target): Delete function prototype. (inf_child_target): New class. (inf_child_open_target, inf_child_mourn_inferior) (inf_child_maybe_unpush_target): Delete. * inf-ptrace.c (inf_ptrace_target::~inf_ptrace_target): New. (inf_ptrace_follow_fork, inf_ptrace_insert_fork_catchpoint) (inf_ptrace_remove_fork_catchpoint, inf_ptrace_create_inferior) (inf_ptrace_post_startup_inferior, inf_ptrace_mourn_inferior) (inf_ptrace_attach, inf_ptrace_post_attach, inf_ptrace_detach) (inf_ptrace_detach_success, inf_ptrace_kill, inf_ptrace_resume) (inf_ptrace_wait, inf_ptrace_xfer_partial) (inf_ptrace_thread_alive, inf_ptrace_files_info) (inf_ptrace_pid_to_str, inf_ptrace_auxv_parse): Refactor as methods of inf_ptrace_target. (inf_ptrace_target): Delete function. * inf-ptrace.h: Include "inf-child.h". (inf_ptrace_target): Delete function declaration. (inf_ptrace_target): New class. (inf_ptrace_trad_target, inf_ptrace_detach_success): Delete. * linux-nat.c (linux_target): New. (linux_ops, linux_ops_saved, super_xfer_partial): Delete. (linux_nat_target::~linux_nat_target): New. (linux_child_post_attach, linux_child_post_startup_inferior) (linux_child_follow_fork, linux_child_insert_fork_catchpoint) (linux_child_remove_fork_catchpoint) (linux_child_insert_vfork_catchpoint) (linux_child_remove_vfork_catchpoint) (linux_child_insert_exec_catchpoint) (linux_child_remove_exec_catchpoint) (linux_child_set_syscall_catchpoint, linux_nat_pass_signals) (linux_nat_create_inferior, linux_nat_attach, linux_nat_detach) (linux_nat_resume, linux_nat_stopped_by_watchpoint) (linux_nat_stopped_data_address) (linux_nat_stopped_by_sw_breakpoint) (linux_nat_supports_stopped_by_sw_breakpoint) (linux_nat_stopped_by_hw_breakpoint) (linux_nat_supports_stopped_by_hw_breakpoint, linux_nat_wait) (linux_nat_kill, linux_nat_mourn_inferior) (linux_nat_xfer_partial, linux_nat_thread_alive) (linux_nat_update_thread_list, linux_nat_pid_to_str) (linux_nat_thread_name, linux_child_pid_to_exec_file) (linux_child_static_tracepoint_markers_by_strid) (linux_nat_is_async_p, linux_nat_can_async_p) (linux_nat_supports_non_stop, linux_nat_always_non_stop_p) (linux_nat_supports_multi_process) (linux_nat_supports_disable_randomization, linux_nat_async) (linux_nat_stop, linux_nat_close, linux_nat_thread_address_space) (linux_nat_core_of_thread, linux_nat_filesystem_is_local) (linux_nat_fileio_open, linux_nat_fileio_readlink) (linux_nat_fileio_unlink, linux_nat_thread_events): Refactor as methods of linux_nat_target. (linux_nat_wait_1, linux_xfer_siginfo, linux_proc_xfer_partial) (linux_proc_xfer_spu, linux_nat_xfer_osdata): Remove target_ops parameter. (check_stopped_by_watchpoint): Adjust. (linux_xfer_partial): Delete. (linux_target_install_ops, linux_target, linux_nat_add_target): Delete. (linux_nat_target::linux_nat_target): New. * linux-nat.h: Include "inf-ptrace.h". (linux_nat_target): New. (linux_target, linux_target_install_ops, linux_nat_add_target): Delete function declarations. (linux_target): Declare global. * linux-thread-db.c (thread_db_target): New. (thread_db_target::thread_db_target): New. (thread_db_ops): Delete. (the_thread_db_target): New. (thread_db_detach, thread_db_wait, thread_db_mourn_inferior) (thread_db_update_thread_list, thread_db_pid_to_str) (thread_db_extra_thread_info) (thread_db_thread_handle_to_thread_info) (thread_db_get_thread_local_address, thread_db_get_ada_task_ptid) (thread_db_resume): Refactor as methods of thread_db_target. (init_thread_db_ops): Delete. (_initialize_thread_db): Remove reference to init_thread_db_ops. * x86-linux-nat.c: Don't include "linux-nat.h". (super_post_startup_inferior): Delete. (x86_linux_nat_target::~x86_linux_nat_target): New. (x86_linux_child_post_startup_inferior) (x86_linux_read_description, x86_linux_enable_btrace) (x86_linux_disable_btrace, x86_linux_teardown_btrace) (x86_linux_read_btrace, x86_linux_btrace_conf): Refactor as methods of x86_linux_nat_target. (x86_linux_create_target): Delete. Bits folded ... (x86_linux_add_target): ... here. Now takes a linux_nat_target pointer. * x86-linux-nat.h: Include "linux-nat.h" and "x86-nat.h". (x86_linux_nat_target): New class. (x86_linux_create_target): Delete. (x86_linux_add_target): Now takes a linux_nat_target pointer. * x86-nat.c (x86_insert_watchpoint, x86_remove_watchpoint) (x86_region_ok_for_watchpoint, x86_stopped_data_address) (x86_stopped_by_watchpoint, x86_insert_hw_breakpoint) (x86_remove_hw_breakpoint, x86_can_use_hw_breakpoint) (x86_stopped_by_hw_breakpoint): Remove target_ops parameter and make extern. (x86_use_watchpoints): Delete. * x86-nat.h: Include "breakpoint.h" and "target.h". (x86_use_watchpoints): Delete. (x86_can_use_hw_breakpoint, x86_region_ok_for_hw_watchpoint) (x86_stopped_by_watchpoint, x86_stopped_data_address) (x86_insert_watchpoint, x86_remove_watchpoint) (x86_insert_hw_breakpoint, x86_remove_hw_breakpoint) (x86_stopped_by_hw_breakpoint): New declarations. (x86_nat_target): New template class. * ppc-linux-nat.c (ppc_linux_nat_target): New class. (the_ppc_linux_nat_target): New. (ppc_linux_fetch_inferior_registers) (ppc_linux_can_use_hw_breakpoint) (ppc_linux_region_ok_for_hw_watchpoint) (ppc_linux_ranged_break_num_registers) (ppc_linux_insert_hw_breakpoint, ppc_linux_remove_hw_breakpoint) (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_can_accel_watchpoint_condition) (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint) (ppc_linux_stopped_data_address, ppc_linux_stopped_by_watchpoint) (ppc_linux_watchpoint_addr_within_range) (ppc_linux_masked_watch_num_registers) (ppc_linux_store_inferior_registers, ppc_linux_auxv_parse) (ppc_linux_read_description): Refactor as methods of ppc_linux_nat_target. (_initialize_ppc_linux_nat): Adjust. Set linux_target. * procfs.c (procfs_xfer_partial): Delete forward declaration. (procfs_target): New class. (the_procfs_target): New. (procfs_target): Delete function. (procfs_auxv_parse, procfs_attach, procfs_detach) (procfs_fetch_registers, procfs_store_registers, procfs_wait) (procfs_xfer_partial, procfs_resume, procfs_pass_signals) (procfs_files_info, procfs_kill_inferior, procfs_mourn_inferior) (procfs_create_inferior, procfs_update_thread_list) (procfs_thread_alive, procfs_pid_to_str) (procfs_can_use_hw_breakpoint, procfs_stopped_by_watchpoint) (procfs_stopped_data_address, procfs_insert_watchpoint) (procfs_remove_watchpoint, procfs_region_ok_for_hw_watchpoint) (proc_find_memory_regions, procfs_info_proc) (procfs_make_note_section): Refactor as methods of procfs_target. (_initialize_procfs): Adjust. * sol-thread.c (sol_thread_target): New class. (sol_thread_ops): Now a sol_thread_target. (sol_thread_detach, sol_thread_resume, sol_thread_wait) (sol_thread_fetch_registers, sol_thread_store_registers) (sol_thread_xfer_partial, sol_thread_mourn_inferior) (sol_thread_alive, solaris_pid_to_str, sol_update_thread_list) (sol_get_ada_task_ptid): Refactor as methods of sol_thread_target. (init_sol_thread_ops): Delete. (_initialize_sol_thread): Adjust. Remove references to init_sol_thread_ops and complete_target_initialization. * windows-nat.c (windows_nat_target): New class. (windows_fetch_inferior_registers) (windows_store_inferior_registers, windows_resume, windows_wait) (windows_attach, windows_detach, windows_pid_to_exec_file) (windows_files_info, windows_create_inferior) (windows_mourn_inferior, windows_interrupt, windows_kill_inferior) (windows_close, windows_pid_to_str, windows_xfer_partial) (windows_get_tib_address, windows_get_ada_task_ptid) (windows_thread_name, windows_thread_alive): Refactor as windows_nat_target methods. (do_initial_windows_stuff): Adjust. (windows_target): Delete function. (_initialize_windows_nat): Adjust. * darwin-nat.c (darwin_resume, darwin_wait_to, darwin_interrupt) (darwin_mourn_inferior, darwin_kill_inferior) (darwin_create_inferior, darwin_attach, darwin_detach) (darwin_pid_to_str, darwin_thread_alive, darwin_xfer_partial) (darwin_pid_to_exec_file, darwin_get_ada_task_ptid) (darwin_supports_multi_process): Refactor as darwin_nat_target methods. (darwin_resume_to, darwin_files_info): Delete. (_initialize_darwin_inferior): Rename to ... (_initialize_darwin_nat): ... this. Adjust to C++ification. * darwin-nat.h: Include "inf-child.h". (darwin_nat_target): New class. (darwin_complete_target): Delete. * i386-darwin-nat.c (i386_darwin_nat_target): New class. (darwin_target): New. (i386_darwin_fetch_inferior_registers) (i386_darwin_store_inferior_registers): Refactor as methods of darwin_nat_target. (darwin_complete_target): Delete, with ... (_initialize_i386_darwin_nat): ... bits factored out here. * alpha-linux-nat.c (alpha_linux_nat_target): New class. (the_alpha_linux_nat_target): New. (alpha_linux_register_u_offset): Refactor as alpha_linux_nat_target method. (_initialize_alpha_linux_nat): Adjust. * linux-nat-trad.c (inf_ptrace_register_u_offset): Delete. (inf_ptrace_fetch_register, inf_ptrace_fetch_registers) (inf_ptrace_store_register, inf_ptrace_store_registers): Refact as methods of linux_nat_trad_target. (linux_trad_target): Delete. * linux-nat-trad.h (linux_trad_target): Delete function. (linux_nat_trad_target): New class. * mips-linux-nat.c (mips_linux_nat_target): New class. (super_fetch_registers, super_store_registers, super_close): Delete. (the_mips_linux_nat_target): New. (mips64_linux_regsets_fetch_registers) (mips64_linux_regsets_store_registers) (mips64_linux_fetch_registers, mips64_linux_store_registers) (mips_linux_register_u_offset, mips_linux_read_description) (mips_linux_can_use_hw_breakpoint) (mips_linux_stopped_by_watchpoint) (mips_linux_stopped_data_address) (mips_linux_region_ok_for_hw_watchpoint) (mips_linux_insert_watchpoint, mips_linux_remove_watchpoint) (mips_linux_close): Refactor as methods of mips_linux_nat. (_initialize_mips_linux_nat): Adjust to C++ification. * aix-thread.c (aix_thread_target): New class. (aix_thread_ops): Now an aix_thread_target. (aix_thread_detach, aix_thread_resume, aix_thread_wait) (aix_thread_fetch_registers, aix_thread_store_registers) (aix_thread_xfer_partial, aix_thread_mourn_inferior) (aix_thread_thread_alive, aix_thread_pid_to_str) (aix_thread_extra_thread_info, aix_thread_get_ada_task_ptid): Refactor as methods of aix_thread_target. (init_aix_thread_ops): Delete. (_initialize_aix_thread): Remove references to init_aix_thread_ops and complete_target_initialization. * rs6000-nat.c (rs6000_xfer_shared_libraries): Delete. (rs6000_nat_target): New class. (the_rs6000_nat_target): New. (rs6000_fetch_inferior_registers, rs6000_store_inferior_registers) (rs6000_xfer_partial, rs6000_wait, rs6000_create_inferior) (rs6000_xfer_shared_libraries): Refactor as rs6000_nat_target methods. (super_create_inferior): Delete. (_initialize_rs6000_nat): Adjust to C++ification. * arm-linux-nat.c (arm_linux_nat_target): New class. (the_arm_linux_nat_target): New. (arm_linux_fetch_inferior_registers) (arm_linux_store_inferior_registers, arm_linux_read_description) (arm_linux_can_use_hw_breakpoint, arm_linux_insert_hw_breakpoint) (arm_linux_remove_hw_breakpoint) (arm_linux_region_ok_for_hw_watchpoint) (arm_linux_insert_watchpoint, arm_linux_remove_watchpoint) (arm_linux_stopped_data_address, arm_linux_stopped_by_watchpoint) (arm_linux_watchpoint_addr_within_range): Refactor as methods of arm_linux_nat_target. (_initialize_arm_linux_nat): Adjust to C++ification. * aarch64-linux-nat.c (aarch64_linux_nat_target): New class. (the_aarch64_linux_nat_target): New. (aarch64_linux_fetch_inferior_registers) (aarch64_linux_store_inferior_registers) (aarch64_linux_child_post_startup_inferior) (aarch64_linux_read_description) (aarch64_linux_can_use_hw_breakpoint) (aarch64_linux_insert_hw_breakpoint) (aarch64_linux_remove_hw_breakpoint) (aarch64_linux_insert_watchpoint, aarch64_linux_remove_watchpoint) (aarch64_linux_region_ok_for_hw_watchpoint) (aarch64_linux_stopped_data_address) (aarch64_linux_stopped_by_watchpoint) (aarch64_linux_watchpoint_addr_within_range) (aarch64_linux_can_do_single_step): Refactor as methods of aarch64_linux_nat_target. (super_post_startup_inferior): Delete. (_initialize_aarch64_linux_nat): Adjust to C++ification. * hppa-linux-nat.c (hppa_linux_nat_target): New class. (the_hppa_linux_nat_target): New. (hppa_linux_fetch_inferior_registers) (hppa_linux_store_inferior_registers): Refactor as methods of hppa_linux_nat_target. (_initialize_hppa_linux_nat): Adjust to C++ification. * ia64-linux-nat.c (ia64_linux_nat_target): New class. (the_ia64_linux_nat_target): New. (ia64_linux_insert_watchpoint, ia64_linux_remove_watchpoint) (ia64_linux_stopped_data_address) (ia64_linux_stopped_by_watchpoint, ia64_linux_fetch_registers) (ia64_linux_store_registers, ia64_linux_xfer_partial): Refactor as ia64_linux_nat_target methods. (super_xfer_partial): Delete. (_initialize_ia64_linux_nat): Adjust to C++ification. * m32r-linux-nat.c (m32r_linux_nat_target): New class. (the_m32r_linux_nat_target): New. (m32r_linux_fetch_inferior_registers) (m32r_linux_store_inferior_registers): Refactor as m32r_linux_nat_target methods. (_initialize_m32r_linux_nat): Adjust to C++ification. * m68k-linux-nat.c (m68k_linux_nat_target): New class. (the_m68k_linux_nat_target): New. (m68k_linux_fetch_inferior_registers) (m68k_linux_store_inferior_registers): Refactor as m68k_linux_nat_target methods. (_initialize_m68k_linux_nat): Adjust to C++ification. * s390-linux-nat.c (s390_linux_nat_target): New class. (the_s390_linux_nat_target): New. (s390_linux_fetch_inferior_registers) (s390_linux_store_inferior_registers, s390_stopped_by_watchpoint) (s390_insert_watchpoint, s390_remove_watchpoint) (s390_can_use_hw_breakpoint, s390_insert_hw_breakpoint) (s390_remove_hw_breakpoint, s390_region_ok_for_hw_watchpoint) (s390_auxv_parse, s390_read_description): Refactor as methods of s390_linux_nat_target. (_initialize_s390_nat): Adjust to C++ification. * sparc-linux-nat.c (sparc_linux_nat_target): New class. (the_sparc_linux_nat_target): New. (_initialize_sparc_linux_nat): Adjust to C++ification. * sparc-nat.c (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc64-linux-nat.c (sparc64_linux_nat_target): New class. (the_sparc64_linux_nat_target): New. (_initialize_sparc64_linux_nat): Adjust to C++ification. * spu-linux-nat.c (spu_linux_nat_target): New class. (the_spu_linux_nat_target): New. (spu_child_post_startup_inferior, spu_child_post_attach) (spu_child_wait, spu_fetch_inferior_registers) (spu_store_inferior_registers, spu_xfer_partial) (spu_can_use_hw_breakpoint): Refactor as spu_linux_nat_target methods. (_initialize_spu_nat): Adjust to C++ification. * tilegx-linux-nat.c (tilegx_linux_nat_target): New class. (the_tilegx_linux_nat_target): New. (fetch_inferior_registers, store_inferior_registers): Refactor as methods. (_initialize_tile_linux_nat): Adjust to C++ification. * xtensa-linux-nat.c (xtensa_linux_nat_target): New class. (the_xtensa_linux_nat_target): New. (xtensa_linux_fetch_inferior_registers) (xtensa_linux_store_inferior_registers): Refactor as xtensa_linux_nat_target methods. (_initialize_xtensa_linux_nat): Adjust to C++ification. * fbsd-nat.c (USE_SIGTRAP_SIGINFO): Delete. (fbsd_pid_to_exec_file, fbsd_find_memory_regions) (fbsd_find_memory_regions, fbsd_info_proc, fbsd_xfer_partial) (fbsd_thread_alive, fbsd_pid_to_str, fbsd_thread_name) (fbsd_update_thread_list, fbsd_resume, fbsd_wait) (fbsd_stopped_by_sw_breakpoint) (fbsd_supports_stopped_by_sw_breakpoint, fbsd_follow_fork) (fbsd_insert_fork_catchpoint, fbsd_remove_fork_catchpoint) (fbsd_insert_vfork_catchpoint, fbsd_remove_vfork_catchpoint) (fbsd_post_startup_inferior, fbsd_post_attach) (fbsd_insert_exec_catchpoint, fbsd_remove_exec_catchpoint) (fbsd_set_syscall_catchpoint) (super_xfer_partial, super_resume, super_wait) (fbsd_supports_stopped_by_hw_breakpoint): Delete. (fbsd_handle_debug_trap): Remove target_ops parameter. (fbsd_nat_add_target): Delete. * fbsd-nat.h: Include "inf-ptrace.h". (fbsd_nat_add_target): Delete. (USE_SIGTRAP_SIGINFO): Define. (fbsd_nat_target): New class. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers) (amd64bsd_store_inferior_registers): Remove target_ops parameter. (amd64bsd_target): Delete. * amd64-bsd-nat.h: New file. * amd64-fbsd-nat.c: Include "amd64-bsd-nat.h" instead of "x86-bsd-nat.h". (amd64_fbsd_nat_target): New class. (the_amd64_fbsd_nat_target): New. (amd64fbsd_read_description): Refactor as method of amd64_fbsd_nat_target. (amd64_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_amd64fbsd_nat): Adjust to C++ification. * amd64-nat.h (amd64bsd_target): Delete function declaration. * i386-bsd-nat.c (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Remove target_ops parameter. (i386bsd_target): Delete. * i386-bsd-nat.h (i386bsd_target): Delete function declaration. (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Declare. (i386_bsd_nat_target): New class. * i386-fbsd-nat.c (i386_fbsd_nat_target): New class. (the_i386_fbsd_nat_target): New. (i386fbsd_resume, i386fbsd_read_description): Refactor as i386_fbsd_nat_target methods. (i386_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_i386fbsd_nat): Adjust to C++ification. * x86-bsd-nat.c (super_mourn_inferior): Delete. (x86bsd_mourn_inferior, x86bsd_target): Delete. (_initialize_x86_bsd_nat): Adjust to C++ification. * x86-bsd-nat.h: Include "x86-nat.h". (x86bsd_target): Delete declaration. (x86bsd_nat_target): New class. * aarch64-fbsd-nat.c (aarch64_fbsd_nat_target): New class. (the_aarch64_fbsd_nat_target): New. (aarch64_fbsd_fetch_inferior_registers) (aarch64_fbsd_store_inferior_registers): Refactor as methods of aarch64_fbsd_nat_target. (_initialize_aarch64_fbsd_nat): Adjust to C++ification. * alpha-bsd-nat.c (alpha_bsd_nat_target): New class. (the_alpha_bsd_nat_target): New. (alphabsd_fetch_inferior_registers) (alphabsd_store_inferior_registers): Refactor as alpha_bsd_nat_target methods. (_initialize_alphabsd_nat): Refactor as methods of alpha_bsd_nat_target. * amd64-nbsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_nbsd_nat_target): New. (_initialize_amd64nbsd_nat): Adjust to C++ification. * amd64-obsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_obsd_nat_target): New. (_initialize_amd64obsd_nat): Adjust to C++ification. * arm-fbsd-nat.c (arm_fbsd_nat_target): New. (the_arm_fbsd_nat_target): New. (arm_fbsd_fetch_inferior_registers) (arm_fbsd_store_inferior_registers, arm_fbsd_read_description): (_initialize_arm_fbsd_nat): Refactor as methods of arm_fbsd_nat_target. (_initialize_arm_fbsd_nat): Adjust to C++ification. * arm-nbsd-nat.c (arm_netbsd_nat_target): New class. (the_arm_netbsd_nat_target): New. (armnbsd_fetch_registers, armnbsd_store_registers): Refactor as arm_netbsd_nat_target. (_initialize_arm_netbsd_nat): Adjust to C++ification. * hppa-nbsd-nat.c (hppa_nbsd_nat_target): New class. (the_hppa_nbsd_nat_target): New. (hppanbsd_fetch_registers, hppanbsd_store_registers): Refactor as hppa_nbsd_nat_target methods. (_initialize_hppanbsd_nat): Adjust to C++ification. * hppa-obsd-nat.c (hppa_obsd_nat_target): New class. (the_hppa_obsd_nat_target): New. (hppaobsd_fetch_registers, hppaobsd_store_registers): Refactor as methods of hppa_obsd_nat_target. (_initialize_hppaobsd_nat): Adjust to C++ification. Use add_target. * i386-nbsd-nat.c (the_i386_nbsd_nat_target): New. (_initialize_i386nbsd_nat): Adjust to C++ification. Use add_target. * i386-obsd-nat.c (the_i386_obsd_nat_target): New. (_initialize_i386obsd_nat): Use add_target. * m68k-bsd-nat.c (m68k_bsd_nat_target): New class. (the_m68k_bsd_nat_target): New. (m68kbsd_fetch_inferior_registers) (m68kbsd_store_inferior_registers): Refactor as methods of m68k_bsd_nat_target. (_initialize_m68kbsd_nat): Adjust to C++ification. * mips-fbsd-nat.c (mips_fbsd_nat_target): New class. (the_mips_fbsd_nat_target): New. (mips_fbsd_fetch_inferior_registers) (mips_fbsd_store_inferior_registers): Refactor as methods of mips_fbsd_nat_target. (_initialize_mips_fbsd_nat): Adjust to C++ification. Use add_target. * mips-nbsd-nat.c (mips_nbsd_nat_target): New class. (the_mips_nbsd_nat_target): New. (mipsnbsd_fetch_inferior_registers) (mipsnbsd_store_inferior_registers): Refactor as methods of mips_nbsd_nat_target. (_initialize_mipsnbsd_nat): Adjust to C++ification. * mips64-obsd-nat.c (mips64_obsd_nat_target): New class. (the_mips64_obsd_nat_target): New. (mips64obsd_fetch_inferior_registers) (mips64obsd_store_inferior_registers): Refactor as methods of mips64_obsd_nat_target. (_initialize_mips64obsd_nat): Adjust to C++ification. Use add_target. * nbsd-nat.c (nbsd_pid_to_exec_file): Refactor as method of nbsd_nat_target. * nbsd-nat.h: Include "inf-ptrace.h". (nbsd_nat_target): New class. * obsd-nat.c (obsd_pid_to_str, obsd_update_thread_list) (obsd_wait): Refactor as methods of obsd_nat_target. (obsd_add_target): Delete. * obsd-nat.h: Include "inf-ptrace.h". (obsd_nat_target): New class. * ppc-fbsd-nat.c (ppc_fbsd_nat_target): New class. (the_ppc_fbsd_nat_target): New. (ppcfbsd_fetch_inferior_registers) (ppcfbsd_store_inferior_registers): Refactor as methods of ppc_fbsd_nat_target. (_initialize_ppcfbsd_nat): Adjust to C++ification. Use add_target. * ppc-nbsd-nat.c (ppc_nbsd_nat_target): New class. (the_ppc_nbsd_nat_target): New. (ppcnbsd_fetch_inferior_registers) (ppcnbsd_store_inferior_registers): Refactor as methods of ppc_nbsd_nat_target. (_initialize_ppcnbsd_nat): Adjust to C++ification. * ppc-obsd-nat.c (ppc_obsd_nat_target): New class. (the_ppc_obsd_nat_target): New. (ppcobsd_fetch_registers, ppcobsd_store_registers): Refactor as methods of ppc_obsd_nat_target. (_initialize_ppcobsd_nat): Adjust to C++ification. Use add_target. * sh-nbsd-nat.c (sh_nbsd_nat_target): New class. (the_sh_nbsd_nat_target): New. (shnbsd_fetch_inferior_registers) (shnbsd_store_inferior_registers): Refactor as methods of sh_nbsd_nat_target. (_initialize_shnbsd_nat): Adjust to C++ification. * sparc-nat.c (sparc_xfer_wcookie): Make extern. (inf_ptrace_xfer_partial): Delete. (sparc_xfer_partial, sparc_target): Delete. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers, sparc_xfer_wcookie): Declare. (sparc_target): Delete function declaration. (sparc_target): New template class. * sparc-nbsd-nat.c (the_sparc_nbsd_nat_target): New. (_initialize_sparcnbsd_nat): Adjust to C++ification. * sparc64-fbsd-nat.c (the_sparc64_fbsd_nat_target): New. (_initialize_sparc64fbsd_nat): Adjust to C++ification. Use add_target. * sparc64-nbsd-nat.c (the_sparc64_nbsd_nat_target): New. (_initialize_sparc64nbsd_nat): Adjust to C++ification. * sparc64-obsd-nat.c (the_sparc64_obsd_nat_target): New. (_initialize_sparc64obsd_nat): Adjust to C++ification. Use add_target. * vax-bsd-nat.c (vax_bsd_nat_target): New class. (the_vax_bsd_nat_target): New. (vaxbsd_fetch_inferior_registers) (vaxbsd_store_inferior_registers): Refactor as vax_bsd_nat_target methods. (_initialize_vaxbsd_nat): Adjust to C++ification. * bsd-kvm.c (bsd_kvm_target): New class. (bsd_kvm_ops): Now a bsd_kvm_target. (bsd_kvm_open, bsd_kvm_close, bsd_kvm_xfer_partial) (bsd_kvm_files_info, bsd_kvm_fetch_registers) (bsd_kvm_thread_alive, bsd_kvm_pid_to_str): Refactor as methods of bsd_kvm_target. (bsd_kvm_return_one): Delete. (bsd_kvm_add_target): Adjust to C++ification. * nto-procfs.c (nto_procfs_target, nto_procfs_target_native) (nto_procfs_target_procfs): New classes. (procfs_open_1, procfs_thread_alive, procfs_update_thread_list) (procfs_files_info, procfs_pid_to_exec_file, procfs_attach) (procfs_post_attach, procfs_wait, procfs_fetch_registers) (procfs_xfer_partial, procfs_detach, procfs_insert_breakpoint) (procfs_remove_breakpoint, procfs_insert_hw_breakpoint) (procfs_remove_hw_breakpoint, procfs_resume) (procfs_mourn_inferior, procfs_create_inferior, procfs_interrupt) (procfs_kill_inferior, procfs_store_registers) (procfs_pass_signals, procfs_pid_to_str, procfs_can_run): Refactor as methods of nto_procfs_target. (nto_procfs_ops): Now an nto_procfs_target_procfs. (nto_native_ops): Delete. (procfs_open, procfs_native_open): Delete. (nto_native_ops): Now an nto_procfs_target_native. (init_procfs_targets): Adjust to C++ification. (procfs_can_use_hw_breakpoint, procfs_remove_hw_watchpoint) (procfs_insert_hw_watchpoint, procfs_stopped_by_watchpoint): Refactor as methods of nto_procfs_target. * go32-nat.c (go32_nat_target): New class. (the_go32_nat_target): New. (go32_attach, go32_resume, go32_wait, go32_fetch_registers) (go32_store_registers, go32_xfer_partial, go32_files_info) (go32_kill_inferior, go32_create_inferior, go32_mourn_inferior) (go32_terminal_init, go32_terminal_info, go32_terminal_inferior) (go32_terminal_ours, go32_pass_ctrlc, go32_thread_alive) (go32_pid_to_str): Refactor as methods of go32_nat_target. (go32_target): Delete. (_initialize_go32_nat): Adjust to C++ification. * gnu-nat.c (gnu_wait, gnu_resume, gnu_kill_inferior) (gnu_mourn_inferior, gnu_create_inferior, gnu_attach, gnu_detach) (gnu_stop, gnu_thread_alive, gnu_xfer_partial) (gnu_find_memory_regions, gnu_pid_to_str): Refactor as methods of gnu_nat_target. (gnu_target): Delete. * gnu-nat.h (gnu_target): Delete. (gnu_nat_target): New class. * i386-gnu-nat.c (gnu_base_target): New. (i386_gnu_nat_target): New class. (the_i386_gnu_nat_target): New. (_initialize_i386gnu_nat): Adjust to C++ification. gdb/testsuite/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * gdb.base/breakpoint-in-ro-region.exp: Adjust to to_resume and to_log_command renames. * gdb.base/sss-bp-on-user-bp-2.exp: Likewise.
2018-05-03 07:37:22 +08:00
int
ppc_linux_nat_target::ranged_break_num_registers ()
2011-03-31 Thiago Jung Bauermann <bauerman@br.ibm.com> Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Implement support for PowerPC BookE ranged breakpoints. gdb/ * NEWS: Mention support for ranged breakpoints on embedded PowerPC. * breakpoint.h (struct bp_target_info) <length>: New member variable. (struct breakpoint_ops) <breakpoint_hit>: Take struct bp_location instead of struct breakpoint as argument, and also add ASPACE and BP_ADDR arguments. Update all callers. (struct breakpoint_ops) <print_one_detail>: New method. (struct breakpoint) <addr_string_range_end>: New member variable. * breakpoint.c (breakpoint_location_address_match): Add function prototype. (insert_bp_location): Set bl->target_info.length. (breakpoint_here_p): Call breakpoint_location_address_match. (moribund_breakpoint_here_p): Likewise. (regular_breakpoint_inserted_here_p): Likewise. (breakpoint_thread_match): Likewise. (bpstat_stop_status): Likewise. (bpstat_check_location): Move call to breakpoint_ops.breakpoint_hit to the top. (print_one_breakpoint_location): Call breakpoint_ops.print_one_detail if available. (breakpoint_address_match_range): New function. (breakpoint_location_address_match): Likewise. (breakpoint_locations_match): Compare the length field of the locations too. (hw_breakpoint_used_count): Count resources used by all locations in a breakpoint, and use breakpoint_ops.resources_needed if available. (breakpoint_hit_ranged_breakpoint): New function. (resources_needed_ranged_breakpoint): Likewise. (print_it_ranged_breakpoint): Likewise. (print_one_ranged_breakpoint): Likewise. (print_one_detail_ranged_breakpoint): Likewise. (print_mention_ranged_breakpoint): Likewise. (print_recreate_ranged_breakpoint): Likewise. (ranged_breakpoint_ops): New structure. (find_breakpoint_range_end): New function. (break_range_command): Likewise. (delete_breakpoint): Free addr_string_range_end. (update_breakpoint_locations): Add SALS_END argument. Update all callers. Calculate breakpoint length if a non-zero SALS_END is given. Call breakpoint_locations_match instead of breakpoint_address_match. (reset_breakpoint): Find SaL of the end of the range if B is a ranged breakpoint. (_initialize_breakpoint): Register break-range command. * defs.h (print_core_address): Add function prototype. * ppc-linux-nat.c (ppc_linux_ranged_break_num_registers): New function. (ppc_linux_insert_hw_breakpoint): Support ranged breakpoints. (ppc_linux_remove_hw_breakpoint): Likewise. (_initialize_ppc_linux_nat): Initialize to_ranged_break_num_registers. * target.c (update_current_target): Add comment about to_ranged_break_num_registers. (target_ranged_break_num_registers): New function. * target.h (struct target_ops) <to_ranged_break_num_registers>: New method. (target_ranged_break_num_registers): Add function prototype. * ui-out.c (ui_out_field_core_addr): Move address-printing logic to ... * utils.c (print_core_address): ... here. gdb/doc/ * gdb.texinfo (PowerPC Embedded): Document ranged breakpoints.
2011-03-31 22:32:49 +08:00
{
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
m_dreg_interface.detect (inferior_ptid);
return ((m_dreg_interface.hwdebug_p ()
&& (m_dreg_interface.hwdebug_info ().features
& PPC_DEBUG_FEATURE_INSN_BP_RANGE))?
2011-03-31 Thiago Jung Bauermann <bauerman@br.ibm.com> Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Implement support for PowerPC BookE ranged breakpoints. gdb/ * NEWS: Mention support for ranged breakpoints on embedded PowerPC. * breakpoint.h (struct bp_target_info) <length>: New member variable. (struct breakpoint_ops) <breakpoint_hit>: Take struct bp_location instead of struct breakpoint as argument, and also add ASPACE and BP_ADDR arguments. Update all callers. (struct breakpoint_ops) <print_one_detail>: New method. (struct breakpoint) <addr_string_range_end>: New member variable. * breakpoint.c (breakpoint_location_address_match): Add function prototype. (insert_bp_location): Set bl->target_info.length. (breakpoint_here_p): Call breakpoint_location_address_match. (moribund_breakpoint_here_p): Likewise. (regular_breakpoint_inserted_here_p): Likewise. (breakpoint_thread_match): Likewise. (bpstat_stop_status): Likewise. (bpstat_check_location): Move call to breakpoint_ops.breakpoint_hit to the top. (print_one_breakpoint_location): Call breakpoint_ops.print_one_detail if available. (breakpoint_address_match_range): New function. (breakpoint_location_address_match): Likewise. (breakpoint_locations_match): Compare the length field of the locations too. (hw_breakpoint_used_count): Count resources used by all locations in a breakpoint, and use breakpoint_ops.resources_needed if available. (breakpoint_hit_ranged_breakpoint): New function. (resources_needed_ranged_breakpoint): Likewise. (print_it_ranged_breakpoint): Likewise. (print_one_ranged_breakpoint): Likewise. (print_one_detail_ranged_breakpoint): Likewise. (print_mention_ranged_breakpoint): Likewise. (print_recreate_ranged_breakpoint): Likewise. (ranged_breakpoint_ops): New structure. (find_breakpoint_range_end): New function. (break_range_command): Likewise. (delete_breakpoint): Free addr_string_range_end. (update_breakpoint_locations): Add SALS_END argument. Update all callers. Calculate breakpoint length if a non-zero SALS_END is given. Call breakpoint_locations_match instead of breakpoint_address_match. (reset_breakpoint): Find SaL of the end of the range if B is a ranged breakpoint. (_initialize_breakpoint): Register break-range command. * defs.h (print_core_address): Add function prototype. * ppc-linux-nat.c (ppc_linux_ranged_break_num_registers): New function. (ppc_linux_insert_hw_breakpoint): Support ranged breakpoints. (ppc_linux_remove_hw_breakpoint): Likewise. (_initialize_ppc_linux_nat): Initialize to_ranged_break_num_registers. * target.c (update_current_target): Add comment about to_ranged_break_num_registers. (target_ranged_break_num_registers): New function. * target.h (struct target_ops) <to_ranged_break_num_registers>: New method. (target_ranged_break_num_registers): Add function prototype. * ui-out.c (ui_out_field_core_addr): Move address-printing logic to ... * utils.c (print_core_address): ... here. gdb/doc/ * gdb.texinfo (PowerPC Embedded): Document ranged breakpoints.
2011-03-31 22:32:49 +08:00
2 : -1);
}
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
/* Register the hardware breakpoint described by BP_TGT, to be inserted
when the threads of inferior_ptid are resumed. Returns 0 for success,
or -1 if the HWDEBUG interface that we need for hardware breakpoints
is not available. */
2011-03-31 Thiago Jung Bauermann <bauerman@br.ibm.com> Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Implement support for PowerPC BookE ranged breakpoints. gdb/ * NEWS: Mention support for ranged breakpoints on embedded PowerPC. * breakpoint.h (struct bp_target_info) <length>: New member variable. (struct breakpoint_ops) <breakpoint_hit>: Take struct bp_location instead of struct breakpoint as argument, and also add ASPACE and BP_ADDR arguments. Update all callers. (struct breakpoint_ops) <print_one_detail>: New method. (struct breakpoint) <addr_string_range_end>: New member variable. * breakpoint.c (breakpoint_location_address_match): Add function prototype. (insert_bp_location): Set bl->target_info.length. (breakpoint_here_p): Call breakpoint_location_address_match. (moribund_breakpoint_here_p): Likewise. (regular_breakpoint_inserted_here_p): Likewise. (breakpoint_thread_match): Likewise. (bpstat_stop_status): Likewise. (bpstat_check_location): Move call to breakpoint_ops.breakpoint_hit to the top. (print_one_breakpoint_location): Call breakpoint_ops.print_one_detail if available. (breakpoint_address_match_range): New function. (breakpoint_location_address_match): Likewise. (breakpoint_locations_match): Compare the length field of the locations too. (hw_breakpoint_used_count): Count resources used by all locations in a breakpoint, and use breakpoint_ops.resources_needed if available. (breakpoint_hit_ranged_breakpoint): New function. (resources_needed_ranged_breakpoint): Likewise. (print_it_ranged_breakpoint): Likewise. (print_one_ranged_breakpoint): Likewise. (print_one_detail_ranged_breakpoint): Likewise. (print_mention_ranged_breakpoint): Likewise. (print_recreate_ranged_breakpoint): Likewise. (ranged_breakpoint_ops): New structure. (find_breakpoint_range_end): New function. (break_range_command): Likewise. (delete_breakpoint): Free addr_string_range_end. (update_breakpoint_locations): Add SALS_END argument. Update all callers. Calculate breakpoint length if a non-zero SALS_END is given. Call breakpoint_locations_match instead of breakpoint_address_match. (reset_breakpoint): Find SaL of the end of the range if B is a ranged breakpoint. (_initialize_breakpoint): Register break-range command. * defs.h (print_core_address): Add function prototype. * ppc-linux-nat.c (ppc_linux_ranged_break_num_registers): New function. (ppc_linux_insert_hw_breakpoint): Support ranged breakpoints. (ppc_linux_remove_hw_breakpoint): Likewise. (_initialize_ppc_linux_nat): Initialize to_ranged_break_num_registers. * target.c (update_current_target): Add comment about to_ranged_break_num_registers. (target_ranged_break_num_registers): New function. * target.h (struct target_ops) <to_ranged_break_num_registers>: New method. (target_ranged_break_num_registers): Add function prototype. * ui-out.c (ui_out_field_core_addr): Move address-printing logic to ... * utils.c (print_core_address): ... here. gdb/doc/ * gdb.texinfo (PowerPC Embedded): Document ranged breakpoints.
2011-03-31 22:32:49 +08:00
Convert struct target_ops to C++ I.e., use C++ virtual methods and inheritance instead of tables of function pointers. Unfortunately, there's no way to do a smooth transition. ALL native targets in the tree must be converted at the same time. I've tested all I could with cross compilers and with help from GCC compile farm, but naturally I haven't been able to test many of the ports. Still, I made a best effort to port everything over, and while I expect some build problems due to typos and such, which should be trivial to fix, I don't expect any design problems. * Implementation notes: - The flattened current_target is gone. References to current_target or current_target.beneath are replaced with references to target_stack (the top of the stack) directly. - To keep "set debug target" working, this adds a new debug_stratum layer that sits on top of the stack, prints the debug, and delegates to the target beneath. In addition, this makes the shortname and longname properties of target_ops be virtual methods instead of data fields, and makes the debug target defer those to the target beneath. This is so that debug code sprinkled around that does "if (debugtarget) ..." can transparently print the name of the target beneath. A patch later in the series actually splits out the shortname/longname methods to a separate structure, but I preferred to keep that chance separate as it is associated with changing a bit the design of how targets are registered and open. - Since you can't check whether a C++ virtual method is overridden, the old method of checking whether a target_ops implements a method by comparing the function pointer must be replaced with something else. Some cases are fixed by adding a parallel "can_do_foo" target_ops methods. E.g.,: + for (t = target_stack; t != NULL; t = t->beneath) { - if (t->to_create_inferior != NULL) + if (t->can_create_inferior ()) break; } Others are fixed by changing void return type to bool or int return type, and have the default implementation return false or -1, to indicate lack of support. - make-target-delegates was adjusted to generate C++ classes and methods. It needed tweaks to grok "virtual" in front of the target method name, and for the fact that methods are no longer function pointers. (In particular, the current code parsing the return type was simple because it could simply parse up until the '(' in '(*to_foo)'. It now generates a couple C++ classes that inherit target_ops: dummy_target and debug_target. Since we need to generate the class declarations as well, i.e., we need to emit methods twice, we now generate the code in two passes. - The core_target global is renamed to avoid conflict with the "core_target" class. - ctf/tfile targets init_tracefile_ops is replaced by a base class that is inherited by both ctf and tfile. - bsd-uthread The bsd_uthread_ops_hack hack is gone. It's not needed because nothing was extending a target created by bsd_uthread_target. - remote/extended-remote targets This is a first pass, just enough to C++ify target_ops. A later pass will convert more free functions to methods, and make remote_state be truly per remote instance, allowing multiple simultaneous instances of remote targets. - inf-child/"native" is converted to an actual base class (inf_child_target), that is inherited by all native targets. - GNU/Linux The old weird double-target linux_ops mechanism in linux-nat.c, is gone, replaced by adding a few virtual methods to linux-nat.h's target_ops, called low_XXX, that the concrete linux-nat implementations override. Sort of like gdbserver's linux_target_ops, but simpler, for requiring only one target_ops-like hierarchy, which spares implementing the same method twice when we need to forward the method to a low implementation. The low target simply reimplements the target_ops method directly in that case. There are a few remaining linux-nat.c hooks that would be better converted to low_ methods like above too. E.g.: linux_nat_set_new_thread (t, x86_linux_new_thread); linux_nat_set_new_fork (t, x86_linux_new_fork); linux_nat_set_forget_process That'll be done in a follow up patch. - We can no longer use functions like x86_use_watchpoints to install custom methods on an arbitrary base target. The patch replaces instances of such a pattern with template mixins. For example memory_breakpoint_target defined in target.h, or x86_nat_target in x86-nat.h. - linux_trad_target, MIPS and Alpha GNU/Linux The code in the new linux-nat-trad.h/c files which was split off of inf-ptrace.h/c recently, is converted to a C++ base class, and used by the MIPS and Alpha GNU/Linux ports. - BSD targets The $architecture x NetBSD/OpenBSD/FreeBSD support matrix complicates things a bit. There's common BSD target code, and there's common architecture-specific code shared between the different BSDs. Currently, all that is stiched together to form a final target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target functions etc. This introduces new fbsd_nat_target, obsd_nat_target and nbsd_nat_target classes that serve as base/prototype target for the corresponding BSD variant. And introduces generic i386/AMD64 BSD targets, to be used as template mixin to build a final target. Similarly, a generic SPARC target is added, used by both BSD and Linux ports. - bsd_kvm_add_target, BSD libkvm target I considered making bsd_kvm_supply_pcb a virtual method, and then have each port inherit bsd_kvm_target and override that method, but that was resulting in lots of unjustified churn, so I left the function pointer mechanism alone. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> John Baldwin <jhb@freebsd.org> * target.h (enum strata) <debug_stratum>: New. (struct target_ops) <all delegation methods>: Replace by C++ virtual methods, and drop "to_" prefix. All references updated throughout. <to_shortname, to_longname, to_doc, to_data, to_have_steppable_watchpoint, to_have_continuable_watchpoint, to_has_thread_control, to_attach_no_wait>: Delete, replaced by virtual methods. All references updated throughout. <can_attach, supports_terminal_ours, can_create_inferior, get_thread_control_capabilities, attach_no_wait>: New virtual methods. <insert_breakpoint, remove_breakpoint>: Now TARGET_DEFAULT_NORETURN methods. <info_proc>: Now returns bool. <to_magic>: Delete. (OPS_MAGIC): Delete. (current_target): Delete. All references replaced by references to ... (target_stack): ... this. New. (target_shortname, target_longname): Adjust. (target_can_run): Now a function declaration. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (memory_breakpoint_target): New template class. (test_target_ops): Refactor as a C++ class with virtual methods. * make-target-delegates (NAME_PART): Tighten. (POINTER_PART, CP_SYMBOL): New. (SIMPLE_RETURN_PART): Reimplement. (VEC_RETURN_PART): Expect less. (RETURN_PART, VIRTUAL_PART): New. (METHOD): Adjust to C++ virtual methods. (scan_target_h): Remove reference to C99. (dname): Output "target_ops::" prefix. (write_function_header): Adjust to output a C++ class method. (write_declaration): New. (write_delegator): Adjust to output a C++ class method. (tdname): Output "dummy_target::" prefix. (write_tdefault, write_debugmethod): Adjust to output a C++ class method. (tdefault_names, debug_names): Delete. (return_types, tdefaults, styles, argtypes_array): New. (top level): All methods are delegators. (print_class): New. (top level): Print dummy_target and debug_target classes. * target-delegates.c: Regenerate. * target-debug.h (target_debug_print_enum_info_proc_what) (target_debug_print_thread_control_capabilities) (target_debug_print_thread_info_p): New. * target.c (dummy_target): Delete. (the_dummy_target, the_debug_target): New. (target_stack): Now extern. (set_targetdebug): Push/unpush debug target. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (add_target_with_completer): No longer call complete_target_initialization. (target_supports_terminal_ours): Use regular delegation. (update_current_target): Delete. (push_target): No longer check magic number. Don't call update_current_target. (unpush_target): Don't call update_current_target. (target_is_pushed): No longer check magic number. (target_require_runnable): Skip for all stratums over process_stratum. (target_ops::info_proc): New. (target_info_proc): Use find_target_at and find_default_run_target. (target_supports_disable_randomization): Use regular delegation. (target_get_osdata): Use find_target_at. (target_ops::open, target_ops::close, target_ops::can_attach) (target_ops::attach, target_ops::can_create_inferior) (target_ops::create_inferior, target_ops::can_run) (target_can_run): New. (default_fileio_target): Use regular delegation. (target_ops::fileio_open, target_ops::fileio_pwrite) (target_ops::fileio_pread, target_ops::fileio_fstat) (target_ops::fileio_close, target_ops::fileio_unlink) (target_ops::fileio_readlink): New. (target_fileio_open_1, target_fileio_unlink) (target_fileio_readlink): Always call the target method. Handle FILEIO_ENOSYS. (return_zero, return_zero_has_execution): Delete. (init_dummy_target): Delete. (dummy_target::dummy_target, dummy_target::shortname) (dummy_target::longname, dummy_target::doc) (debug_target::debug_target, debug_target::shortname) (debug_target::longname, debug_target::doc): New. (target_supports_delete_record): Use regular delegation. (setup_target_debug): Delete. (maintenance_print_target_stack): Skip debug_stratum. (initialize_targets): Instantiate the_dummy_target and the_debug_target. * auxv.c (target_auxv_parse): Remove 'ops' parameter. Adjust to use target_stack. (target_auxv_search, fprint_target_auxv): Adjust. (info_auxv_command): Adjust to use target_stack. * auxv.h (target_auxv_parse): Remove 'ops' parameter. * exceptions.c (print_flush): Handle a NULL target_stack. * regcache.c (target_ops_no_register): Refactor as class with virtual methods. * exec.c (exec_target): New class. (exec_ops): Now an exec_target. (exec_open, exec_close_1, exec_get_section_table) (exec_xfer_partial, exec_files_info, exec_has_memory) (exec_make_note_section): Refactor as exec_target methods. (exec_file_clear, ignore, exec_remove_breakpoint, init_exec_ops): Delete. (exec_target::find_memory_regions): New. (_initialize_exec): Don't call init_exec_ops. * gdbcore.h (exec_file_clear): Delete. * corefile.c (core_target): Delete. (core_file_command): Adjust. * corelow.c (core_target): New class. (the_core_target): New. (core_close): Remove target_ops parameter. (core_close_cleanup): Adjust. (core_target::close): New. (core_open, core_detach, get_core_registers, core_files_info) (core_xfer_partial, core_thread_alive, core_read_description) (core_pid_to_str, core_thread_name, core_has_memory) (core_has_stack, core_has_registers, core_info_proc): Rework as core_target methods. (ignore, core_remove_breakpoint, init_core_ops): Delete. (_initialize_corelow): Initialize the_core_target. * gdbcore.h (core_target): Delete. (the_core_target): New. * ctf.c: (ctf_target): New class. (ctf_ops): Now a ctf_target. (ctf_open, ctf_close, ctf_files_info, ctf_fetch_registers) (ctf_xfer_partial, ctf_get_trace_state_variable_value) (ctf_trace_find, ctf_traceframe_info): Refactor as ctf_target methods. (init_ctf_ops): Delete. (_initialize_ctf): Don't call it. * tracefile-tfile.c (tfile_target): New class. (tfile_ops): Now a tfile_target. (tfile_open, tfile_close, tfile_files_info) (tfile_get_tracepoint_status, tfile_trace_find) (tfile_fetch_registers, tfile_xfer_partial) (tfile_get_trace_state_variable_value, tfile_traceframe_info): Refactor as tfile_target methods. (tfile_xfer_partial_features): Remove target_ops parameter. (init_tfile_ops): Delete. (_initialize_tracefile_tfile): Don't call it. * tracefile.c (tracefile_has_all_memory, tracefile_has_memory) (tracefile_has_stack, tracefile_has_registers) (tracefile_thread_alive, tracefile_get_trace_status): Refactor as tracefile_target methods. (init_tracefile_ops): Delete. (tracefile_target::tracefile_target): New. * tracefile.h: Include "target.h". (tracefile_target): New class. (init_tracefile_ops): Delete. * spu-multiarch.c (spu_multiarch_target): New class. (spu_ops): Now a spu_multiarch_target. (spu_thread_architecture, spu_region_ok_for_hw_watchpoint) (spu_fetch_registers, spu_store_registers, spu_xfer_partial) (spu_search_memory, spu_mourn_inferior): Refactor as spu_multiarch_target methods. (init_spu_ops): Delete. (_initialize_spu_multiarch): Remove references to init_spu_ops, complete_target_initialization. * ravenscar-thread.c (ravenscar_thread_target): New class. (ravenscar_ops): Now a ravenscar_thread_target. (ravenscar_resume, ravenscar_wait, ravenscar_update_thread_list) (ravenscar_thread_alive, ravenscar_pid_to_str) (ravenscar_fetch_registers, ravenscar_store_registers) (ravenscar_prepare_to_store, ravenscar_stopped_by_sw_breakpoint) (ravenscar_stopped_by_hw_breakpoint) (ravenscar_stopped_by_watchpoint, ravenscar_stopped_data_address) (ravenscar_mourn_inferior, ravenscar_core_of_thread) (ravenscar_get_ada_task_ptid): Refactor as ravenscar_thread_target methods. (init_ravenscar_thread_ops): Delete. (_initialize_ravenscar): Remove references to init_ravenscar_thread_ops and complete_target_initialization. * bsd-uthread.c (bsd_uthread_ops_hack): Delete. (bsd_uthread_target): New class. (bsd_uthread_ops): Now a bsd_uthread_target. (bsd_uthread_activate): Adjust to refer to bsd_uthread_ops. (bsd_uthread_close, bsd_uthread_mourn_inferior) (bsd_uthread_fetch_registers, bsd_uthread_store_registers) (bsd_uthread_wait, bsd_uthread_resume, bsd_uthread_thread_alive) (bsd_uthread_update_thread_list, bsd_uthread_extra_thread_info) (bsd_uthread_pid_to_str): Refactor as bsd_uthread_target methods. (bsd_uthread_target): Delete function. (_initialize_bsd_uthread): Remove reference to complete_target_initialization. * bfd-target.c (target_bfd_data): Delete. Fields folded into ... (target_bfd): ... this new class. (target_bfd_xfer_partial, target_bfd_get_section_table) (target_bfd_close): Refactor as target_bfd methods. (target_bfd::~target_bfd): New. (target_bfd_reopen): Adjust. (target_bfd::close): New. * record-btrace.c (record_btrace_target): New class. (record_btrace_ops): Now a record_btrace_target. (record_btrace_open, record_btrace_stop_recording) (record_btrace_disconnect, record_btrace_close) (record_btrace_async, record_btrace_info) (record_btrace_insn_history, record_btrace_insn_history_range) (record_btrace_insn_history_from, record_btrace_call_history) (record_btrace_call_history_range) (record_btrace_call_history_from, record_btrace_record_method) (record_btrace_is_replaying, record_btrace_will_replay) (record_btrace_xfer_partial, record_btrace_insert_breakpoint) (record_btrace_remove_breakpoint, record_btrace_fetch_registers) (record_btrace_store_registers, record_btrace_prepare_to_store) (record_btrace_to_get_unwinder) (record_btrace_to_get_tailcall_unwinder, record_btrace_resume) (record_btrace_commit_resume, record_btrace_wait) (record_btrace_stop, record_btrace_can_execute_reverse) (record_btrace_stopped_by_sw_breakpoint) (record_btrace_supports_stopped_by_sw_breakpoint) (record_btrace_stopped_by_hw_breakpoint) (record_btrace_supports_stopped_by_hw_breakpoint) (record_btrace_update_thread_list, record_btrace_thread_alive) (record_btrace_goto_begin, record_btrace_goto_end) (record_btrace_goto, record_btrace_stop_replaying_all) (record_btrace_execution_direction) (record_btrace_prepare_to_generate_core) (record_btrace_done_generating_core): Refactor as record_btrace_target methods. (init_record_btrace_ops): Delete. (_initialize_record_btrace): Remove reference to init_record_btrace_ops. * record-full.c (RECORD_FULL_IS_REPLAY): Adjust to always refer to the execution_direction global. (record_full_base_target, record_full_target) (record_full_core_target): New classes. (record_full_ops): Now a record_full_target. (record_full_core_ops): Now a record_full_core_target. (record_full_target::detach, record_full_target::disconnect) (record_full_core_target::disconnect) (record_full_target::mourn_inferior, record_full_target::kill): New. (record_full_open, record_full_close, record_full_async): Refactor as methods of the record_full_base_target class. (record_full_resume, record_full_commit_resume): Refactor as methods of the record_full_target class. (record_full_wait, record_full_stopped_by_watchpoint) (record_full_stopped_data_address) (record_full_stopped_by_sw_breakpoint) (record_full_supports_stopped_by_sw_breakpoint) (record_full_stopped_by_hw_breakpoint) (record_full_supports_stopped_by_hw_breakpoint): Refactor as methods of the record_full_base_target class. (record_full_store_registers, record_full_xfer_partial) (record_full_insert_breakpoint, record_full_remove_breakpoint): Refactor as methods of the record_full_target class. (record_full_can_execute_reverse, record_full_get_bookmark) (record_full_goto_bookmark, record_full_execution_direction) (record_full_record_method, record_full_info, record_full_delete) (record_full_is_replaying, record_full_will_replay) (record_full_goto_begin, record_full_goto_end, record_full_goto) (record_full_stop_replaying): Refactor as methods of the record_full_base_target class. (record_full_core_resume, record_full_core_kill) (record_full_core_fetch_registers) (record_full_core_prepare_to_store) (record_full_core_store_registers, record_full_core_xfer_partial) (record_full_core_insert_breakpoint) (record_full_core_remove_breakpoint) (record_full_core_has_execution): Refactor as methods of the record_full_core_target class. (record_full_base_target::supports_delete_record): New. (init_record_full_ops): Delete. (init_record_full_core_ops): Delete. (record_full_save): Refactor as method of the record_full_base_target class. (_initialize_record_full): Remove references to init_record_full_ops and init_record_full_core_ops. * remote.c (remote_target, extended_remote_target): New classes. (remote_ops): Now a remote_target. (extended_remote_ops): Now an extended_remote_target. (remote_insert_fork_catchpoint, remote_remove_fork_catchpoint) (remote_insert_vfork_catchpoint, remote_remove_vfork_catchpoint) (remote_insert_exec_catchpoint, remote_remove_exec_catchpoint) (remote_pass_signals, remote_set_syscall_catchpoint) (remote_program_signals, ) (remote_thread_always_alive): Remove target_ops parameter. (remote_thread_alive, remote_thread_name) (remote_update_thread_list, remote_threads_extra_info) (remote_static_tracepoint_marker_at) (remote_static_tracepoint_markers_by_strid) (remote_get_ada_task_ptid, remote_close, remote_start_remote) (remote_open): Refactor as methods of remote_target. (extended_remote_open, extended_remote_detach) (extended_remote_attach, extended_remote_post_attach): (extended_remote_supports_disable_randomization) (extended_remote_create_inferior): : Refactor as method of extended_remote_target. (remote_set_permissions, remote_open_1, remote_detach) (remote_follow_fork, remote_follow_exec, remote_disconnect) (remote_resume, remote_commit_resume, remote_stop) (remote_interrupt, remote_pass_ctrlc, remote_terminal_inferior) (remote_terminal_ours, remote_wait, remote_fetch_registers) (remote_prepare_to_store, remote_store_registers) (remote_flash_erase, remote_flash_done, remote_files_info) (remote_kill, remote_mourn, remote_insert_breakpoint) (remote_remove_breakpoint, remote_insert_watchpoint) (remote_watchpoint_addr_within_range) (remote_remove_watchpoint, remote_region_ok_for_hw_watchpoint) (remote_check_watch_resources, remote_stopped_by_sw_breakpoint) (remote_supports_stopped_by_sw_breakpoint) (remote_stopped_by_hw_breakpoint) (remote_supports_stopped_by_hw_breakpoint) (remote_stopped_by_watchpoint, remote_stopped_data_address) (remote_insert_hw_breakpoint, remote_remove_hw_breakpoint) (remote_verify_memory): Refactor as methods of remote_target. (remote_write_qxfer, remote_read_qxfer): Remove target_ops parameter. (remote_xfer_partial, remote_get_memory_xfer_limit) (remote_search_memory, remote_rcmd, remote_memory_map) (remote_pid_to_str, remote_get_thread_local_address) (remote_get_tib_address, remote_read_description): Refactor as methods of remote_target. (remote_target::fileio_open, remote_target::fileio_pwrite) (remote_target::fileio_pread, remote_target::fileio_close): New. (remote_hostio_readlink, remote_hostio_fstat) (remote_filesystem_is_local, remote_can_execute_reverse) (remote_supports_non_stop, remote_supports_disable_randomization) (remote_supports_multi_process, remote_supports_cond_breakpoints) (remote_supports_enable_disable_tracepoint) (remote_supports_string_tracing) (remote_can_run_breakpoint_commands, remote_trace_init) (remote_download_tracepoint, remote_can_download_tracepoint) (remote_download_trace_state_variable, remote_enable_tracepoint) (remote_disable_tracepoint, remote_trace_set_readonly_regions) (remote_trace_start, remote_get_trace_status) (remote_get_tracepoint_status, remote_trace_stop) (remote_trace_find, remote_get_trace_state_variable_value) (remote_save_trace_data, remote_get_raw_trace_data) (remote_set_disconnected_tracing, remote_core_of_thread) (remote_set_circular_trace_buffer, remote_traceframe_info) (remote_get_min_fast_tracepoint_insn_len) (remote_set_trace_buffer_size, remote_set_trace_notes) (remote_use_agent, remote_can_use_agent, remote_enable_btrace) (remote_disable_btrace, remote_teardown_btrace) (remote_read_btrace, remote_btrace_conf) (remote_augmented_libraries_svr4_read, remote_load) (remote_pid_to_exec_file, remote_can_do_single_step) (remote_execution_direction, remote_thread_handle_to_thread_info): Refactor as methods of remote_target. (init_remote_ops, init_extended_remote_ops): Delete. (remote_can_async_p, remote_is_async_p, remote_async) (remote_thread_events, remote_upload_tracepoints) (remote_upload_trace_state_variables): Refactor as methods of remote_target. (_initialize_remote): Remove references to init_remote_ops and init_extended_remote_ops. * remote-sim.c (gdbsim_target): New class. (gdbsim_fetch_register, gdbsim_store_register, gdbsim_kill) (gdbsim_load, gdbsim_create_inferior, gdbsim_open, gdbsim_close) (gdbsim_detach, gdbsim_resume, gdbsim_interrupt) (gdbsim_wait, gdbsim_prepare_to_store, gdbsim_xfer_partial) (gdbsim_files_info, gdbsim_mourn_inferior, gdbsim_thread_alive) (gdbsim_pid_to_str, gdbsim_has_all_memory, gdbsim_has_memory): Refactor as methods of gdbsim_target. (gdbsim_ops): Now a gdbsim_target. (init_gdbsim_ops): Delete. (gdbsim_cntrl_c): Adjust. (_initialize_remote_sim): Remove reference to init_gdbsim_ops. * amd64-linux-nat.c (amd64_linux_nat_target): New class. (the_amd64_linux_nat_target): New. (amd64_linux_fetch_inferior_registers) (amd64_linux_store_inferior_registers): Refactor as methods of amd64_linux_nat_target. (_initialize_amd64_linux_nat): Adjust. Set linux_target. * i386-linux-nat.c: Don't include "linux-nat.h". (i386_linux_nat_target): New class. (the_i386_linux_nat_target): New. (i386_linux_fetch_inferior_registers) (i386_linux_store_inferior_registers, i386_linux_resume): Refactor as methods of i386_linux_nat_target. (_initialize_i386_linux_nat): Adjust. Set linux_target. * inf-child.c (inf_child_ops): Delete. (inf_child_fetch_inferior_registers) (inf_child_store_inferior_registers): Delete. (inf_child_post_attach, inf_child_prepare_to_store): Refactor as methods of inf_child_target. (inf_child_target::supports_terminal_ours) (inf_child_target::terminal_init) (inf_child_target::terminal_inferior) (inf_child_target::terminal_ours_for_output) (inf_child_target::terminal_ours, inf_child_target::interrupt) (inf_child_target::pass_ctrlc, inf_child_target::terminal_info): New. (inf_child_open, inf_child_disconnect, inf_child_close) (inf_child_mourn_inferior, inf_child_maybe_unpush_target) (inf_child_post_startup_inferior, inf_child_can_run) (inf_child_pid_to_exec_file): Refactor as methods of inf_child_target. (inf_child_follow_fork): Delete. (inf_child_target::can_create_inferior) (inf_child_target::can_attach): New. (inf_child_target::has_all_memory, inf_child_target::has_memory) (inf_child_target::has_stack, inf_child_target::has_registers) (inf_child_target::has_execution): New. (inf_child_fileio_open, inf_child_fileio_pwrite) (inf_child_fileio_pread, inf_child_fileio_fstat) (inf_child_fileio_close, inf_child_fileio_unlink) (inf_child_fileio_readlink, inf_child_use_agent) (inf_child_can_use_agent): Refactor as methods of inf_child_target. (return_zero, inf_child_target): Delete. (inf_child_target::inf_child_target): New. * inf-child.h: Include "target.h". (inf_child_target): Delete function prototype. (inf_child_target): New class. (inf_child_open_target, inf_child_mourn_inferior) (inf_child_maybe_unpush_target): Delete. * inf-ptrace.c (inf_ptrace_target::~inf_ptrace_target): New. (inf_ptrace_follow_fork, inf_ptrace_insert_fork_catchpoint) (inf_ptrace_remove_fork_catchpoint, inf_ptrace_create_inferior) (inf_ptrace_post_startup_inferior, inf_ptrace_mourn_inferior) (inf_ptrace_attach, inf_ptrace_post_attach, inf_ptrace_detach) (inf_ptrace_detach_success, inf_ptrace_kill, inf_ptrace_resume) (inf_ptrace_wait, inf_ptrace_xfer_partial) (inf_ptrace_thread_alive, inf_ptrace_files_info) (inf_ptrace_pid_to_str, inf_ptrace_auxv_parse): Refactor as methods of inf_ptrace_target. (inf_ptrace_target): Delete function. * inf-ptrace.h: Include "inf-child.h". (inf_ptrace_target): Delete function declaration. (inf_ptrace_target): New class. (inf_ptrace_trad_target, inf_ptrace_detach_success): Delete. * linux-nat.c (linux_target): New. (linux_ops, linux_ops_saved, super_xfer_partial): Delete. (linux_nat_target::~linux_nat_target): New. (linux_child_post_attach, linux_child_post_startup_inferior) (linux_child_follow_fork, linux_child_insert_fork_catchpoint) (linux_child_remove_fork_catchpoint) (linux_child_insert_vfork_catchpoint) (linux_child_remove_vfork_catchpoint) (linux_child_insert_exec_catchpoint) (linux_child_remove_exec_catchpoint) (linux_child_set_syscall_catchpoint, linux_nat_pass_signals) (linux_nat_create_inferior, linux_nat_attach, linux_nat_detach) (linux_nat_resume, linux_nat_stopped_by_watchpoint) (linux_nat_stopped_data_address) (linux_nat_stopped_by_sw_breakpoint) (linux_nat_supports_stopped_by_sw_breakpoint) (linux_nat_stopped_by_hw_breakpoint) (linux_nat_supports_stopped_by_hw_breakpoint, linux_nat_wait) (linux_nat_kill, linux_nat_mourn_inferior) (linux_nat_xfer_partial, linux_nat_thread_alive) (linux_nat_update_thread_list, linux_nat_pid_to_str) (linux_nat_thread_name, linux_child_pid_to_exec_file) (linux_child_static_tracepoint_markers_by_strid) (linux_nat_is_async_p, linux_nat_can_async_p) (linux_nat_supports_non_stop, linux_nat_always_non_stop_p) (linux_nat_supports_multi_process) (linux_nat_supports_disable_randomization, linux_nat_async) (linux_nat_stop, linux_nat_close, linux_nat_thread_address_space) (linux_nat_core_of_thread, linux_nat_filesystem_is_local) (linux_nat_fileio_open, linux_nat_fileio_readlink) (linux_nat_fileio_unlink, linux_nat_thread_events): Refactor as methods of linux_nat_target. (linux_nat_wait_1, linux_xfer_siginfo, linux_proc_xfer_partial) (linux_proc_xfer_spu, linux_nat_xfer_osdata): Remove target_ops parameter. (check_stopped_by_watchpoint): Adjust. (linux_xfer_partial): Delete. (linux_target_install_ops, linux_target, linux_nat_add_target): Delete. (linux_nat_target::linux_nat_target): New. * linux-nat.h: Include "inf-ptrace.h". (linux_nat_target): New. (linux_target, linux_target_install_ops, linux_nat_add_target): Delete function declarations. (linux_target): Declare global. * linux-thread-db.c (thread_db_target): New. (thread_db_target::thread_db_target): New. (thread_db_ops): Delete. (the_thread_db_target): New. (thread_db_detach, thread_db_wait, thread_db_mourn_inferior) (thread_db_update_thread_list, thread_db_pid_to_str) (thread_db_extra_thread_info) (thread_db_thread_handle_to_thread_info) (thread_db_get_thread_local_address, thread_db_get_ada_task_ptid) (thread_db_resume): Refactor as methods of thread_db_target. (init_thread_db_ops): Delete. (_initialize_thread_db): Remove reference to init_thread_db_ops. * x86-linux-nat.c: Don't include "linux-nat.h". (super_post_startup_inferior): Delete. (x86_linux_nat_target::~x86_linux_nat_target): New. (x86_linux_child_post_startup_inferior) (x86_linux_read_description, x86_linux_enable_btrace) (x86_linux_disable_btrace, x86_linux_teardown_btrace) (x86_linux_read_btrace, x86_linux_btrace_conf): Refactor as methods of x86_linux_nat_target. (x86_linux_create_target): Delete. Bits folded ... (x86_linux_add_target): ... here. Now takes a linux_nat_target pointer. * x86-linux-nat.h: Include "linux-nat.h" and "x86-nat.h". (x86_linux_nat_target): New class. (x86_linux_create_target): Delete. (x86_linux_add_target): Now takes a linux_nat_target pointer. * x86-nat.c (x86_insert_watchpoint, x86_remove_watchpoint) (x86_region_ok_for_watchpoint, x86_stopped_data_address) (x86_stopped_by_watchpoint, x86_insert_hw_breakpoint) (x86_remove_hw_breakpoint, x86_can_use_hw_breakpoint) (x86_stopped_by_hw_breakpoint): Remove target_ops parameter and make extern. (x86_use_watchpoints): Delete. * x86-nat.h: Include "breakpoint.h" and "target.h". (x86_use_watchpoints): Delete. (x86_can_use_hw_breakpoint, x86_region_ok_for_hw_watchpoint) (x86_stopped_by_watchpoint, x86_stopped_data_address) (x86_insert_watchpoint, x86_remove_watchpoint) (x86_insert_hw_breakpoint, x86_remove_hw_breakpoint) (x86_stopped_by_hw_breakpoint): New declarations. (x86_nat_target): New template class. * ppc-linux-nat.c (ppc_linux_nat_target): New class. (the_ppc_linux_nat_target): New. (ppc_linux_fetch_inferior_registers) (ppc_linux_can_use_hw_breakpoint) (ppc_linux_region_ok_for_hw_watchpoint) (ppc_linux_ranged_break_num_registers) (ppc_linux_insert_hw_breakpoint, ppc_linux_remove_hw_breakpoint) (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_can_accel_watchpoint_condition) (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint) (ppc_linux_stopped_data_address, ppc_linux_stopped_by_watchpoint) (ppc_linux_watchpoint_addr_within_range) (ppc_linux_masked_watch_num_registers) (ppc_linux_store_inferior_registers, ppc_linux_auxv_parse) (ppc_linux_read_description): Refactor as methods of ppc_linux_nat_target. (_initialize_ppc_linux_nat): Adjust. Set linux_target. * procfs.c (procfs_xfer_partial): Delete forward declaration. (procfs_target): New class. (the_procfs_target): New. (procfs_target): Delete function. (procfs_auxv_parse, procfs_attach, procfs_detach) (procfs_fetch_registers, procfs_store_registers, procfs_wait) (procfs_xfer_partial, procfs_resume, procfs_pass_signals) (procfs_files_info, procfs_kill_inferior, procfs_mourn_inferior) (procfs_create_inferior, procfs_update_thread_list) (procfs_thread_alive, procfs_pid_to_str) (procfs_can_use_hw_breakpoint, procfs_stopped_by_watchpoint) (procfs_stopped_data_address, procfs_insert_watchpoint) (procfs_remove_watchpoint, procfs_region_ok_for_hw_watchpoint) (proc_find_memory_regions, procfs_info_proc) (procfs_make_note_section): Refactor as methods of procfs_target. (_initialize_procfs): Adjust. * sol-thread.c (sol_thread_target): New class. (sol_thread_ops): Now a sol_thread_target. (sol_thread_detach, sol_thread_resume, sol_thread_wait) (sol_thread_fetch_registers, sol_thread_store_registers) (sol_thread_xfer_partial, sol_thread_mourn_inferior) (sol_thread_alive, solaris_pid_to_str, sol_update_thread_list) (sol_get_ada_task_ptid): Refactor as methods of sol_thread_target. (init_sol_thread_ops): Delete. (_initialize_sol_thread): Adjust. Remove references to init_sol_thread_ops and complete_target_initialization. * windows-nat.c (windows_nat_target): New class. (windows_fetch_inferior_registers) (windows_store_inferior_registers, windows_resume, windows_wait) (windows_attach, windows_detach, windows_pid_to_exec_file) (windows_files_info, windows_create_inferior) (windows_mourn_inferior, windows_interrupt, windows_kill_inferior) (windows_close, windows_pid_to_str, windows_xfer_partial) (windows_get_tib_address, windows_get_ada_task_ptid) (windows_thread_name, windows_thread_alive): Refactor as windows_nat_target methods. (do_initial_windows_stuff): Adjust. (windows_target): Delete function. (_initialize_windows_nat): Adjust. * darwin-nat.c (darwin_resume, darwin_wait_to, darwin_interrupt) (darwin_mourn_inferior, darwin_kill_inferior) (darwin_create_inferior, darwin_attach, darwin_detach) (darwin_pid_to_str, darwin_thread_alive, darwin_xfer_partial) (darwin_pid_to_exec_file, darwin_get_ada_task_ptid) (darwin_supports_multi_process): Refactor as darwin_nat_target methods. (darwin_resume_to, darwin_files_info): Delete. (_initialize_darwin_inferior): Rename to ... (_initialize_darwin_nat): ... this. Adjust to C++ification. * darwin-nat.h: Include "inf-child.h". (darwin_nat_target): New class. (darwin_complete_target): Delete. * i386-darwin-nat.c (i386_darwin_nat_target): New class. (darwin_target): New. (i386_darwin_fetch_inferior_registers) (i386_darwin_store_inferior_registers): Refactor as methods of darwin_nat_target. (darwin_complete_target): Delete, with ... (_initialize_i386_darwin_nat): ... bits factored out here. * alpha-linux-nat.c (alpha_linux_nat_target): New class. (the_alpha_linux_nat_target): New. (alpha_linux_register_u_offset): Refactor as alpha_linux_nat_target method. (_initialize_alpha_linux_nat): Adjust. * linux-nat-trad.c (inf_ptrace_register_u_offset): Delete. (inf_ptrace_fetch_register, inf_ptrace_fetch_registers) (inf_ptrace_store_register, inf_ptrace_store_registers): Refact as methods of linux_nat_trad_target. (linux_trad_target): Delete. * linux-nat-trad.h (linux_trad_target): Delete function. (linux_nat_trad_target): New class. * mips-linux-nat.c (mips_linux_nat_target): New class. (super_fetch_registers, super_store_registers, super_close): Delete. (the_mips_linux_nat_target): New. (mips64_linux_regsets_fetch_registers) (mips64_linux_regsets_store_registers) (mips64_linux_fetch_registers, mips64_linux_store_registers) (mips_linux_register_u_offset, mips_linux_read_description) (mips_linux_can_use_hw_breakpoint) (mips_linux_stopped_by_watchpoint) (mips_linux_stopped_data_address) (mips_linux_region_ok_for_hw_watchpoint) (mips_linux_insert_watchpoint, mips_linux_remove_watchpoint) (mips_linux_close): Refactor as methods of mips_linux_nat. (_initialize_mips_linux_nat): Adjust to C++ification. * aix-thread.c (aix_thread_target): New class. (aix_thread_ops): Now an aix_thread_target. (aix_thread_detach, aix_thread_resume, aix_thread_wait) (aix_thread_fetch_registers, aix_thread_store_registers) (aix_thread_xfer_partial, aix_thread_mourn_inferior) (aix_thread_thread_alive, aix_thread_pid_to_str) (aix_thread_extra_thread_info, aix_thread_get_ada_task_ptid): Refactor as methods of aix_thread_target. (init_aix_thread_ops): Delete. (_initialize_aix_thread): Remove references to init_aix_thread_ops and complete_target_initialization. * rs6000-nat.c (rs6000_xfer_shared_libraries): Delete. (rs6000_nat_target): New class. (the_rs6000_nat_target): New. (rs6000_fetch_inferior_registers, rs6000_store_inferior_registers) (rs6000_xfer_partial, rs6000_wait, rs6000_create_inferior) (rs6000_xfer_shared_libraries): Refactor as rs6000_nat_target methods. (super_create_inferior): Delete. (_initialize_rs6000_nat): Adjust to C++ification. * arm-linux-nat.c (arm_linux_nat_target): New class. (the_arm_linux_nat_target): New. (arm_linux_fetch_inferior_registers) (arm_linux_store_inferior_registers, arm_linux_read_description) (arm_linux_can_use_hw_breakpoint, arm_linux_insert_hw_breakpoint) (arm_linux_remove_hw_breakpoint) (arm_linux_region_ok_for_hw_watchpoint) (arm_linux_insert_watchpoint, arm_linux_remove_watchpoint) (arm_linux_stopped_data_address, arm_linux_stopped_by_watchpoint) (arm_linux_watchpoint_addr_within_range): Refactor as methods of arm_linux_nat_target. (_initialize_arm_linux_nat): Adjust to C++ification. * aarch64-linux-nat.c (aarch64_linux_nat_target): New class. (the_aarch64_linux_nat_target): New. (aarch64_linux_fetch_inferior_registers) (aarch64_linux_store_inferior_registers) (aarch64_linux_child_post_startup_inferior) (aarch64_linux_read_description) (aarch64_linux_can_use_hw_breakpoint) (aarch64_linux_insert_hw_breakpoint) (aarch64_linux_remove_hw_breakpoint) (aarch64_linux_insert_watchpoint, aarch64_linux_remove_watchpoint) (aarch64_linux_region_ok_for_hw_watchpoint) (aarch64_linux_stopped_data_address) (aarch64_linux_stopped_by_watchpoint) (aarch64_linux_watchpoint_addr_within_range) (aarch64_linux_can_do_single_step): Refactor as methods of aarch64_linux_nat_target. (super_post_startup_inferior): Delete. (_initialize_aarch64_linux_nat): Adjust to C++ification. * hppa-linux-nat.c (hppa_linux_nat_target): New class. (the_hppa_linux_nat_target): New. (hppa_linux_fetch_inferior_registers) (hppa_linux_store_inferior_registers): Refactor as methods of hppa_linux_nat_target. (_initialize_hppa_linux_nat): Adjust to C++ification. * ia64-linux-nat.c (ia64_linux_nat_target): New class. (the_ia64_linux_nat_target): New. (ia64_linux_insert_watchpoint, ia64_linux_remove_watchpoint) (ia64_linux_stopped_data_address) (ia64_linux_stopped_by_watchpoint, ia64_linux_fetch_registers) (ia64_linux_store_registers, ia64_linux_xfer_partial): Refactor as ia64_linux_nat_target methods. (super_xfer_partial): Delete. (_initialize_ia64_linux_nat): Adjust to C++ification. * m32r-linux-nat.c (m32r_linux_nat_target): New class. (the_m32r_linux_nat_target): New. (m32r_linux_fetch_inferior_registers) (m32r_linux_store_inferior_registers): Refactor as m32r_linux_nat_target methods. (_initialize_m32r_linux_nat): Adjust to C++ification. * m68k-linux-nat.c (m68k_linux_nat_target): New class. (the_m68k_linux_nat_target): New. (m68k_linux_fetch_inferior_registers) (m68k_linux_store_inferior_registers): Refactor as m68k_linux_nat_target methods. (_initialize_m68k_linux_nat): Adjust to C++ification. * s390-linux-nat.c (s390_linux_nat_target): New class. (the_s390_linux_nat_target): New. (s390_linux_fetch_inferior_registers) (s390_linux_store_inferior_registers, s390_stopped_by_watchpoint) (s390_insert_watchpoint, s390_remove_watchpoint) (s390_can_use_hw_breakpoint, s390_insert_hw_breakpoint) (s390_remove_hw_breakpoint, s390_region_ok_for_hw_watchpoint) (s390_auxv_parse, s390_read_description): Refactor as methods of s390_linux_nat_target. (_initialize_s390_nat): Adjust to C++ification. * sparc-linux-nat.c (sparc_linux_nat_target): New class. (the_sparc_linux_nat_target): New. (_initialize_sparc_linux_nat): Adjust to C++ification. * sparc-nat.c (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc64-linux-nat.c (sparc64_linux_nat_target): New class. (the_sparc64_linux_nat_target): New. (_initialize_sparc64_linux_nat): Adjust to C++ification. * spu-linux-nat.c (spu_linux_nat_target): New class. (the_spu_linux_nat_target): New. (spu_child_post_startup_inferior, spu_child_post_attach) (spu_child_wait, spu_fetch_inferior_registers) (spu_store_inferior_registers, spu_xfer_partial) (spu_can_use_hw_breakpoint): Refactor as spu_linux_nat_target methods. (_initialize_spu_nat): Adjust to C++ification. * tilegx-linux-nat.c (tilegx_linux_nat_target): New class. (the_tilegx_linux_nat_target): New. (fetch_inferior_registers, store_inferior_registers): Refactor as methods. (_initialize_tile_linux_nat): Adjust to C++ification. * xtensa-linux-nat.c (xtensa_linux_nat_target): New class. (the_xtensa_linux_nat_target): New. (xtensa_linux_fetch_inferior_registers) (xtensa_linux_store_inferior_registers): Refactor as xtensa_linux_nat_target methods. (_initialize_xtensa_linux_nat): Adjust to C++ification. * fbsd-nat.c (USE_SIGTRAP_SIGINFO): Delete. (fbsd_pid_to_exec_file, fbsd_find_memory_regions) (fbsd_find_memory_regions, fbsd_info_proc, fbsd_xfer_partial) (fbsd_thread_alive, fbsd_pid_to_str, fbsd_thread_name) (fbsd_update_thread_list, fbsd_resume, fbsd_wait) (fbsd_stopped_by_sw_breakpoint) (fbsd_supports_stopped_by_sw_breakpoint, fbsd_follow_fork) (fbsd_insert_fork_catchpoint, fbsd_remove_fork_catchpoint) (fbsd_insert_vfork_catchpoint, fbsd_remove_vfork_catchpoint) (fbsd_post_startup_inferior, fbsd_post_attach) (fbsd_insert_exec_catchpoint, fbsd_remove_exec_catchpoint) (fbsd_set_syscall_catchpoint) (super_xfer_partial, super_resume, super_wait) (fbsd_supports_stopped_by_hw_breakpoint): Delete. (fbsd_handle_debug_trap): Remove target_ops parameter. (fbsd_nat_add_target): Delete. * fbsd-nat.h: Include "inf-ptrace.h". (fbsd_nat_add_target): Delete. (USE_SIGTRAP_SIGINFO): Define. (fbsd_nat_target): New class. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers) (amd64bsd_store_inferior_registers): Remove target_ops parameter. (amd64bsd_target): Delete. * amd64-bsd-nat.h: New file. * amd64-fbsd-nat.c: Include "amd64-bsd-nat.h" instead of "x86-bsd-nat.h". (amd64_fbsd_nat_target): New class. (the_amd64_fbsd_nat_target): New. (amd64fbsd_read_description): Refactor as method of amd64_fbsd_nat_target. (amd64_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_amd64fbsd_nat): Adjust to C++ification. * amd64-nat.h (amd64bsd_target): Delete function declaration. * i386-bsd-nat.c (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Remove target_ops parameter. (i386bsd_target): Delete. * i386-bsd-nat.h (i386bsd_target): Delete function declaration. (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Declare. (i386_bsd_nat_target): New class. * i386-fbsd-nat.c (i386_fbsd_nat_target): New class. (the_i386_fbsd_nat_target): New. (i386fbsd_resume, i386fbsd_read_description): Refactor as i386_fbsd_nat_target methods. (i386_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_i386fbsd_nat): Adjust to C++ification. * x86-bsd-nat.c (super_mourn_inferior): Delete. (x86bsd_mourn_inferior, x86bsd_target): Delete. (_initialize_x86_bsd_nat): Adjust to C++ification. * x86-bsd-nat.h: Include "x86-nat.h". (x86bsd_target): Delete declaration. (x86bsd_nat_target): New class. * aarch64-fbsd-nat.c (aarch64_fbsd_nat_target): New class. (the_aarch64_fbsd_nat_target): New. (aarch64_fbsd_fetch_inferior_registers) (aarch64_fbsd_store_inferior_registers): Refactor as methods of aarch64_fbsd_nat_target. (_initialize_aarch64_fbsd_nat): Adjust to C++ification. * alpha-bsd-nat.c (alpha_bsd_nat_target): New class. (the_alpha_bsd_nat_target): New. (alphabsd_fetch_inferior_registers) (alphabsd_store_inferior_registers): Refactor as alpha_bsd_nat_target methods. (_initialize_alphabsd_nat): Refactor as methods of alpha_bsd_nat_target. * amd64-nbsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_nbsd_nat_target): New. (_initialize_amd64nbsd_nat): Adjust to C++ification. * amd64-obsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_obsd_nat_target): New. (_initialize_amd64obsd_nat): Adjust to C++ification. * arm-fbsd-nat.c (arm_fbsd_nat_target): New. (the_arm_fbsd_nat_target): New. (arm_fbsd_fetch_inferior_registers) (arm_fbsd_store_inferior_registers, arm_fbsd_read_description): (_initialize_arm_fbsd_nat): Refactor as methods of arm_fbsd_nat_target. (_initialize_arm_fbsd_nat): Adjust to C++ification. * arm-nbsd-nat.c (arm_netbsd_nat_target): New class. (the_arm_netbsd_nat_target): New. (armnbsd_fetch_registers, armnbsd_store_registers): Refactor as arm_netbsd_nat_target. (_initialize_arm_netbsd_nat): Adjust to C++ification. * hppa-nbsd-nat.c (hppa_nbsd_nat_target): New class. (the_hppa_nbsd_nat_target): New. (hppanbsd_fetch_registers, hppanbsd_store_registers): Refactor as hppa_nbsd_nat_target methods. (_initialize_hppanbsd_nat): Adjust to C++ification. * hppa-obsd-nat.c (hppa_obsd_nat_target): New class. (the_hppa_obsd_nat_target): New. (hppaobsd_fetch_registers, hppaobsd_store_registers): Refactor as methods of hppa_obsd_nat_target. (_initialize_hppaobsd_nat): Adjust to C++ification. Use add_target. * i386-nbsd-nat.c (the_i386_nbsd_nat_target): New. (_initialize_i386nbsd_nat): Adjust to C++ification. Use add_target. * i386-obsd-nat.c (the_i386_obsd_nat_target): New. (_initialize_i386obsd_nat): Use add_target. * m68k-bsd-nat.c (m68k_bsd_nat_target): New class. (the_m68k_bsd_nat_target): New. (m68kbsd_fetch_inferior_registers) (m68kbsd_store_inferior_registers): Refactor as methods of m68k_bsd_nat_target. (_initialize_m68kbsd_nat): Adjust to C++ification. * mips-fbsd-nat.c (mips_fbsd_nat_target): New class. (the_mips_fbsd_nat_target): New. (mips_fbsd_fetch_inferior_registers) (mips_fbsd_store_inferior_registers): Refactor as methods of mips_fbsd_nat_target. (_initialize_mips_fbsd_nat): Adjust to C++ification. Use add_target. * mips-nbsd-nat.c (mips_nbsd_nat_target): New class. (the_mips_nbsd_nat_target): New. (mipsnbsd_fetch_inferior_registers) (mipsnbsd_store_inferior_registers): Refactor as methods of mips_nbsd_nat_target. (_initialize_mipsnbsd_nat): Adjust to C++ification. * mips64-obsd-nat.c (mips64_obsd_nat_target): New class. (the_mips64_obsd_nat_target): New. (mips64obsd_fetch_inferior_registers) (mips64obsd_store_inferior_registers): Refactor as methods of mips64_obsd_nat_target. (_initialize_mips64obsd_nat): Adjust to C++ification. Use add_target. * nbsd-nat.c (nbsd_pid_to_exec_file): Refactor as method of nbsd_nat_target. * nbsd-nat.h: Include "inf-ptrace.h". (nbsd_nat_target): New class. * obsd-nat.c (obsd_pid_to_str, obsd_update_thread_list) (obsd_wait): Refactor as methods of obsd_nat_target. (obsd_add_target): Delete. * obsd-nat.h: Include "inf-ptrace.h". (obsd_nat_target): New class. * ppc-fbsd-nat.c (ppc_fbsd_nat_target): New class. (the_ppc_fbsd_nat_target): New. (ppcfbsd_fetch_inferior_registers) (ppcfbsd_store_inferior_registers): Refactor as methods of ppc_fbsd_nat_target. (_initialize_ppcfbsd_nat): Adjust to C++ification. Use add_target. * ppc-nbsd-nat.c (ppc_nbsd_nat_target): New class. (the_ppc_nbsd_nat_target): New. (ppcnbsd_fetch_inferior_registers) (ppcnbsd_store_inferior_registers): Refactor as methods of ppc_nbsd_nat_target. (_initialize_ppcnbsd_nat): Adjust to C++ification. * ppc-obsd-nat.c (ppc_obsd_nat_target): New class. (the_ppc_obsd_nat_target): New. (ppcobsd_fetch_registers, ppcobsd_store_registers): Refactor as methods of ppc_obsd_nat_target. (_initialize_ppcobsd_nat): Adjust to C++ification. Use add_target. * sh-nbsd-nat.c (sh_nbsd_nat_target): New class. (the_sh_nbsd_nat_target): New. (shnbsd_fetch_inferior_registers) (shnbsd_store_inferior_registers): Refactor as methods of sh_nbsd_nat_target. (_initialize_shnbsd_nat): Adjust to C++ification. * sparc-nat.c (sparc_xfer_wcookie): Make extern. (inf_ptrace_xfer_partial): Delete. (sparc_xfer_partial, sparc_target): Delete. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers, sparc_xfer_wcookie): Declare. (sparc_target): Delete function declaration. (sparc_target): New template class. * sparc-nbsd-nat.c (the_sparc_nbsd_nat_target): New. (_initialize_sparcnbsd_nat): Adjust to C++ification. * sparc64-fbsd-nat.c (the_sparc64_fbsd_nat_target): New. (_initialize_sparc64fbsd_nat): Adjust to C++ification. Use add_target. * sparc64-nbsd-nat.c (the_sparc64_nbsd_nat_target): New. (_initialize_sparc64nbsd_nat): Adjust to C++ification. * sparc64-obsd-nat.c (the_sparc64_obsd_nat_target): New. (_initialize_sparc64obsd_nat): Adjust to C++ification. Use add_target. * vax-bsd-nat.c (vax_bsd_nat_target): New class. (the_vax_bsd_nat_target): New. (vaxbsd_fetch_inferior_registers) (vaxbsd_store_inferior_registers): Refactor as vax_bsd_nat_target methods. (_initialize_vaxbsd_nat): Adjust to C++ification. * bsd-kvm.c (bsd_kvm_target): New class. (bsd_kvm_ops): Now a bsd_kvm_target. (bsd_kvm_open, bsd_kvm_close, bsd_kvm_xfer_partial) (bsd_kvm_files_info, bsd_kvm_fetch_registers) (bsd_kvm_thread_alive, bsd_kvm_pid_to_str): Refactor as methods of bsd_kvm_target. (bsd_kvm_return_one): Delete. (bsd_kvm_add_target): Adjust to C++ification. * nto-procfs.c (nto_procfs_target, nto_procfs_target_native) (nto_procfs_target_procfs): New classes. (procfs_open_1, procfs_thread_alive, procfs_update_thread_list) (procfs_files_info, procfs_pid_to_exec_file, procfs_attach) (procfs_post_attach, procfs_wait, procfs_fetch_registers) (procfs_xfer_partial, procfs_detach, procfs_insert_breakpoint) (procfs_remove_breakpoint, procfs_insert_hw_breakpoint) (procfs_remove_hw_breakpoint, procfs_resume) (procfs_mourn_inferior, procfs_create_inferior, procfs_interrupt) (procfs_kill_inferior, procfs_store_registers) (procfs_pass_signals, procfs_pid_to_str, procfs_can_run): Refactor as methods of nto_procfs_target. (nto_procfs_ops): Now an nto_procfs_target_procfs. (nto_native_ops): Delete. (procfs_open, procfs_native_open): Delete. (nto_native_ops): Now an nto_procfs_target_native. (init_procfs_targets): Adjust to C++ification. (procfs_can_use_hw_breakpoint, procfs_remove_hw_watchpoint) (procfs_insert_hw_watchpoint, procfs_stopped_by_watchpoint): Refactor as methods of nto_procfs_target. * go32-nat.c (go32_nat_target): New class. (the_go32_nat_target): New. (go32_attach, go32_resume, go32_wait, go32_fetch_registers) (go32_store_registers, go32_xfer_partial, go32_files_info) (go32_kill_inferior, go32_create_inferior, go32_mourn_inferior) (go32_terminal_init, go32_terminal_info, go32_terminal_inferior) (go32_terminal_ours, go32_pass_ctrlc, go32_thread_alive) (go32_pid_to_str): Refactor as methods of go32_nat_target. (go32_target): Delete. (_initialize_go32_nat): Adjust to C++ification. * gnu-nat.c (gnu_wait, gnu_resume, gnu_kill_inferior) (gnu_mourn_inferior, gnu_create_inferior, gnu_attach, gnu_detach) (gnu_stop, gnu_thread_alive, gnu_xfer_partial) (gnu_find_memory_regions, gnu_pid_to_str): Refactor as methods of gnu_nat_target. (gnu_target): Delete. * gnu-nat.h (gnu_target): Delete. (gnu_nat_target): New class. * i386-gnu-nat.c (gnu_base_target): New. (i386_gnu_nat_target): New class. (the_i386_gnu_nat_target): New. (_initialize_i386gnu_nat): Adjust to C++ification. gdb/testsuite/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * gdb.base/breakpoint-in-ro-region.exp: Adjust to to_resume and to_log_command renames. * gdb.base/sss-bp-on-user-bp-2.exp: Likewise.
2018-05-03 07:37:22 +08:00
int
ppc_linux_nat_target::insert_hw_breakpoint (struct gdbarch *gdbarch,
struct bp_target_info *bp_tgt)
{
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
struct ppc_hw_breakpoint p;
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
m_dreg_interface.detect (inferior_ptid);
if (!m_dreg_interface.hwdebug_p ())
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
return -1;
p.version = PPC_DEBUG_CURRENT_VERSION;
p.trigger_type = PPC_BREAKPOINT_TRIGGER_EXECUTE;
p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
Avoid software breakpoint's instruction shadow inconsistency This change: commit b775012e845380ed4c7421a1b87caf7bfae39f5f Author: Luis Machado <luisgpm@br.ibm.com> Date: Fri Feb 24 15:10:59 2012 +0000 2012-02-24 Luis Machado <lgustavo@codesourcery.com> * remote.c (remote_supports_cond_breakpoints): New forward declaration. [...] changed the way breakpoints are inserted and removed such that `insert_bp_location' can now be called with the breakpoint being handled already in place, while previously the call was only ever made for breakpoints that have not been put in place. This in turn caused an issue for software breakpoints and targets for which a breakpoint's `placed_address' may not be the same as the original requested address. The issue is `insert_bp_location' overwrites the previously adjusted value in `placed_address' with the original address, that is only replaced back with the correct adjusted address later on when `gdbarch_breakpoint_from_pc' is called. Meanwhile there's a window where the value in `placed_address' does not correspond to data stored in `shadow_contents', leading to incorrect instruction bytes being supplied when `one_breakpoint_xfer_memory' is called to supply the instruction overlaid by the breakpoint. And this is exactly what happens on the MIPS target with software breakpoints placed in microMIPS code. In this case not only `placed_address' is not the original address because of the ISA bit, but `mips_breakpoint_from_pc' has to read the original instruction to determine which one of the two software breakpoint instruction encodings to choose as well. The 16-bit encoding is used to replace 16-bit instructions and similarly the 32-bit one is used with 32-bit instructions, to satisfy branch delay slot size requirements. The mismatch between `placed_address' and the address data in `shadow_contents' has been obtained from leads to the wrong encoding being used in some cases, which in the case of a 32-bit software breakpoint instruction replacing a 16-bit instruction causes corruption to the adjacent following instruction and leads the debug session astray if execution reaches there e.g. with a jump. To address this problem I made the change below, that adds a `reqstd_address' field to `struct bp_target_info' and leaves `placed_address' unchanged once it has been set. This ensures data in `shadow_contents' is always consistent with `placed_address'. This approach also has this good side effect that all the places that examine the breakpoint's address see a consistent value, either `reqstd_address' or `placed_address', as required. Currently some places see either the original or the adjusted address in `placed_address', depending on whether they have been called before `gdbarch_remote_breakpoint_from_pc' or afterwards. This is in particular true for subsequent calls to `gdbarch_remote_breakpoint_from_pc' itself, e.g. from `one_breakpoint_xfer_memory'. This is also important for places like `find_single_step_breakpoint' where a breakpoint's address is compared to the raw value of $pc. * breakpoint.h (bp_target_info): Add `reqstd_address' member, update comments. * breakpoint.c (one_breakpoint_xfer_memory): Use `reqstd_address' for the breakpoint's address. Don't preinitialize `placed_size'. (insert_bp_location): Set `reqstd_address' rather than `placed_address'. (bp_target_info_copy_insertion_state): Also copy `placed_address'. (bkpt_insert_location): Use `reqstd_address' for the breakpoint's address. (bkpt_remove_location): Likewise. (deprecated_insert_raw_breakpoint): Likewise. (deprecated_remove_raw_breakpoint): Likewise. (find_single_step_breakpoint): Likewise. * mem-break.c (default_memory_insert_breakpoint): Use `reqstd_address' for the breakpoint's address. Don't set `placed_address' or `placed_size' if breakpoint contents couldn't have been determined. * remote.c (remote_insert_breakpoint): Use `reqstd_address' for the breakpoint's address. (remote_insert_hw_breakpoint): Likewise. Don't set `placed_address' or `placed_size' if breakpoint couldn't have been set. * aarch64-linux-nat.c (aarch64_linux_insert_hw_breakpoint): Use `reqstd_address' for the breakpoint's address. * arm-linux-nat.c (arm_linux_hw_breakpoint_initialize): Likewise. * ia64-tdep.c (ia64_memory_insert_breakpoint): Likewise. * m32r-tdep.c (m32r_memory_insert_breakpoint): Likewise. * microblaze-linux-tdep.c (microblaze_linux_memory_remove_breakpoint): Likewise. * monitor.c (monitor_insert_breakpoint): Likewise. * nto-procfs.c (procfs_insert_breakpoint): Likewise. (procfs_insert_hw_breakpoint): Likewise. * ppc-linux-nat.c (ppc_linux_insert_hw_breakpoint): Likewise. * ppc-linux-tdep.c (ppc_linux_memory_remove_breakpoint): Likewise. * remote-m32r-sdi.c (m32r_insert_breakpoint): Likewise. * remote-mips.c (mips_insert_breakpoint): Likewise. * x86-nat.c (x86_insert_hw_breakpoint): Likewise.
2014-10-03 19:44:58 +08:00
p.addr = (uint64_t) (bp_tgt->placed_address = bp_tgt->reqstd_address);
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
p.condition_value = 0;
2011-03-31 Thiago Jung Bauermann <bauerman@br.ibm.com> Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Implement support for PowerPC BookE ranged breakpoints. gdb/ * NEWS: Mention support for ranged breakpoints on embedded PowerPC. * breakpoint.h (struct bp_target_info) <length>: New member variable. (struct breakpoint_ops) <breakpoint_hit>: Take struct bp_location instead of struct breakpoint as argument, and also add ASPACE and BP_ADDR arguments. Update all callers. (struct breakpoint_ops) <print_one_detail>: New method. (struct breakpoint) <addr_string_range_end>: New member variable. * breakpoint.c (breakpoint_location_address_match): Add function prototype. (insert_bp_location): Set bl->target_info.length. (breakpoint_here_p): Call breakpoint_location_address_match. (moribund_breakpoint_here_p): Likewise. (regular_breakpoint_inserted_here_p): Likewise. (breakpoint_thread_match): Likewise. (bpstat_stop_status): Likewise. (bpstat_check_location): Move call to breakpoint_ops.breakpoint_hit to the top. (print_one_breakpoint_location): Call breakpoint_ops.print_one_detail if available. (breakpoint_address_match_range): New function. (breakpoint_location_address_match): Likewise. (breakpoint_locations_match): Compare the length field of the locations too. (hw_breakpoint_used_count): Count resources used by all locations in a breakpoint, and use breakpoint_ops.resources_needed if available. (breakpoint_hit_ranged_breakpoint): New function. (resources_needed_ranged_breakpoint): Likewise. (print_it_ranged_breakpoint): Likewise. (print_one_ranged_breakpoint): Likewise. (print_one_detail_ranged_breakpoint): Likewise. (print_mention_ranged_breakpoint): Likewise. (print_recreate_ranged_breakpoint): Likewise. (ranged_breakpoint_ops): New structure. (find_breakpoint_range_end): New function. (break_range_command): Likewise. (delete_breakpoint): Free addr_string_range_end. (update_breakpoint_locations): Add SALS_END argument. Update all callers. Calculate breakpoint length if a non-zero SALS_END is given. Call breakpoint_locations_match instead of breakpoint_address_match. (reset_breakpoint): Find SaL of the end of the range if B is a ranged breakpoint. (_initialize_breakpoint): Register break-range command. * defs.h (print_core_address): Add function prototype. * ppc-linux-nat.c (ppc_linux_ranged_break_num_registers): New function. (ppc_linux_insert_hw_breakpoint): Support ranged breakpoints. (ppc_linux_remove_hw_breakpoint): Likewise. (_initialize_ppc_linux_nat): Initialize to_ranged_break_num_registers. * target.c (update_current_target): Add comment about to_ranged_break_num_registers. (target_ranged_break_num_registers): New function. * target.h (struct target_ops) <to_ranged_break_num_registers>: New method. (target_ranged_break_num_registers): Add function prototype. * ui-out.c (ui_out_field_core_addr): Move address-printing logic to ... * utils.c (print_core_address): ... here. gdb/doc/ * gdb.texinfo (PowerPC Embedded): Document ranged breakpoints.
2011-03-31 22:32:49 +08:00
if (bp_tgt->length)
{
p.addr_mode = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
/* The breakpoint will trigger if the address of the instruction is
within the defined range, as follows: p.addr <= address < p.addr2. */
p.addr2 = (uint64_t) bp_tgt->placed_address + bp_tgt->length;
}
else
{
p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
p.addr2 = 0;
}
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
register_hw_breakpoint (inferior_ptid.pid (), p);
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
return 0;
}
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
/* Clear a registration for the hardware breakpoint given by type BP_TGT.
It will be removed from the threads of inferior_ptid when they are
next resumed. Returns 0 for success, or -1 if the HWDEBUG interface
that we need for hardware breakpoints is not available. */
Convert struct target_ops to C++ I.e., use C++ virtual methods and inheritance instead of tables of function pointers. Unfortunately, there's no way to do a smooth transition. ALL native targets in the tree must be converted at the same time. I've tested all I could with cross compilers and with help from GCC compile farm, but naturally I haven't been able to test many of the ports. Still, I made a best effort to port everything over, and while I expect some build problems due to typos and such, which should be trivial to fix, I don't expect any design problems. * Implementation notes: - The flattened current_target is gone. References to current_target or current_target.beneath are replaced with references to target_stack (the top of the stack) directly. - To keep "set debug target" working, this adds a new debug_stratum layer that sits on top of the stack, prints the debug, and delegates to the target beneath. In addition, this makes the shortname and longname properties of target_ops be virtual methods instead of data fields, and makes the debug target defer those to the target beneath. This is so that debug code sprinkled around that does "if (debugtarget) ..." can transparently print the name of the target beneath. A patch later in the series actually splits out the shortname/longname methods to a separate structure, but I preferred to keep that chance separate as it is associated with changing a bit the design of how targets are registered and open. - Since you can't check whether a C++ virtual method is overridden, the old method of checking whether a target_ops implements a method by comparing the function pointer must be replaced with something else. Some cases are fixed by adding a parallel "can_do_foo" target_ops methods. E.g.,: + for (t = target_stack; t != NULL; t = t->beneath) { - if (t->to_create_inferior != NULL) + if (t->can_create_inferior ()) break; } Others are fixed by changing void return type to bool or int return type, and have the default implementation return false or -1, to indicate lack of support. - make-target-delegates was adjusted to generate C++ classes and methods. It needed tweaks to grok "virtual" in front of the target method name, and for the fact that methods are no longer function pointers. (In particular, the current code parsing the return type was simple because it could simply parse up until the '(' in '(*to_foo)'. It now generates a couple C++ classes that inherit target_ops: dummy_target and debug_target. Since we need to generate the class declarations as well, i.e., we need to emit methods twice, we now generate the code in two passes. - The core_target global is renamed to avoid conflict with the "core_target" class. - ctf/tfile targets init_tracefile_ops is replaced by a base class that is inherited by both ctf and tfile. - bsd-uthread The bsd_uthread_ops_hack hack is gone. It's not needed because nothing was extending a target created by bsd_uthread_target. - remote/extended-remote targets This is a first pass, just enough to C++ify target_ops. A later pass will convert more free functions to methods, and make remote_state be truly per remote instance, allowing multiple simultaneous instances of remote targets. - inf-child/"native" is converted to an actual base class (inf_child_target), that is inherited by all native targets. - GNU/Linux The old weird double-target linux_ops mechanism in linux-nat.c, is gone, replaced by adding a few virtual methods to linux-nat.h's target_ops, called low_XXX, that the concrete linux-nat implementations override. Sort of like gdbserver's linux_target_ops, but simpler, for requiring only one target_ops-like hierarchy, which spares implementing the same method twice when we need to forward the method to a low implementation. The low target simply reimplements the target_ops method directly in that case. There are a few remaining linux-nat.c hooks that would be better converted to low_ methods like above too. E.g.: linux_nat_set_new_thread (t, x86_linux_new_thread); linux_nat_set_new_fork (t, x86_linux_new_fork); linux_nat_set_forget_process That'll be done in a follow up patch. - We can no longer use functions like x86_use_watchpoints to install custom methods on an arbitrary base target. The patch replaces instances of such a pattern with template mixins. For example memory_breakpoint_target defined in target.h, or x86_nat_target in x86-nat.h. - linux_trad_target, MIPS and Alpha GNU/Linux The code in the new linux-nat-trad.h/c files which was split off of inf-ptrace.h/c recently, is converted to a C++ base class, and used by the MIPS and Alpha GNU/Linux ports. - BSD targets The $architecture x NetBSD/OpenBSD/FreeBSD support matrix complicates things a bit. There's common BSD target code, and there's common architecture-specific code shared between the different BSDs. Currently, all that is stiched together to form a final target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target functions etc. This introduces new fbsd_nat_target, obsd_nat_target and nbsd_nat_target classes that serve as base/prototype target for the corresponding BSD variant. And introduces generic i386/AMD64 BSD targets, to be used as template mixin to build a final target. Similarly, a generic SPARC target is added, used by both BSD and Linux ports. - bsd_kvm_add_target, BSD libkvm target I considered making bsd_kvm_supply_pcb a virtual method, and then have each port inherit bsd_kvm_target and override that method, but that was resulting in lots of unjustified churn, so I left the function pointer mechanism alone. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> John Baldwin <jhb@freebsd.org> * target.h (enum strata) <debug_stratum>: New. (struct target_ops) <all delegation methods>: Replace by C++ virtual methods, and drop "to_" prefix. All references updated throughout. <to_shortname, to_longname, to_doc, to_data, to_have_steppable_watchpoint, to_have_continuable_watchpoint, to_has_thread_control, to_attach_no_wait>: Delete, replaced by virtual methods. All references updated throughout. <can_attach, supports_terminal_ours, can_create_inferior, get_thread_control_capabilities, attach_no_wait>: New virtual methods. <insert_breakpoint, remove_breakpoint>: Now TARGET_DEFAULT_NORETURN methods. <info_proc>: Now returns bool. <to_magic>: Delete. (OPS_MAGIC): Delete. (current_target): Delete. All references replaced by references to ... (target_stack): ... this. New. (target_shortname, target_longname): Adjust. (target_can_run): Now a function declaration. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (memory_breakpoint_target): New template class. (test_target_ops): Refactor as a C++ class with virtual methods. * make-target-delegates (NAME_PART): Tighten. (POINTER_PART, CP_SYMBOL): New. (SIMPLE_RETURN_PART): Reimplement. (VEC_RETURN_PART): Expect less. (RETURN_PART, VIRTUAL_PART): New. (METHOD): Adjust to C++ virtual methods. (scan_target_h): Remove reference to C99. (dname): Output "target_ops::" prefix. (write_function_header): Adjust to output a C++ class method. (write_declaration): New. (write_delegator): Adjust to output a C++ class method. (tdname): Output "dummy_target::" prefix. (write_tdefault, write_debugmethod): Adjust to output a C++ class method. (tdefault_names, debug_names): Delete. (return_types, tdefaults, styles, argtypes_array): New. (top level): All methods are delegators. (print_class): New. (top level): Print dummy_target and debug_target classes. * target-delegates.c: Regenerate. * target-debug.h (target_debug_print_enum_info_proc_what) (target_debug_print_thread_control_capabilities) (target_debug_print_thread_info_p): New. * target.c (dummy_target): Delete. (the_dummy_target, the_debug_target): New. (target_stack): Now extern. (set_targetdebug): Push/unpush debug target. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (add_target_with_completer): No longer call complete_target_initialization. (target_supports_terminal_ours): Use regular delegation. (update_current_target): Delete. (push_target): No longer check magic number. Don't call update_current_target. (unpush_target): Don't call update_current_target. (target_is_pushed): No longer check magic number. (target_require_runnable): Skip for all stratums over process_stratum. (target_ops::info_proc): New. (target_info_proc): Use find_target_at and find_default_run_target. (target_supports_disable_randomization): Use regular delegation. (target_get_osdata): Use find_target_at. (target_ops::open, target_ops::close, target_ops::can_attach) (target_ops::attach, target_ops::can_create_inferior) (target_ops::create_inferior, target_ops::can_run) (target_can_run): New. (default_fileio_target): Use regular delegation. (target_ops::fileio_open, target_ops::fileio_pwrite) (target_ops::fileio_pread, target_ops::fileio_fstat) (target_ops::fileio_close, target_ops::fileio_unlink) (target_ops::fileio_readlink): New. (target_fileio_open_1, target_fileio_unlink) (target_fileio_readlink): Always call the target method. Handle FILEIO_ENOSYS. (return_zero, return_zero_has_execution): Delete. (init_dummy_target): Delete. (dummy_target::dummy_target, dummy_target::shortname) (dummy_target::longname, dummy_target::doc) (debug_target::debug_target, debug_target::shortname) (debug_target::longname, debug_target::doc): New. (target_supports_delete_record): Use regular delegation. (setup_target_debug): Delete. (maintenance_print_target_stack): Skip debug_stratum. (initialize_targets): Instantiate the_dummy_target and the_debug_target. * auxv.c (target_auxv_parse): Remove 'ops' parameter. Adjust to use target_stack. (target_auxv_search, fprint_target_auxv): Adjust. (info_auxv_command): Adjust to use target_stack. * auxv.h (target_auxv_parse): Remove 'ops' parameter. * exceptions.c (print_flush): Handle a NULL target_stack. * regcache.c (target_ops_no_register): Refactor as class with virtual methods. * exec.c (exec_target): New class. (exec_ops): Now an exec_target. (exec_open, exec_close_1, exec_get_section_table) (exec_xfer_partial, exec_files_info, exec_has_memory) (exec_make_note_section): Refactor as exec_target methods. (exec_file_clear, ignore, exec_remove_breakpoint, init_exec_ops): Delete. (exec_target::find_memory_regions): New. (_initialize_exec): Don't call init_exec_ops. * gdbcore.h (exec_file_clear): Delete. * corefile.c (core_target): Delete. (core_file_command): Adjust. * corelow.c (core_target): New class. (the_core_target): New. (core_close): Remove target_ops parameter. (core_close_cleanup): Adjust. (core_target::close): New. (core_open, core_detach, get_core_registers, core_files_info) (core_xfer_partial, core_thread_alive, core_read_description) (core_pid_to_str, core_thread_name, core_has_memory) (core_has_stack, core_has_registers, core_info_proc): Rework as core_target methods. (ignore, core_remove_breakpoint, init_core_ops): Delete. (_initialize_corelow): Initialize the_core_target. * gdbcore.h (core_target): Delete. (the_core_target): New. * ctf.c: (ctf_target): New class. (ctf_ops): Now a ctf_target. (ctf_open, ctf_close, ctf_files_info, ctf_fetch_registers) (ctf_xfer_partial, ctf_get_trace_state_variable_value) (ctf_trace_find, ctf_traceframe_info): Refactor as ctf_target methods. (init_ctf_ops): Delete. (_initialize_ctf): Don't call it. * tracefile-tfile.c (tfile_target): New class. (tfile_ops): Now a tfile_target. (tfile_open, tfile_close, tfile_files_info) (tfile_get_tracepoint_status, tfile_trace_find) (tfile_fetch_registers, tfile_xfer_partial) (tfile_get_trace_state_variable_value, tfile_traceframe_info): Refactor as tfile_target methods. (tfile_xfer_partial_features): Remove target_ops parameter. (init_tfile_ops): Delete. (_initialize_tracefile_tfile): Don't call it. * tracefile.c (tracefile_has_all_memory, tracefile_has_memory) (tracefile_has_stack, tracefile_has_registers) (tracefile_thread_alive, tracefile_get_trace_status): Refactor as tracefile_target methods. (init_tracefile_ops): Delete. (tracefile_target::tracefile_target): New. * tracefile.h: Include "target.h". (tracefile_target): New class. (init_tracefile_ops): Delete. * spu-multiarch.c (spu_multiarch_target): New class. (spu_ops): Now a spu_multiarch_target. (spu_thread_architecture, spu_region_ok_for_hw_watchpoint) (spu_fetch_registers, spu_store_registers, spu_xfer_partial) (spu_search_memory, spu_mourn_inferior): Refactor as spu_multiarch_target methods. (init_spu_ops): Delete. (_initialize_spu_multiarch): Remove references to init_spu_ops, complete_target_initialization. * ravenscar-thread.c (ravenscar_thread_target): New class. (ravenscar_ops): Now a ravenscar_thread_target. (ravenscar_resume, ravenscar_wait, ravenscar_update_thread_list) (ravenscar_thread_alive, ravenscar_pid_to_str) (ravenscar_fetch_registers, ravenscar_store_registers) (ravenscar_prepare_to_store, ravenscar_stopped_by_sw_breakpoint) (ravenscar_stopped_by_hw_breakpoint) (ravenscar_stopped_by_watchpoint, ravenscar_stopped_data_address) (ravenscar_mourn_inferior, ravenscar_core_of_thread) (ravenscar_get_ada_task_ptid): Refactor as ravenscar_thread_target methods. (init_ravenscar_thread_ops): Delete. (_initialize_ravenscar): Remove references to init_ravenscar_thread_ops and complete_target_initialization. * bsd-uthread.c (bsd_uthread_ops_hack): Delete. (bsd_uthread_target): New class. (bsd_uthread_ops): Now a bsd_uthread_target. (bsd_uthread_activate): Adjust to refer to bsd_uthread_ops. (bsd_uthread_close, bsd_uthread_mourn_inferior) (bsd_uthread_fetch_registers, bsd_uthread_store_registers) (bsd_uthread_wait, bsd_uthread_resume, bsd_uthread_thread_alive) (bsd_uthread_update_thread_list, bsd_uthread_extra_thread_info) (bsd_uthread_pid_to_str): Refactor as bsd_uthread_target methods. (bsd_uthread_target): Delete function. (_initialize_bsd_uthread): Remove reference to complete_target_initialization. * bfd-target.c (target_bfd_data): Delete. Fields folded into ... (target_bfd): ... this new class. (target_bfd_xfer_partial, target_bfd_get_section_table) (target_bfd_close): Refactor as target_bfd methods. (target_bfd::~target_bfd): New. (target_bfd_reopen): Adjust. (target_bfd::close): New. * record-btrace.c (record_btrace_target): New class. (record_btrace_ops): Now a record_btrace_target. (record_btrace_open, record_btrace_stop_recording) (record_btrace_disconnect, record_btrace_close) (record_btrace_async, record_btrace_info) (record_btrace_insn_history, record_btrace_insn_history_range) (record_btrace_insn_history_from, record_btrace_call_history) (record_btrace_call_history_range) (record_btrace_call_history_from, record_btrace_record_method) (record_btrace_is_replaying, record_btrace_will_replay) (record_btrace_xfer_partial, record_btrace_insert_breakpoint) (record_btrace_remove_breakpoint, record_btrace_fetch_registers) (record_btrace_store_registers, record_btrace_prepare_to_store) (record_btrace_to_get_unwinder) (record_btrace_to_get_tailcall_unwinder, record_btrace_resume) (record_btrace_commit_resume, record_btrace_wait) (record_btrace_stop, record_btrace_can_execute_reverse) (record_btrace_stopped_by_sw_breakpoint) (record_btrace_supports_stopped_by_sw_breakpoint) (record_btrace_stopped_by_hw_breakpoint) (record_btrace_supports_stopped_by_hw_breakpoint) (record_btrace_update_thread_list, record_btrace_thread_alive) (record_btrace_goto_begin, record_btrace_goto_end) (record_btrace_goto, record_btrace_stop_replaying_all) (record_btrace_execution_direction) (record_btrace_prepare_to_generate_core) (record_btrace_done_generating_core): Refactor as record_btrace_target methods. (init_record_btrace_ops): Delete. (_initialize_record_btrace): Remove reference to init_record_btrace_ops. * record-full.c (RECORD_FULL_IS_REPLAY): Adjust to always refer to the execution_direction global. (record_full_base_target, record_full_target) (record_full_core_target): New classes. (record_full_ops): Now a record_full_target. (record_full_core_ops): Now a record_full_core_target. (record_full_target::detach, record_full_target::disconnect) (record_full_core_target::disconnect) (record_full_target::mourn_inferior, record_full_target::kill): New. (record_full_open, record_full_close, record_full_async): Refactor as methods of the record_full_base_target class. (record_full_resume, record_full_commit_resume): Refactor as methods of the record_full_target class. (record_full_wait, record_full_stopped_by_watchpoint) (record_full_stopped_data_address) (record_full_stopped_by_sw_breakpoint) (record_full_supports_stopped_by_sw_breakpoint) (record_full_stopped_by_hw_breakpoint) (record_full_supports_stopped_by_hw_breakpoint): Refactor as methods of the record_full_base_target class. (record_full_store_registers, record_full_xfer_partial) (record_full_insert_breakpoint, record_full_remove_breakpoint): Refactor as methods of the record_full_target class. (record_full_can_execute_reverse, record_full_get_bookmark) (record_full_goto_bookmark, record_full_execution_direction) (record_full_record_method, record_full_info, record_full_delete) (record_full_is_replaying, record_full_will_replay) (record_full_goto_begin, record_full_goto_end, record_full_goto) (record_full_stop_replaying): Refactor as methods of the record_full_base_target class. (record_full_core_resume, record_full_core_kill) (record_full_core_fetch_registers) (record_full_core_prepare_to_store) (record_full_core_store_registers, record_full_core_xfer_partial) (record_full_core_insert_breakpoint) (record_full_core_remove_breakpoint) (record_full_core_has_execution): Refactor as methods of the record_full_core_target class. (record_full_base_target::supports_delete_record): New. (init_record_full_ops): Delete. (init_record_full_core_ops): Delete. (record_full_save): Refactor as method of the record_full_base_target class. (_initialize_record_full): Remove references to init_record_full_ops and init_record_full_core_ops. * remote.c (remote_target, extended_remote_target): New classes. (remote_ops): Now a remote_target. (extended_remote_ops): Now an extended_remote_target. (remote_insert_fork_catchpoint, remote_remove_fork_catchpoint) (remote_insert_vfork_catchpoint, remote_remove_vfork_catchpoint) (remote_insert_exec_catchpoint, remote_remove_exec_catchpoint) (remote_pass_signals, remote_set_syscall_catchpoint) (remote_program_signals, ) (remote_thread_always_alive): Remove target_ops parameter. (remote_thread_alive, remote_thread_name) (remote_update_thread_list, remote_threads_extra_info) (remote_static_tracepoint_marker_at) (remote_static_tracepoint_markers_by_strid) (remote_get_ada_task_ptid, remote_close, remote_start_remote) (remote_open): Refactor as methods of remote_target. (extended_remote_open, extended_remote_detach) (extended_remote_attach, extended_remote_post_attach): (extended_remote_supports_disable_randomization) (extended_remote_create_inferior): : Refactor as method of extended_remote_target. (remote_set_permissions, remote_open_1, remote_detach) (remote_follow_fork, remote_follow_exec, remote_disconnect) (remote_resume, remote_commit_resume, remote_stop) (remote_interrupt, remote_pass_ctrlc, remote_terminal_inferior) (remote_terminal_ours, remote_wait, remote_fetch_registers) (remote_prepare_to_store, remote_store_registers) (remote_flash_erase, remote_flash_done, remote_files_info) (remote_kill, remote_mourn, remote_insert_breakpoint) (remote_remove_breakpoint, remote_insert_watchpoint) (remote_watchpoint_addr_within_range) (remote_remove_watchpoint, remote_region_ok_for_hw_watchpoint) (remote_check_watch_resources, remote_stopped_by_sw_breakpoint) (remote_supports_stopped_by_sw_breakpoint) (remote_stopped_by_hw_breakpoint) (remote_supports_stopped_by_hw_breakpoint) (remote_stopped_by_watchpoint, remote_stopped_data_address) (remote_insert_hw_breakpoint, remote_remove_hw_breakpoint) (remote_verify_memory): Refactor as methods of remote_target. (remote_write_qxfer, remote_read_qxfer): Remove target_ops parameter. (remote_xfer_partial, remote_get_memory_xfer_limit) (remote_search_memory, remote_rcmd, remote_memory_map) (remote_pid_to_str, remote_get_thread_local_address) (remote_get_tib_address, remote_read_description): Refactor as methods of remote_target. (remote_target::fileio_open, remote_target::fileio_pwrite) (remote_target::fileio_pread, remote_target::fileio_close): New. (remote_hostio_readlink, remote_hostio_fstat) (remote_filesystem_is_local, remote_can_execute_reverse) (remote_supports_non_stop, remote_supports_disable_randomization) (remote_supports_multi_process, remote_supports_cond_breakpoints) (remote_supports_enable_disable_tracepoint) (remote_supports_string_tracing) (remote_can_run_breakpoint_commands, remote_trace_init) (remote_download_tracepoint, remote_can_download_tracepoint) (remote_download_trace_state_variable, remote_enable_tracepoint) (remote_disable_tracepoint, remote_trace_set_readonly_regions) (remote_trace_start, remote_get_trace_status) (remote_get_tracepoint_status, remote_trace_stop) (remote_trace_find, remote_get_trace_state_variable_value) (remote_save_trace_data, remote_get_raw_trace_data) (remote_set_disconnected_tracing, remote_core_of_thread) (remote_set_circular_trace_buffer, remote_traceframe_info) (remote_get_min_fast_tracepoint_insn_len) (remote_set_trace_buffer_size, remote_set_trace_notes) (remote_use_agent, remote_can_use_agent, remote_enable_btrace) (remote_disable_btrace, remote_teardown_btrace) (remote_read_btrace, remote_btrace_conf) (remote_augmented_libraries_svr4_read, remote_load) (remote_pid_to_exec_file, remote_can_do_single_step) (remote_execution_direction, remote_thread_handle_to_thread_info): Refactor as methods of remote_target. (init_remote_ops, init_extended_remote_ops): Delete. (remote_can_async_p, remote_is_async_p, remote_async) (remote_thread_events, remote_upload_tracepoints) (remote_upload_trace_state_variables): Refactor as methods of remote_target. (_initialize_remote): Remove references to init_remote_ops and init_extended_remote_ops. * remote-sim.c (gdbsim_target): New class. (gdbsim_fetch_register, gdbsim_store_register, gdbsim_kill) (gdbsim_load, gdbsim_create_inferior, gdbsim_open, gdbsim_close) (gdbsim_detach, gdbsim_resume, gdbsim_interrupt) (gdbsim_wait, gdbsim_prepare_to_store, gdbsim_xfer_partial) (gdbsim_files_info, gdbsim_mourn_inferior, gdbsim_thread_alive) (gdbsim_pid_to_str, gdbsim_has_all_memory, gdbsim_has_memory): Refactor as methods of gdbsim_target. (gdbsim_ops): Now a gdbsim_target. (init_gdbsim_ops): Delete. (gdbsim_cntrl_c): Adjust. (_initialize_remote_sim): Remove reference to init_gdbsim_ops. * amd64-linux-nat.c (amd64_linux_nat_target): New class. (the_amd64_linux_nat_target): New. (amd64_linux_fetch_inferior_registers) (amd64_linux_store_inferior_registers): Refactor as methods of amd64_linux_nat_target. (_initialize_amd64_linux_nat): Adjust. Set linux_target. * i386-linux-nat.c: Don't include "linux-nat.h". (i386_linux_nat_target): New class. (the_i386_linux_nat_target): New. (i386_linux_fetch_inferior_registers) (i386_linux_store_inferior_registers, i386_linux_resume): Refactor as methods of i386_linux_nat_target. (_initialize_i386_linux_nat): Adjust. Set linux_target. * inf-child.c (inf_child_ops): Delete. (inf_child_fetch_inferior_registers) (inf_child_store_inferior_registers): Delete. (inf_child_post_attach, inf_child_prepare_to_store): Refactor as methods of inf_child_target. (inf_child_target::supports_terminal_ours) (inf_child_target::terminal_init) (inf_child_target::terminal_inferior) (inf_child_target::terminal_ours_for_output) (inf_child_target::terminal_ours, inf_child_target::interrupt) (inf_child_target::pass_ctrlc, inf_child_target::terminal_info): New. (inf_child_open, inf_child_disconnect, inf_child_close) (inf_child_mourn_inferior, inf_child_maybe_unpush_target) (inf_child_post_startup_inferior, inf_child_can_run) (inf_child_pid_to_exec_file): Refactor as methods of inf_child_target. (inf_child_follow_fork): Delete. (inf_child_target::can_create_inferior) (inf_child_target::can_attach): New. (inf_child_target::has_all_memory, inf_child_target::has_memory) (inf_child_target::has_stack, inf_child_target::has_registers) (inf_child_target::has_execution): New. (inf_child_fileio_open, inf_child_fileio_pwrite) (inf_child_fileio_pread, inf_child_fileio_fstat) (inf_child_fileio_close, inf_child_fileio_unlink) (inf_child_fileio_readlink, inf_child_use_agent) (inf_child_can_use_agent): Refactor as methods of inf_child_target. (return_zero, inf_child_target): Delete. (inf_child_target::inf_child_target): New. * inf-child.h: Include "target.h". (inf_child_target): Delete function prototype. (inf_child_target): New class. (inf_child_open_target, inf_child_mourn_inferior) (inf_child_maybe_unpush_target): Delete. * inf-ptrace.c (inf_ptrace_target::~inf_ptrace_target): New. (inf_ptrace_follow_fork, inf_ptrace_insert_fork_catchpoint) (inf_ptrace_remove_fork_catchpoint, inf_ptrace_create_inferior) (inf_ptrace_post_startup_inferior, inf_ptrace_mourn_inferior) (inf_ptrace_attach, inf_ptrace_post_attach, inf_ptrace_detach) (inf_ptrace_detach_success, inf_ptrace_kill, inf_ptrace_resume) (inf_ptrace_wait, inf_ptrace_xfer_partial) (inf_ptrace_thread_alive, inf_ptrace_files_info) (inf_ptrace_pid_to_str, inf_ptrace_auxv_parse): Refactor as methods of inf_ptrace_target. (inf_ptrace_target): Delete function. * inf-ptrace.h: Include "inf-child.h". (inf_ptrace_target): Delete function declaration. (inf_ptrace_target): New class. (inf_ptrace_trad_target, inf_ptrace_detach_success): Delete. * linux-nat.c (linux_target): New. (linux_ops, linux_ops_saved, super_xfer_partial): Delete. (linux_nat_target::~linux_nat_target): New. (linux_child_post_attach, linux_child_post_startup_inferior) (linux_child_follow_fork, linux_child_insert_fork_catchpoint) (linux_child_remove_fork_catchpoint) (linux_child_insert_vfork_catchpoint) (linux_child_remove_vfork_catchpoint) (linux_child_insert_exec_catchpoint) (linux_child_remove_exec_catchpoint) (linux_child_set_syscall_catchpoint, linux_nat_pass_signals) (linux_nat_create_inferior, linux_nat_attach, linux_nat_detach) (linux_nat_resume, linux_nat_stopped_by_watchpoint) (linux_nat_stopped_data_address) (linux_nat_stopped_by_sw_breakpoint) (linux_nat_supports_stopped_by_sw_breakpoint) (linux_nat_stopped_by_hw_breakpoint) (linux_nat_supports_stopped_by_hw_breakpoint, linux_nat_wait) (linux_nat_kill, linux_nat_mourn_inferior) (linux_nat_xfer_partial, linux_nat_thread_alive) (linux_nat_update_thread_list, linux_nat_pid_to_str) (linux_nat_thread_name, linux_child_pid_to_exec_file) (linux_child_static_tracepoint_markers_by_strid) (linux_nat_is_async_p, linux_nat_can_async_p) (linux_nat_supports_non_stop, linux_nat_always_non_stop_p) (linux_nat_supports_multi_process) (linux_nat_supports_disable_randomization, linux_nat_async) (linux_nat_stop, linux_nat_close, linux_nat_thread_address_space) (linux_nat_core_of_thread, linux_nat_filesystem_is_local) (linux_nat_fileio_open, linux_nat_fileio_readlink) (linux_nat_fileio_unlink, linux_nat_thread_events): Refactor as methods of linux_nat_target. (linux_nat_wait_1, linux_xfer_siginfo, linux_proc_xfer_partial) (linux_proc_xfer_spu, linux_nat_xfer_osdata): Remove target_ops parameter. (check_stopped_by_watchpoint): Adjust. (linux_xfer_partial): Delete. (linux_target_install_ops, linux_target, linux_nat_add_target): Delete. (linux_nat_target::linux_nat_target): New. * linux-nat.h: Include "inf-ptrace.h". (linux_nat_target): New. (linux_target, linux_target_install_ops, linux_nat_add_target): Delete function declarations. (linux_target): Declare global. * linux-thread-db.c (thread_db_target): New. (thread_db_target::thread_db_target): New. (thread_db_ops): Delete. (the_thread_db_target): New. (thread_db_detach, thread_db_wait, thread_db_mourn_inferior) (thread_db_update_thread_list, thread_db_pid_to_str) (thread_db_extra_thread_info) (thread_db_thread_handle_to_thread_info) (thread_db_get_thread_local_address, thread_db_get_ada_task_ptid) (thread_db_resume): Refactor as methods of thread_db_target. (init_thread_db_ops): Delete. (_initialize_thread_db): Remove reference to init_thread_db_ops. * x86-linux-nat.c: Don't include "linux-nat.h". (super_post_startup_inferior): Delete. (x86_linux_nat_target::~x86_linux_nat_target): New. (x86_linux_child_post_startup_inferior) (x86_linux_read_description, x86_linux_enable_btrace) (x86_linux_disable_btrace, x86_linux_teardown_btrace) (x86_linux_read_btrace, x86_linux_btrace_conf): Refactor as methods of x86_linux_nat_target. (x86_linux_create_target): Delete. Bits folded ... (x86_linux_add_target): ... here. Now takes a linux_nat_target pointer. * x86-linux-nat.h: Include "linux-nat.h" and "x86-nat.h". (x86_linux_nat_target): New class. (x86_linux_create_target): Delete. (x86_linux_add_target): Now takes a linux_nat_target pointer. * x86-nat.c (x86_insert_watchpoint, x86_remove_watchpoint) (x86_region_ok_for_watchpoint, x86_stopped_data_address) (x86_stopped_by_watchpoint, x86_insert_hw_breakpoint) (x86_remove_hw_breakpoint, x86_can_use_hw_breakpoint) (x86_stopped_by_hw_breakpoint): Remove target_ops parameter and make extern. (x86_use_watchpoints): Delete. * x86-nat.h: Include "breakpoint.h" and "target.h". (x86_use_watchpoints): Delete. (x86_can_use_hw_breakpoint, x86_region_ok_for_hw_watchpoint) (x86_stopped_by_watchpoint, x86_stopped_data_address) (x86_insert_watchpoint, x86_remove_watchpoint) (x86_insert_hw_breakpoint, x86_remove_hw_breakpoint) (x86_stopped_by_hw_breakpoint): New declarations. (x86_nat_target): New template class. * ppc-linux-nat.c (ppc_linux_nat_target): New class. (the_ppc_linux_nat_target): New. (ppc_linux_fetch_inferior_registers) (ppc_linux_can_use_hw_breakpoint) (ppc_linux_region_ok_for_hw_watchpoint) (ppc_linux_ranged_break_num_registers) (ppc_linux_insert_hw_breakpoint, ppc_linux_remove_hw_breakpoint) (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_can_accel_watchpoint_condition) (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint) (ppc_linux_stopped_data_address, ppc_linux_stopped_by_watchpoint) (ppc_linux_watchpoint_addr_within_range) (ppc_linux_masked_watch_num_registers) (ppc_linux_store_inferior_registers, ppc_linux_auxv_parse) (ppc_linux_read_description): Refactor as methods of ppc_linux_nat_target. (_initialize_ppc_linux_nat): Adjust. Set linux_target. * procfs.c (procfs_xfer_partial): Delete forward declaration. (procfs_target): New class. (the_procfs_target): New. (procfs_target): Delete function. (procfs_auxv_parse, procfs_attach, procfs_detach) (procfs_fetch_registers, procfs_store_registers, procfs_wait) (procfs_xfer_partial, procfs_resume, procfs_pass_signals) (procfs_files_info, procfs_kill_inferior, procfs_mourn_inferior) (procfs_create_inferior, procfs_update_thread_list) (procfs_thread_alive, procfs_pid_to_str) (procfs_can_use_hw_breakpoint, procfs_stopped_by_watchpoint) (procfs_stopped_data_address, procfs_insert_watchpoint) (procfs_remove_watchpoint, procfs_region_ok_for_hw_watchpoint) (proc_find_memory_regions, procfs_info_proc) (procfs_make_note_section): Refactor as methods of procfs_target. (_initialize_procfs): Adjust. * sol-thread.c (sol_thread_target): New class. (sol_thread_ops): Now a sol_thread_target. (sol_thread_detach, sol_thread_resume, sol_thread_wait) (sol_thread_fetch_registers, sol_thread_store_registers) (sol_thread_xfer_partial, sol_thread_mourn_inferior) (sol_thread_alive, solaris_pid_to_str, sol_update_thread_list) (sol_get_ada_task_ptid): Refactor as methods of sol_thread_target. (init_sol_thread_ops): Delete. (_initialize_sol_thread): Adjust. Remove references to init_sol_thread_ops and complete_target_initialization. * windows-nat.c (windows_nat_target): New class. (windows_fetch_inferior_registers) (windows_store_inferior_registers, windows_resume, windows_wait) (windows_attach, windows_detach, windows_pid_to_exec_file) (windows_files_info, windows_create_inferior) (windows_mourn_inferior, windows_interrupt, windows_kill_inferior) (windows_close, windows_pid_to_str, windows_xfer_partial) (windows_get_tib_address, windows_get_ada_task_ptid) (windows_thread_name, windows_thread_alive): Refactor as windows_nat_target methods. (do_initial_windows_stuff): Adjust. (windows_target): Delete function. (_initialize_windows_nat): Adjust. * darwin-nat.c (darwin_resume, darwin_wait_to, darwin_interrupt) (darwin_mourn_inferior, darwin_kill_inferior) (darwin_create_inferior, darwin_attach, darwin_detach) (darwin_pid_to_str, darwin_thread_alive, darwin_xfer_partial) (darwin_pid_to_exec_file, darwin_get_ada_task_ptid) (darwin_supports_multi_process): Refactor as darwin_nat_target methods. (darwin_resume_to, darwin_files_info): Delete. (_initialize_darwin_inferior): Rename to ... (_initialize_darwin_nat): ... this. Adjust to C++ification. * darwin-nat.h: Include "inf-child.h". (darwin_nat_target): New class. (darwin_complete_target): Delete. * i386-darwin-nat.c (i386_darwin_nat_target): New class. (darwin_target): New. (i386_darwin_fetch_inferior_registers) (i386_darwin_store_inferior_registers): Refactor as methods of darwin_nat_target. (darwin_complete_target): Delete, with ... (_initialize_i386_darwin_nat): ... bits factored out here. * alpha-linux-nat.c (alpha_linux_nat_target): New class. (the_alpha_linux_nat_target): New. (alpha_linux_register_u_offset): Refactor as alpha_linux_nat_target method. (_initialize_alpha_linux_nat): Adjust. * linux-nat-trad.c (inf_ptrace_register_u_offset): Delete. (inf_ptrace_fetch_register, inf_ptrace_fetch_registers) (inf_ptrace_store_register, inf_ptrace_store_registers): Refact as methods of linux_nat_trad_target. (linux_trad_target): Delete. * linux-nat-trad.h (linux_trad_target): Delete function. (linux_nat_trad_target): New class. * mips-linux-nat.c (mips_linux_nat_target): New class. (super_fetch_registers, super_store_registers, super_close): Delete. (the_mips_linux_nat_target): New. (mips64_linux_regsets_fetch_registers) (mips64_linux_regsets_store_registers) (mips64_linux_fetch_registers, mips64_linux_store_registers) (mips_linux_register_u_offset, mips_linux_read_description) (mips_linux_can_use_hw_breakpoint) (mips_linux_stopped_by_watchpoint) (mips_linux_stopped_data_address) (mips_linux_region_ok_for_hw_watchpoint) (mips_linux_insert_watchpoint, mips_linux_remove_watchpoint) (mips_linux_close): Refactor as methods of mips_linux_nat. (_initialize_mips_linux_nat): Adjust to C++ification. * aix-thread.c (aix_thread_target): New class. (aix_thread_ops): Now an aix_thread_target. (aix_thread_detach, aix_thread_resume, aix_thread_wait) (aix_thread_fetch_registers, aix_thread_store_registers) (aix_thread_xfer_partial, aix_thread_mourn_inferior) (aix_thread_thread_alive, aix_thread_pid_to_str) (aix_thread_extra_thread_info, aix_thread_get_ada_task_ptid): Refactor as methods of aix_thread_target. (init_aix_thread_ops): Delete. (_initialize_aix_thread): Remove references to init_aix_thread_ops and complete_target_initialization. * rs6000-nat.c (rs6000_xfer_shared_libraries): Delete. (rs6000_nat_target): New class. (the_rs6000_nat_target): New. (rs6000_fetch_inferior_registers, rs6000_store_inferior_registers) (rs6000_xfer_partial, rs6000_wait, rs6000_create_inferior) (rs6000_xfer_shared_libraries): Refactor as rs6000_nat_target methods. (super_create_inferior): Delete. (_initialize_rs6000_nat): Adjust to C++ification. * arm-linux-nat.c (arm_linux_nat_target): New class. (the_arm_linux_nat_target): New. (arm_linux_fetch_inferior_registers) (arm_linux_store_inferior_registers, arm_linux_read_description) (arm_linux_can_use_hw_breakpoint, arm_linux_insert_hw_breakpoint) (arm_linux_remove_hw_breakpoint) (arm_linux_region_ok_for_hw_watchpoint) (arm_linux_insert_watchpoint, arm_linux_remove_watchpoint) (arm_linux_stopped_data_address, arm_linux_stopped_by_watchpoint) (arm_linux_watchpoint_addr_within_range): Refactor as methods of arm_linux_nat_target. (_initialize_arm_linux_nat): Adjust to C++ification. * aarch64-linux-nat.c (aarch64_linux_nat_target): New class. (the_aarch64_linux_nat_target): New. (aarch64_linux_fetch_inferior_registers) (aarch64_linux_store_inferior_registers) (aarch64_linux_child_post_startup_inferior) (aarch64_linux_read_description) (aarch64_linux_can_use_hw_breakpoint) (aarch64_linux_insert_hw_breakpoint) (aarch64_linux_remove_hw_breakpoint) (aarch64_linux_insert_watchpoint, aarch64_linux_remove_watchpoint) (aarch64_linux_region_ok_for_hw_watchpoint) (aarch64_linux_stopped_data_address) (aarch64_linux_stopped_by_watchpoint) (aarch64_linux_watchpoint_addr_within_range) (aarch64_linux_can_do_single_step): Refactor as methods of aarch64_linux_nat_target. (super_post_startup_inferior): Delete. (_initialize_aarch64_linux_nat): Adjust to C++ification. * hppa-linux-nat.c (hppa_linux_nat_target): New class. (the_hppa_linux_nat_target): New. (hppa_linux_fetch_inferior_registers) (hppa_linux_store_inferior_registers): Refactor as methods of hppa_linux_nat_target. (_initialize_hppa_linux_nat): Adjust to C++ification. * ia64-linux-nat.c (ia64_linux_nat_target): New class. (the_ia64_linux_nat_target): New. (ia64_linux_insert_watchpoint, ia64_linux_remove_watchpoint) (ia64_linux_stopped_data_address) (ia64_linux_stopped_by_watchpoint, ia64_linux_fetch_registers) (ia64_linux_store_registers, ia64_linux_xfer_partial): Refactor as ia64_linux_nat_target methods. (super_xfer_partial): Delete. (_initialize_ia64_linux_nat): Adjust to C++ification. * m32r-linux-nat.c (m32r_linux_nat_target): New class. (the_m32r_linux_nat_target): New. (m32r_linux_fetch_inferior_registers) (m32r_linux_store_inferior_registers): Refactor as m32r_linux_nat_target methods. (_initialize_m32r_linux_nat): Adjust to C++ification. * m68k-linux-nat.c (m68k_linux_nat_target): New class. (the_m68k_linux_nat_target): New. (m68k_linux_fetch_inferior_registers) (m68k_linux_store_inferior_registers): Refactor as m68k_linux_nat_target methods. (_initialize_m68k_linux_nat): Adjust to C++ification. * s390-linux-nat.c (s390_linux_nat_target): New class. (the_s390_linux_nat_target): New. (s390_linux_fetch_inferior_registers) (s390_linux_store_inferior_registers, s390_stopped_by_watchpoint) (s390_insert_watchpoint, s390_remove_watchpoint) (s390_can_use_hw_breakpoint, s390_insert_hw_breakpoint) (s390_remove_hw_breakpoint, s390_region_ok_for_hw_watchpoint) (s390_auxv_parse, s390_read_description): Refactor as methods of s390_linux_nat_target. (_initialize_s390_nat): Adjust to C++ification. * sparc-linux-nat.c (sparc_linux_nat_target): New class. (the_sparc_linux_nat_target): New. (_initialize_sparc_linux_nat): Adjust to C++ification. * sparc-nat.c (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc64-linux-nat.c (sparc64_linux_nat_target): New class. (the_sparc64_linux_nat_target): New. (_initialize_sparc64_linux_nat): Adjust to C++ification. * spu-linux-nat.c (spu_linux_nat_target): New class. (the_spu_linux_nat_target): New. (spu_child_post_startup_inferior, spu_child_post_attach) (spu_child_wait, spu_fetch_inferior_registers) (spu_store_inferior_registers, spu_xfer_partial) (spu_can_use_hw_breakpoint): Refactor as spu_linux_nat_target methods. (_initialize_spu_nat): Adjust to C++ification. * tilegx-linux-nat.c (tilegx_linux_nat_target): New class. (the_tilegx_linux_nat_target): New. (fetch_inferior_registers, store_inferior_registers): Refactor as methods. (_initialize_tile_linux_nat): Adjust to C++ification. * xtensa-linux-nat.c (xtensa_linux_nat_target): New class. (the_xtensa_linux_nat_target): New. (xtensa_linux_fetch_inferior_registers) (xtensa_linux_store_inferior_registers): Refactor as xtensa_linux_nat_target methods. (_initialize_xtensa_linux_nat): Adjust to C++ification. * fbsd-nat.c (USE_SIGTRAP_SIGINFO): Delete. (fbsd_pid_to_exec_file, fbsd_find_memory_regions) (fbsd_find_memory_regions, fbsd_info_proc, fbsd_xfer_partial) (fbsd_thread_alive, fbsd_pid_to_str, fbsd_thread_name) (fbsd_update_thread_list, fbsd_resume, fbsd_wait) (fbsd_stopped_by_sw_breakpoint) (fbsd_supports_stopped_by_sw_breakpoint, fbsd_follow_fork) (fbsd_insert_fork_catchpoint, fbsd_remove_fork_catchpoint) (fbsd_insert_vfork_catchpoint, fbsd_remove_vfork_catchpoint) (fbsd_post_startup_inferior, fbsd_post_attach) (fbsd_insert_exec_catchpoint, fbsd_remove_exec_catchpoint) (fbsd_set_syscall_catchpoint) (super_xfer_partial, super_resume, super_wait) (fbsd_supports_stopped_by_hw_breakpoint): Delete. (fbsd_handle_debug_trap): Remove target_ops parameter. (fbsd_nat_add_target): Delete. * fbsd-nat.h: Include "inf-ptrace.h". (fbsd_nat_add_target): Delete. (USE_SIGTRAP_SIGINFO): Define. (fbsd_nat_target): New class. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers) (amd64bsd_store_inferior_registers): Remove target_ops parameter. (amd64bsd_target): Delete. * amd64-bsd-nat.h: New file. * amd64-fbsd-nat.c: Include "amd64-bsd-nat.h" instead of "x86-bsd-nat.h". (amd64_fbsd_nat_target): New class. (the_amd64_fbsd_nat_target): New. (amd64fbsd_read_description): Refactor as method of amd64_fbsd_nat_target. (amd64_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_amd64fbsd_nat): Adjust to C++ification. * amd64-nat.h (amd64bsd_target): Delete function declaration. * i386-bsd-nat.c (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Remove target_ops parameter. (i386bsd_target): Delete. * i386-bsd-nat.h (i386bsd_target): Delete function declaration. (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Declare. (i386_bsd_nat_target): New class. * i386-fbsd-nat.c (i386_fbsd_nat_target): New class. (the_i386_fbsd_nat_target): New. (i386fbsd_resume, i386fbsd_read_description): Refactor as i386_fbsd_nat_target methods. (i386_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_i386fbsd_nat): Adjust to C++ification. * x86-bsd-nat.c (super_mourn_inferior): Delete. (x86bsd_mourn_inferior, x86bsd_target): Delete. (_initialize_x86_bsd_nat): Adjust to C++ification. * x86-bsd-nat.h: Include "x86-nat.h". (x86bsd_target): Delete declaration. (x86bsd_nat_target): New class. * aarch64-fbsd-nat.c (aarch64_fbsd_nat_target): New class. (the_aarch64_fbsd_nat_target): New. (aarch64_fbsd_fetch_inferior_registers) (aarch64_fbsd_store_inferior_registers): Refactor as methods of aarch64_fbsd_nat_target. (_initialize_aarch64_fbsd_nat): Adjust to C++ification. * alpha-bsd-nat.c (alpha_bsd_nat_target): New class. (the_alpha_bsd_nat_target): New. (alphabsd_fetch_inferior_registers) (alphabsd_store_inferior_registers): Refactor as alpha_bsd_nat_target methods. (_initialize_alphabsd_nat): Refactor as methods of alpha_bsd_nat_target. * amd64-nbsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_nbsd_nat_target): New. (_initialize_amd64nbsd_nat): Adjust to C++ification. * amd64-obsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_obsd_nat_target): New. (_initialize_amd64obsd_nat): Adjust to C++ification. * arm-fbsd-nat.c (arm_fbsd_nat_target): New. (the_arm_fbsd_nat_target): New. (arm_fbsd_fetch_inferior_registers) (arm_fbsd_store_inferior_registers, arm_fbsd_read_description): (_initialize_arm_fbsd_nat): Refactor as methods of arm_fbsd_nat_target. (_initialize_arm_fbsd_nat): Adjust to C++ification. * arm-nbsd-nat.c (arm_netbsd_nat_target): New class. (the_arm_netbsd_nat_target): New. (armnbsd_fetch_registers, armnbsd_store_registers): Refactor as arm_netbsd_nat_target. (_initialize_arm_netbsd_nat): Adjust to C++ification. * hppa-nbsd-nat.c (hppa_nbsd_nat_target): New class. (the_hppa_nbsd_nat_target): New. (hppanbsd_fetch_registers, hppanbsd_store_registers): Refactor as hppa_nbsd_nat_target methods. (_initialize_hppanbsd_nat): Adjust to C++ification. * hppa-obsd-nat.c (hppa_obsd_nat_target): New class. (the_hppa_obsd_nat_target): New. (hppaobsd_fetch_registers, hppaobsd_store_registers): Refactor as methods of hppa_obsd_nat_target. (_initialize_hppaobsd_nat): Adjust to C++ification. Use add_target. * i386-nbsd-nat.c (the_i386_nbsd_nat_target): New. (_initialize_i386nbsd_nat): Adjust to C++ification. Use add_target. * i386-obsd-nat.c (the_i386_obsd_nat_target): New. (_initialize_i386obsd_nat): Use add_target. * m68k-bsd-nat.c (m68k_bsd_nat_target): New class. (the_m68k_bsd_nat_target): New. (m68kbsd_fetch_inferior_registers) (m68kbsd_store_inferior_registers): Refactor as methods of m68k_bsd_nat_target. (_initialize_m68kbsd_nat): Adjust to C++ification. * mips-fbsd-nat.c (mips_fbsd_nat_target): New class. (the_mips_fbsd_nat_target): New. (mips_fbsd_fetch_inferior_registers) (mips_fbsd_store_inferior_registers): Refactor as methods of mips_fbsd_nat_target. (_initialize_mips_fbsd_nat): Adjust to C++ification. Use add_target. * mips-nbsd-nat.c (mips_nbsd_nat_target): New class. (the_mips_nbsd_nat_target): New. (mipsnbsd_fetch_inferior_registers) (mipsnbsd_store_inferior_registers): Refactor as methods of mips_nbsd_nat_target. (_initialize_mipsnbsd_nat): Adjust to C++ification. * mips64-obsd-nat.c (mips64_obsd_nat_target): New class. (the_mips64_obsd_nat_target): New. (mips64obsd_fetch_inferior_registers) (mips64obsd_store_inferior_registers): Refactor as methods of mips64_obsd_nat_target. (_initialize_mips64obsd_nat): Adjust to C++ification. Use add_target. * nbsd-nat.c (nbsd_pid_to_exec_file): Refactor as method of nbsd_nat_target. * nbsd-nat.h: Include "inf-ptrace.h". (nbsd_nat_target): New class. * obsd-nat.c (obsd_pid_to_str, obsd_update_thread_list) (obsd_wait): Refactor as methods of obsd_nat_target. (obsd_add_target): Delete. * obsd-nat.h: Include "inf-ptrace.h". (obsd_nat_target): New class. * ppc-fbsd-nat.c (ppc_fbsd_nat_target): New class. (the_ppc_fbsd_nat_target): New. (ppcfbsd_fetch_inferior_registers) (ppcfbsd_store_inferior_registers): Refactor as methods of ppc_fbsd_nat_target. (_initialize_ppcfbsd_nat): Adjust to C++ification. Use add_target. * ppc-nbsd-nat.c (ppc_nbsd_nat_target): New class. (the_ppc_nbsd_nat_target): New. (ppcnbsd_fetch_inferior_registers) (ppcnbsd_store_inferior_registers): Refactor as methods of ppc_nbsd_nat_target. (_initialize_ppcnbsd_nat): Adjust to C++ification. * ppc-obsd-nat.c (ppc_obsd_nat_target): New class. (the_ppc_obsd_nat_target): New. (ppcobsd_fetch_registers, ppcobsd_store_registers): Refactor as methods of ppc_obsd_nat_target. (_initialize_ppcobsd_nat): Adjust to C++ification. Use add_target. * sh-nbsd-nat.c (sh_nbsd_nat_target): New class. (the_sh_nbsd_nat_target): New. (shnbsd_fetch_inferior_registers) (shnbsd_store_inferior_registers): Refactor as methods of sh_nbsd_nat_target. (_initialize_shnbsd_nat): Adjust to C++ification. * sparc-nat.c (sparc_xfer_wcookie): Make extern. (inf_ptrace_xfer_partial): Delete. (sparc_xfer_partial, sparc_target): Delete. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers, sparc_xfer_wcookie): Declare. (sparc_target): Delete function declaration. (sparc_target): New template class. * sparc-nbsd-nat.c (the_sparc_nbsd_nat_target): New. (_initialize_sparcnbsd_nat): Adjust to C++ification. * sparc64-fbsd-nat.c (the_sparc64_fbsd_nat_target): New. (_initialize_sparc64fbsd_nat): Adjust to C++ification. Use add_target. * sparc64-nbsd-nat.c (the_sparc64_nbsd_nat_target): New. (_initialize_sparc64nbsd_nat): Adjust to C++ification. * sparc64-obsd-nat.c (the_sparc64_obsd_nat_target): New. (_initialize_sparc64obsd_nat): Adjust to C++ification. Use add_target. * vax-bsd-nat.c (vax_bsd_nat_target): New class. (the_vax_bsd_nat_target): New. (vaxbsd_fetch_inferior_registers) (vaxbsd_store_inferior_registers): Refactor as vax_bsd_nat_target methods. (_initialize_vaxbsd_nat): Adjust to C++ification. * bsd-kvm.c (bsd_kvm_target): New class. (bsd_kvm_ops): Now a bsd_kvm_target. (bsd_kvm_open, bsd_kvm_close, bsd_kvm_xfer_partial) (bsd_kvm_files_info, bsd_kvm_fetch_registers) (bsd_kvm_thread_alive, bsd_kvm_pid_to_str): Refactor as methods of bsd_kvm_target. (bsd_kvm_return_one): Delete. (bsd_kvm_add_target): Adjust to C++ification. * nto-procfs.c (nto_procfs_target, nto_procfs_target_native) (nto_procfs_target_procfs): New classes. (procfs_open_1, procfs_thread_alive, procfs_update_thread_list) (procfs_files_info, procfs_pid_to_exec_file, procfs_attach) (procfs_post_attach, procfs_wait, procfs_fetch_registers) (procfs_xfer_partial, procfs_detach, procfs_insert_breakpoint) (procfs_remove_breakpoint, procfs_insert_hw_breakpoint) (procfs_remove_hw_breakpoint, procfs_resume) (procfs_mourn_inferior, procfs_create_inferior, procfs_interrupt) (procfs_kill_inferior, procfs_store_registers) (procfs_pass_signals, procfs_pid_to_str, procfs_can_run): Refactor as methods of nto_procfs_target. (nto_procfs_ops): Now an nto_procfs_target_procfs. (nto_native_ops): Delete. (procfs_open, procfs_native_open): Delete. (nto_native_ops): Now an nto_procfs_target_native. (init_procfs_targets): Adjust to C++ification. (procfs_can_use_hw_breakpoint, procfs_remove_hw_watchpoint) (procfs_insert_hw_watchpoint, procfs_stopped_by_watchpoint): Refactor as methods of nto_procfs_target. * go32-nat.c (go32_nat_target): New class. (the_go32_nat_target): New. (go32_attach, go32_resume, go32_wait, go32_fetch_registers) (go32_store_registers, go32_xfer_partial, go32_files_info) (go32_kill_inferior, go32_create_inferior, go32_mourn_inferior) (go32_terminal_init, go32_terminal_info, go32_terminal_inferior) (go32_terminal_ours, go32_pass_ctrlc, go32_thread_alive) (go32_pid_to_str): Refactor as methods of go32_nat_target. (go32_target): Delete. (_initialize_go32_nat): Adjust to C++ification. * gnu-nat.c (gnu_wait, gnu_resume, gnu_kill_inferior) (gnu_mourn_inferior, gnu_create_inferior, gnu_attach, gnu_detach) (gnu_stop, gnu_thread_alive, gnu_xfer_partial) (gnu_find_memory_regions, gnu_pid_to_str): Refactor as methods of gnu_nat_target. (gnu_target): Delete. * gnu-nat.h (gnu_target): Delete. (gnu_nat_target): New class. * i386-gnu-nat.c (gnu_base_target): New. (i386_gnu_nat_target): New class. (the_i386_gnu_nat_target): New. (_initialize_i386gnu_nat): Adjust to C++ification. gdb/testsuite/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * gdb.base/breakpoint-in-ro-region.exp: Adjust to to_resume and to_log_command renames. * gdb.base/sss-bp-on-user-bp-2.exp: Likewise.
2018-05-03 07:37:22 +08:00
int
ppc_linux_nat_target::remove_hw_breakpoint (struct gdbarch *gdbarch,
struct bp_target_info *bp_tgt)
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
{
struct ppc_hw_breakpoint p;
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
m_dreg_interface.detect (inferior_ptid);
if (!m_dreg_interface.hwdebug_p ())
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
return -1;
p.version = PPC_DEBUG_CURRENT_VERSION;
p.trigger_type = PPC_BREAKPOINT_TRIGGER_EXECUTE;
p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
p.addr = (uint64_t) bp_tgt->placed_address;
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
p.condition_value = 0;
2011-03-31 Thiago Jung Bauermann <bauerman@br.ibm.com> Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Implement support for PowerPC BookE ranged breakpoints. gdb/ * NEWS: Mention support for ranged breakpoints on embedded PowerPC. * breakpoint.h (struct bp_target_info) <length>: New member variable. (struct breakpoint_ops) <breakpoint_hit>: Take struct bp_location instead of struct breakpoint as argument, and also add ASPACE and BP_ADDR arguments. Update all callers. (struct breakpoint_ops) <print_one_detail>: New method. (struct breakpoint) <addr_string_range_end>: New member variable. * breakpoint.c (breakpoint_location_address_match): Add function prototype. (insert_bp_location): Set bl->target_info.length. (breakpoint_here_p): Call breakpoint_location_address_match. (moribund_breakpoint_here_p): Likewise. (regular_breakpoint_inserted_here_p): Likewise. (breakpoint_thread_match): Likewise. (bpstat_stop_status): Likewise. (bpstat_check_location): Move call to breakpoint_ops.breakpoint_hit to the top. (print_one_breakpoint_location): Call breakpoint_ops.print_one_detail if available. (breakpoint_address_match_range): New function. (breakpoint_location_address_match): Likewise. (breakpoint_locations_match): Compare the length field of the locations too. (hw_breakpoint_used_count): Count resources used by all locations in a breakpoint, and use breakpoint_ops.resources_needed if available. (breakpoint_hit_ranged_breakpoint): New function. (resources_needed_ranged_breakpoint): Likewise. (print_it_ranged_breakpoint): Likewise. (print_one_ranged_breakpoint): Likewise. (print_one_detail_ranged_breakpoint): Likewise. (print_mention_ranged_breakpoint): Likewise. (print_recreate_ranged_breakpoint): Likewise. (ranged_breakpoint_ops): New structure. (find_breakpoint_range_end): New function. (break_range_command): Likewise. (delete_breakpoint): Free addr_string_range_end. (update_breakpoint_locations): Add SALS_END argument. Update all callers. Calculate breakpoint length if a non-zero SALS_END is given. Call breakpoint_locations_match instead of breakpoint_address_match. (reset_breakpoint): Find SaL of the end of the range if B is a ranged breakpoint. (_initialize_breakpoint): Register break-range command. * defs.h (print_core_address): Add function prototype. * ppc-linux-nat.c (ppc_linux_ranged_break_num_registers): New function. (ppc_linux_insert_hw_breakpoint): Support ranged breakpoints. (ppc_linux_remove_hw_breakpoint): Likewise. (_initialize_ppc_linux_nat): Initialize to_ranged_break_num_registers. * target.c (update_current_target): Add comment about to_ranged_break_num_registers. (target_ranged_break_num_registers): New function. * target.h (struct target_ops) <to_ranged_break_num_registers>: New method. (target_ranged_break_num_registers): Add function prototype. * ui-out.c (ui_out_field_core_addr): Move address-printing logic to ... * utils.c (print_core_address): ... here. gdb/doc/ * gdb.texinfo (PowerPC Embedded): Document ranged breakpoints.
2011-03-31 22:32:49 +08:00
if (bp_tgt->length)
{
p.addr_mode = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
/* The breakpoint will trigger if the address of the instruction is within
the defined range, as follows: p.addr <= address < p.addr2. */
p.addr2 = (uint64_t) bp_tgt->placed_address + bp_tgt->length;
}
else
{
p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
p.addr2 = 0;
}
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
clear_hw_breakpoint (inferior_ptid.pid (), p);
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
return 0;
}
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
/* Return the trigger value to set in a ppc_hw_breakpoint object for a
given hardware watchpoint TYPE. We assume type is not hw_execute. */
int
ppc_linux_nat_target::get_trigger_type (enum target_hw_bp_type type)
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
{
int t;
if (type == hw_read)
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
t = PPC_BREAKPOINT_TRIGGER_READ;
else if (type == hw_write)
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
t = PPC_BREAKPOINT_TRIGGER_WRITE;
else
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
t = PPC_BREAKPOINT_TRIGGER_READ | PPC_BREAKPOINT_TRIGGER_WRITE;
return t;
}
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
/* Register a new masked watchpoint at ADDR using the mask MASK, to be
inserted when the threads of inferior_ptid are resumed. RW may be
hw_read for a read watchpoint, hw_write for a write watchpoint or
hw_access for an access watchpoint. */
2011-05-06 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Implement support for PowerPC BookE masked watchpoints. gdb/ * NEWS: Mention masked watchpoint support. Create "Changed commands" section. * breakpoint.h (struct breakpoint_ops) <works_in_software_mode>: New method. Initialize to NULL in all existing breakpoint_ops instances. (struct breakpoint) <hw_wp_mask>: New field. * breakpoint.c (is_masked_watchpoint): Add prototype. (update_watchpoint): Don't set b->val for masked watchpoints. Call breakpoint's breakpoint_ops.works_in_software_mode if available. (watchpoints_triggered): Handle the case of a hardware masked watchpoint trigger. (watchpoint_check): Likewise. (works_in_software_mode_watchpoint): New function. (insert_masked_watchpoint, remove_masked_watchpoint) (resources_needed_masked_watchpoint) (works_in_software_mode_masked_watchpoint, print_it_masked_watchpoint) (print_one_detail_masked_watchpoint, print_mention_masked_watchpoint) (print_recreate_masked_watchpoint, is_masked_watchpoint): New functions. (masked_watchpoint_breakpoint_ops): New structure. (watch_command_1): Check for the existence of the `mask' parameter. Set b->ops according to the type of hardware watchpoint being created. * ppc-linux-nat.c (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_masked_watch_num_registers): New functions. (_initialize_ppc_linux_nat): Initialize to_insert_mask_watchpoint, to_remove_mask_watchpoint and to_masked_watch_num_registers. * target.c (update_current_target): Mention to_insert_mask_watchpoint, to_remove_mask_watchpoint, and to_masked_watch_num_registers. (target_insert_mask_watchpoint, target_remove_mask_watchpoint) (target_masked_watch_num_registers): New functions. * target.h (struct target_ops) <to_insert_mask_watchpoint>, <to_remove_mask_watchpoint>, <to_masked_watch_num_registers>: New methods. (target_insert_mask_watchpoint, target_remove_mask_watchpoint) (target_masked_watch_num_registers): Add prototypes. gdb/doc/ * gdb.texinfo (Set Watchpoints): Document mask parameter. (PowerPC Embedded): Mention support of masked watchpoints.
2011-05-07 02:46:33 +08:00
Convert struct target_ops to C++ I.e., use C++ virtual methods and inheritance instead of tables of function pointers. Unfortunately, there's no way to do a smooth transition. ALL native targets in the tree must be converted at the same time. I've tested all I could with cross compilers and with help from GCC compile farm, but naturally I haven't been able to test many of the ports. Still, I made a best effort to port everything over, and while I expect some build problems due to typos and such, which should be trivial to fix, I don't expect any design problems. * Implementation notes: - The flattened current_target is gone. References to current_target or current_target.beneath are replaced with references to target_stack (the top of the stack) directly. - To keep "set debug target" working, this adds a new debug_stratum layer that sits on top of the stack, prints the debug, and delegates to the target beneath. In addition, this makes the shortname and longname properties of target_ops be virtual methods instead of data fields, and makes the debug target defer those to the target beneath. This is so that debug code sprinkled around that does "if (debugtarget) ..." can transparently print the name of the target beneath. A patch later in the series actually splits out the shortname/longname methods to a separate structure, but I preferred to keep that chance separate as it is associated with changing a bit the design of how targets are registered and open. - Since you can't check whether a C++ virtual method is overridden, the old method of checking whether a target_ops implements a method by comparing the function pointer must be replaced with something else. Some cases are fixed by adding a parallel "can_do_foo" target_ops methods. E.g.,: + for (t = target_stack; t != NULL; t = t->beneath) { - if (t->to_create_inferior != NULL) + if (t->can_create_inferior ()) break; } Others are fixed by changing void return type to bool or int return type, and have the default implementation return false or -1, to indicate lack of support. - make-target-delegates was adjusted to generate C++ classes and methods. It needed tweaks to grok "virtual" in front of the target method name, and for the fact that methods are no longer function pointers. (In particular, the current code parsing the return type was simple because it could simply parse up until the '(' in '(*to_foo)'. It now generates a couple C++ classes that inherit target_ops: dummy_target and debug_target. Since we need to generate the class declarations as well, i.e., we need to emit methods twice, we now generate the code in two passes. - The core_target global is renamed to avoid conflict with the "core_target" class. - ctf/tfile targets init_tracefile_ops is replaced by a base class that is inherited by both ctf and tfile. - bsd-uthread The bsd_uthread_ops_hack hack is gone. It's not needed because nothing was extending a target created by bsd_uthread_target. - remote/extended-remote targets This is a first pass, just enough to C++ify target_ops. A later pass will convert more free functions to methods, and make remote_state be truly per remote instance, allowing multiple simultaneous instances of remote targets. - inf-child/"native" is converted to an actual base class (inf_child_target), that is inherited by all native targets. - GNU/Linux The old weird double-target linux_ops mechanism in linux-nat.c, is gone, replaced by adding a few virtual methods to linux-nat.h's target_ops, called low_XXX, that the concrete linux-nat implementations override. Sort of like gdbserver's linux_target_ops, but simpler, for requiring only one target_ops-like hierarchy, which spares implementing the same method twice when we need to forward the method to a low implementation. The low target simply reimplements the target_ops method directly in that case. There are a few remaining linux-nat.c hooks that would be better converted to low_ methods like above too. E.g.: linux_nat_set_new_thread (t, x86_linux_new_thread); linux_nat_set_new_fork (t, x86_linux_new_fork); linux_nat_set_forget_process That'll be done in a follow up patch. - We can no longer use functions like x86_use_watchpoints to install custom methods on an arbitrary base target. The patch replaces instances of such a pattern with template mixins. For example memory_breakpoint_target defined in target.h, or x86_nat_target in x86-nat.h. - linux_trad_target, MIPS and Alpha GNU/Linux The code in the new linux-nat-trad.h/c files which was split off of inf-ptrace.h/c recently, is converted to a C++ base class, and used by the MIPS and Alpha GNU/Linux ports. - BSD targets The $architecture x NetBSD/OpenBSD/FreeBSD support matrix complicates things a bit. There's common BSD target code, and there's common architecture-specific code shared between the different BSDs. Currently, all that is stiched together to form a final target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target functions etc. This introduces new fbsd_nat_target, obsd_nat_target and nbsd_nat_target classes that serve as base/prototype target for the corresponding BSD variant. And introduces generic i386/AMD64 BSD targets, to be used as template mixin to build a final target. Similarly, a generic SPARC target is added, used by both BSD and Linux ports. - bsd_kvm_add_target, BSD libkvm target I considered making bsd_kvm_supply_pcb a virtual method, and then have each port inherit bsd_kvm_target and override that method, but that was resulting in lots of unjustified churn, so I left the function pointer mechanism alone. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> John Baldwin <jhb@freebsd.org> * target.h (enum strata) <debug_stratum>: New. (struct target_ops) <all delegation methods>: Replace by C++ virtual methods, and drop "to_" prefix. All references updated throughout. <to_shortname, to_longname, to_doc, to_data, to_have_steppable_watchpoint, to_have_continuable_watchpoint, to_has_thread_control, to_attach_no_wait>: Delete, replaced by virtual methods. All references updated throughout. <can_attach, supports_terminal_ours, can_create_inferior, get_thread_control_capabilities, attach_no_wait>: New virtual methods. <insert_breakpoint, remove_breakpoint>: Now TARGET_DEFAULT_NORETURN methods. <info_proc>: Now returns bool. <to_magic>: Delete. (OPS_MAGIC): Delete. (current_target): Delete. All references replaced by references to ... (target_stack): ... this. New. (target_shortname, target_longname): Adjust. (target_can_run): Now a function declaration. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (memory_breakpoint_target): New template class. (test_target_ops): Refactor as a C++ class with virtual methods. * make-target-delegates (NAME_PART): Tighten. (POINTER_PART, CP_SYMBOL): New. (SIMPLE_RETURN_PART): Reimplement. (VEC_RETURN_PART): Expect less. (RETURN_PART, VIRTUAL_PART): New. (METHOD): Adjust to C++ virtual methods. (scan_target_h): Remove reference to C99. (dname): Output "target_ops::" prefix. (write_function_header): Adjust to output a C++ class method. (write_declaration): New. (write_delegator): Adjust to output a C++ class method. (tdname): Output "dummy_target::" prefix. (write_tdefault, write_debugmethod): Adjust to output a C++ class method. (tdefault_names, debug_names): Delete. (return_types, tdefaults, styles, argtypes_array): New. (top level): All methods are delegators. (print_class): New. (top level): Print dummy_target and debug_target classes. * target-delegates.c: Regenerate. * target-debug.h (target_debug_print_enum_info_proc_what) (target_debug_print_thread_control_capabilities) (target_debug_print_thread_info_p): New. * target.c (dummy_target): Delete. (the_dummy_target, the_debug_target): New. (target_stack): Now extern. (set_targetdebug): Push/unpush debug target. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (add_target_with_completer): No longer call complete_target_initialization. (target_supports_terminal_ours): Use regular delegation. (update_current_target): Delete. (push_target): No longer check magic number. Don't call update_current_target. (unpush_target): Don't call update_current_target. (target_is_pushed): No longer check magic number. (target_require_runnable): Skip for all stratums over process_stratum. (target_ops::info_proc): New. (target_info_proc): Use find_target_at and find_default_run_target. (target_supports_disable_randomization): Use regular delegation. (target_get_osdata): Use find_target_at. (target_ops::open, target_ops::close, target_ops::can_attach) (target_ops::attach, target_ops::can_create_inferior) (target_ops::create_inferior, target_ops::can_run) (target_can_run): New. (default_fileio_target): Use regular delegation. (target_ops::fileio_open, target_ops::fileio_pwrite) (target_ops::fileio_pread, target_ops::fileio_fstat) (target_ops::fileio_close, target_ops::fileio_unlink) (target_ops::fileio_readlink): New. (target_fileio_open_1, target_fileio_unlink) (target_fileio_readlink): Always call the target method. Handle FILEIO_ENOSYS. (return_zero, return_zero_has_execution): Delete. (init_dummy_target): Delete. (dummy_target::dummy_target, dummy_target::shortname) (dummy_target::longname, dummy_target::doc) (debug_target::debug_target, debug_target::shortname) (debug_target::longname, debug_target::doc): New. (target_supports_delete_record): Use regular delegation. (setup_target_debug): Delete. (maintenance_print_target_stack): Skip debug_stratum. (initialize_targets): Instantiate the_dummy_target and the_debug_target. * auxv.c (target_auxv_parse): Remove 'ops' parameter. Adjust to use target_stack. (target_auxv_search, fprint_target_auxv): Adjust. (info_auxv_command): Adjust to use target_stack. * auxv.h (target_auxv_parse): Remove 'ops' parameter. * exceptions.c (print_flush): Handle a NULL target_stack. * regcache.c (target_ops_no_register): Refactor as class with virtual methods. * exec.c (exec_target): New class. (exec_ops): Now an exec_target. (exec_open, exec_close_1, exec_get_section_table) (exec_xfer_partial, exec_files_info, exec_has_memory) (exec_make_note_section): Refactor as exec_target methods. (exec_file_clear, ignore, exec_remove_breakpoint, init_exec_ops): Delete. (exec_target::find_memory_regions): New. (_initialize_exec): Don't call init_exec_ops. * gdbcore.h (exec_file_clear): Delete. * corefile.c (core_target): Delete. (core_file_command): Adjust. * corelow.c (core_target): New class. (the_core_target): New. (core_close): Remove target_ops parameter. (core_close_cleanup): Adjust. (core_target::close): New. (core_open, core_detach, get_core_registers, core_files_info) (core_xfer_partial, core_thread_alive, core_read_description) (core_pid_to_str, core_thread_name, core_has_memory) (core_has_stack, core_has_registers, core_info_proc): Rework as core_target methods. (ignore, core_remove_breakpoint, init_core_ops): Delete. (_initialize_corelow): Initialize the_core_target. * gdbcore.h (core_target): Delete. (the_core_target): New. * ctf.c: (ctf_target): New class. (ctf_ops): Now a ctf_target. (ctf_open, ctf_close, ctf_files_info, ctf_fetch_registers) (ctf_xfer_partial, ctf_get_trace_state_variable_value) (ctf_trace_find, ctf_traceframe_info): Refactor as ctf_target methods. (init_ctf_ops): Delete. (_initialize_ctf): Don't call it. * tracefile-tfile.c (tfile_target): New class. (tfile_ops): Now a tfile_target. (tfile_open, tfile_close, tfile_files_info) (tfile_get_tracepoint_status, tfile_trace_find) (tfile_fetch_registers, tfile_xfer_partial) (tfile_get_trace_state_variable_value, tfile_traceframe_info): Refactor as tfile_target methods. (tfile_xfer_partial_features): Remove target_ops parameter. (init_tfile_ops): Delete. (_initialize_tracefile_tfile): Don't call it. * tracefile.c (tracefile_has_all_memory, tracefile_has_memory) (tracefile_has_stack, tracefile_has_registers) (tracefile_thread_alive, tracefile_get_trace_status): Refactor as tracefile_target methods. (init_tracefile_ops): Delete. (tracefile_target::tracefile_target): New. * tracefile.h: Include "target.h". (tracefile_target): New class. (init_tracefile_ops): Delete. * spu-multiarch.c (spu_multiarch_target): New class. (spu_ops): Now a spu_multiarch_target. (spu_thread_architecture, spu_region_ok_for_hw_watchpoint) (spu_fetch_registers, spu_store_registers, spu_xfer_partial) (spu_search_memory, spu_mourn_inferior): Refactor as spu_multiarch_target methods. (init_spu_ops): Delete. (_initialize_spu_multiarch): Remove references to init_spu_ops, complete_target_initialization. * ravenscar-thread.c (ravenscar_thread_target): New class. (ravenscar_ops): Now a ravenscar_thread_target. (ravenscar_resume, ravenscar_wait, ravenscar_update_thread_list) (ravenscar_thread_alive, ravenscar_pid_to_str) (ravenscar_fetch_registers, ravenscar_store_registers) (ravenscar_prepare_to_store, ravenscar_stopped_by_sw_breakpoint) (ravenscar_stopped_by_hw_breakpoint) (ravenscar_stopped_by_watchpoint, ravenscar_stopped_data_address) (ravenscar_mourn_inferior, ravenscar_core_of_thread) (ravenscar_get_ada_task_ptid): Refactor as ravenscar_thread_target methods. (init_ravenscar_thread_ops): Delete. (_initialize_ravenscar): Remove references to init_ravenscar_thread_ops and complete_target_initialization. * bsd-uthread.c (bsd_uthread_ops_hack): Delete. (bsd_uthread_target): New class. (bsd_uthread_ops): Now a bsd_uthread_target. (bsd_uthread_activate): Adjust to refer to bsd_uthread_ops. (bsd_uthread_close, bsd_uthread_mourn_inferior) (bsd_uthread_fetch_registers, bsd_uthread_store_registers) (bsd_uthread_wait, bsd_uthread_resume, bsd_uthread_thread_alive) (bsd_uthread_update_thread_list, bsd_uthread_extra_thread_info) (bsd_uthread_pid_to_str): Refactor as bsd_uthread_target methods. (bsd_uthread_target): Delete function. (_initialize_bsd_uthread): Remove reference to complete_target_initialization. * bfd-target.c (target_bfd_data): Delete. Fields folded into ... (target_bfd): ... this new class. (target_bfd_xfer_partial, target_bfd_get_section_table) (target_bfd_close): Refactor as target_bfd methods. (target_bfd::~target_bfd): New. (target_bfd_reopen): Adjust. (target_bfd::close): New. * record-btrace.c (record_btrace_target): New class. (record_btrace_ops): Now a record_btrace_target. (record_btrace_open, record_btrace_stop_recording) (record_btrace_disconnect, record_btrace_close) (record_btrace_async, record_btrace_info) (record_btrace_insn_history, record_btrace_insn_history_range) (record_btrace_insn_history_from, record_btrace_call_history) (record_btrace_call_history_range) (record_btrace_call_history_from, record_btrace_record_method) (record_btrace_is_replaying, record_btrace_will_replay) (record_btrace_xfer_partial, record_btrace_insert_breakpoint) (record_btrace_remove_breakpoint, record_btrace_fetch_registers) (record_btrace_store_registers, record_btrace_prepare_to_store) (record_btrace_to_get_unwinder) (record_btrace_to_get_tailcall_unwinder, record_btrace_resume) (record_btrace_commit_resume, record_btrace_wait) (record_btrace_stop, record_btrace_can_execute_reverse) (record_btrace_stopped_by_sw_breakpoint) (record_btrace_supports_stopped_by_sw_breakpoint) (record_btrace_stopped_by_hw_breakpoint) (record_btrace_supports_stopped_by_hw_breakpoint) (record_btrace_update_thread_list, record_btrace_thread_alive) (record_btrace_goto_begin, record_btrace_goto_end) (record_btrace_goto, record_btrace_stop_replaying_all) (record_btrace_execution_direction) (record_btrace_prepare_to_generate_core) (record_btrace_done_generating_core): Refactor as record_btrace_target methods. (init_record_btrace_ops): Delete. (_initialize_record_btrace): Remove reference to init_record_btrace_ops. * record-full.c (RECORD_FULL_IS_REPLAY): Adjust to always refer to the execution_direction global. (record_full_base_target, record_full_target) (record_full_core_target): New classes. (record_full_ops): Now a record_full_target. (record_full_core_ops): Now a record_full_core_target. (record_full_target::detach, record_full_target::disconnect) (record_full_core_target::disconnect) (record_full_target::mourn_inferior, record_full_target::kill): New. (record_full_open, record_full_close, record_full_async): Refactor as methods of the record_full_base_target class. (record_full_resume, record_full_commit_resume): Refactor as methods of the record_full_target class. (record_full_wait, record_full_stopped_by_watchpoint) (record_full_stopped_data_address) (record_full_stopped_by_sw_breakpoint) (record_full_supports_stopped_by_sw_breakpoint) (record_full_stopped_by_hw_breakpoint) (record_full_supports_stopped_by_hw_breakpoint): Refactor as methods of the record_full_base_target class. (record_full_store_registers, record_full_xfer_partial) (record_full_insert_breakpoint, record_full_remove_breakpoint): Refactor as methods of the record_full_target class. (record_full_can_execute_reverse, record_full_get_bookmark) (record_full_goto_bookmark, record_full_execution_direction) (record_full_record_method, record_full_info, record_full_delete) (record_full_is_replaying, record_full_will_replay) (record_full_goto_begin, record_full_goto_end, record_full_goto) (record_full_stop_replaying): Refactor as methods of the record_full_base_target class. (record_full_core_resume, record_full_core_kill) (record_full_core_fetch_registers) (record_full_core_prepare_to_store) (record_full_core_store_registers, record_full_core_xfer_partial) (record_full_core_insert_breakpoint) (record_full_core_remove_breakpoint) (record_full_core_has_execution): Refactor as methods of the record_full_core_target class. (record_full_base_target::supports_delete_record): New. (init_record_full_ops): Delete. (init_record_full_core_ops): Delete. (record_full_save): Refactor as method of the record_full_base_target class. (_initialize_record_full): Remove references to init_record_full_ops and init_record_full_core_ops. * remote.c (remote_target, extended_remote_target): New classes. (remote_ops): Now a remote_target. (extended_remote_ops): Now an extended_remote_target. (remote_insert_fork_catchpoint, remote_remove_fork_catchpoint) (remote_insert_vfork_catchpoint, remote_remove_vfork_catchpoint) (remote_insert_exec_catchpoint, remote_remove_exec_catchpoint) (remote_pass_signals, remote_set_syscall_catchpoint) (remote_program_signals, ) (remote_thread_always_alive): Remove target_ops parameter. (remote_thread_alive, remote_thread_name) (remote_update_thread_list, remote_threads_extra_info) (remote_static_tracepoint_marker_at) (remote_static_tracepoint_markers_by_strid) (remote_get_ada_task_ptid, remote_close, remote_start_remote) (remote_open): Refactor as methods of remote_target. (extended_remote_open, extended_remote_detach) (extended_remote_attach, extended_remote_post_attach): (extended_remote_supports_disable_randomization) (extended_remote_create_inferior): : Refactor as method of extended_remote_target. (remote_set_permissions, remote_open_1, remote_detach) (remote_follow_fork, remote_follow_exec, remote_disconnect) (remote_resume, remote_commit_resume, remote_stop) (remote_interrupt, remote_pass_ctrlc, remote_terminal_inferior) (remote_terminal_ours, remote_wait, remote_fetch_registers) (remote_prepare_to_store, remote_store_registers) (remote_flash_erase, remote_flash_done, remote_files_info) (remote_kill, remote_mourn, remote_insert_breakpoint) (remote_remove_breakpoint, remote_insert_watchpoint) (remote_watchpoint_addr_within_range) (remote_remove_watchpoint, remote_region_ok_for_hw_watchpoint) (remote_check_watch_resources, remote_stopped_by_sw_breakpoint) (remote_supports_stopped_by_sw_breakpoint) (remote_stopped_by_hw_breakpoint) (remote_supports_stopped_by_hw_breakpoint) (remote_stopped_by_watchpoint, remote_stopped_data_address) (remote_insert_hw_breakpoint, remote_remove_hw_breakpoint) (remote_verify_memory): Refactor as methods of remote_target. (remote_write_qxfer, remote_read_qxfer): Remove target_ops parameter. (remote_xfer_partial, remote_get_memory_xfer_limit) (remote_search_memory, remote_rcmd, remote_memory_map) (remote_pid_to_str, remote_get_thread_local_address) (remote_get_tib_address, remote_read_description): Refactor as methods of remote_target. (remote_target::fileio_open, remote_target::fileio_pwrite) (remote_target::fileio_pread, remote_target::fileio_close): New. (remote_hostio_readlink, remote_hostio_fstat) (remote_filesystem_is_local, remote_can_execute_reverse) (remote_supports_non_stop, remote_supports_disable_randomization) (remote_supports_multi_process, remote_supports_cond_breakpoints) (remote_supports_enable_disable_tracepoint) (remote_supports_string_tracing) (remote_can_run_breakpoint_commands, remote_trace_init) (remote_download_tracepoint, remote_can_download_tracepoint) (remote_download_trace_state_variable, remote_enable_tracepoint) (remote_disable_tracepoint, remote_trace_set_readonly_regions) (remote_trace_start, remote_get_trace_status) (remote_get_tracepoint_status, remote_trace_stop) (remote_trace_find, remote_get_trace_state_variable_value) (remote_save_trace_data, remote_get_raw_trace_data) (remote_set_disconnected_tracing, remote_core_of_thread) (remote_set_circular_trace_buffer, remote_traceframe_info) (remote_get_min_fast_tracepoint_insn_len) (remote_set_trace_buffer_size, remote_set_trace_notes) (remote_use_agent, remote_can_use_agent, remote_enable_btrace) (remote_disable_btrace, remote_teardown_btrace) (remote_read_btrace, remote_btrace_conf) (remote_augmented_libraries_svr4_read, remote_load) (remote_pid_to_exec_file, remote_can_do_single_step) (remote_execution_direction, remote_thread_handle_to_thread_info): Refactor as methods of remote_target. (init_remote_ops, init_extended_remote_ops): Delete. (remote_can_async_p, remote_is_async_p, remote_async) (remote_thread_events, remote_upload_tracepoints) (remote_upload_trace_state_variables): Refactor as methods of remote_target. (_initialize_remote): Remove references to init_remote_ops and init_extended_remote_ops. * remote-sim.c (gdbsim_target): New class. (gdbsim_fetch_register, gdbsim_store_register, gdbsim_kill) (gdbsim_load, gdbsim_create_inferior, gdbsim_open, gdbsim_close) (gdbsim_detach, gdbsim_resume, gdbsim_interrupt) (gdbsim_wait, gdbsim_prepare_to_store, gdbsim_xfer_partial) (gdbsim_files_info, gdbsim_mourn_inferior, gdbsim_thread_alive) (gdbsim_pid_to_str, gdbsim_has_all_memory, gdbsim_has_memory): Refactor as methods of gdbsim_target. (gdbsim_ops): Now a gdbsim_target. (init_gdbsim_ops): Delete. (gdbsim_cntrl_c): Adjust. (_initialize_remote_sim): Remove reference to init_gdbsim_ops. * amd64-linux-nat.c (amd64_linux_nat_target): New class. (the_amd64_linux_nat_target): New. (amd64_linux_fetch_inferior_registers) (amd64_linux_store_inferior_registers): Refactor as methods of amd64_linux_nat_target. (_initialize_amd64_linux_nat): Adjust. Set linux_target. * i386-linux-nat.c: Don't include "linux-nat.h". (i386_linux_nat_target): New class. (the_i386_linux_nat_target): New. (i386_linux_fetch_inferior_registers) (i386_linux_store_inferior_registers, i386_linux_resume): Refactor as methods of i386_linux_nat_target. (_initialize_i386_linux_nat): Adjust. Set linux_target. * inf-child.c (inf_child_ops): Delete. (inf_child_fetch_inferior_registers) (inf_child_store_inferior_registers): Delete. (inf_child_post_attach, inf_child_prepare_to_store): Refactor as methods of inf_child_target. (inf_child_target::supports_terminal_ours) (inf_child_target::terminal_init) (inf_child_target::terminal_inferior) (inf_child_target::terminal_ours_for_output) (inf_child_target::terminal_ours, inf_child_target::interrupt) (inf_child_target::pass_ctrlc, inf_child_target::terminal_info): New. (inf_child_open, inf_child_disconnect, inf_child_close) (inf_child_mourn_inferior, inf_child_maybe_unpush_target) (inf_child_post_startup_inferior, inf_child_can_run) (inf_child_pid_to_exec_file): Refactor as methods of inf_child_target. (inf_child_follow_fork): Delete. (inf_child_target::can_create_inferior) (inf_child_target::can_attach): New. (inf_child_target::has_all_memory, inf_child_target::has_memory) (inf_child_target::has_stack, inf_child_target::has_registers) (inf_child_target::has_execution): New. (inf_child_fileio_open, inf_child_fileio_pwrite) (inf_child_fileio_pread, inf_child_fileio_fstat) (inf_child_fileio_close, inf_child_fileio_unlink) (inf_child_fileio_readlink, inf_child_use_agent) (inf_child_can_use_agent): Refactor as methods of inf_child_target. (return_zero, inf_child_target): Delete. (inf_child_target::inf_child_target): New. * inf-child.h: Include "target.h". (inf_child_target): Delete function prototype. (inf_child_target): New class. (inf_child_open_target, inf_child_mourn_inferior) (inf_child_maybe_unpush_target): Delete. * inf-ptrace.c (inf_ptrace_target::~inf_ptrace_target): New. (inf_ptrace_follow_fork, inf_ptrace_insert_fork_catchpoint) (inf_ptrace_remove_fork_catchpoint, inf_ptrace_create_inferior) (inf_ptrace_post_startup_inferior, inf_ptrace_mourn_inferior) (inf_ptrace_attach, inf_ptrace_post_attach, inf_ptrace_detach) (inf_ptrace_detach_success, inf_ptrace_kill, inf_ptrace_resume) (inf_ptrace_wait, inf_ptrace_xfer_partial) (inf_ptrace_thread_alive, inf_ptrace_files_info) (inf_ptrace_pid_to_str, inf_ptrace_auxv_parse): Refactor as methods of inf_ptrace_target. (inf_ptrace_target): Delete function. * inf-ptrace.h: Include "inf-child.h". (inf_ptrace_target): Delete function declaration. (inf_ptrace_target): New class. (inf_ptrace_trad_target, inf_ptrace_detach_success): Delete. * linux-nat.c (linux_target): New. (linux_ops, linux_ops_saved, super_xfer_partial): Delete. (linux_nat_target::~linux_nat_target): New. (linux_child_post_attach, linux_child_post_startup_inferior) (linux_child_follow_fork, linux_child_insert_fork_catchpoint) (linux_child_remove_fork_catchpoint) (linux_child_insert_vfork_catchpoint) (linux_child_remove_vfork_catchpoint) (linux_child_insert_exec_catchpoint) (linux_child_remove_exec_catchpoint) (linux_child_set_syscall_catchpoint, linux_nat_pass_signals) (linux_nat_create_inferior, linux_nat_attach, linux_nat_detach) (linux_nat_resume, linux_nat_stopped_by_watchpoint) (linux_nat_stopped_data_address) (linux_nat_stopped_by_sw_breakpoint) (linux_nat_supports_stopped_by_sw_breakpoint) (linux_nat_stopped_by_hw_breakpoint) (linux_nat_supports_stopped_by_hw_breakpoint, linux_nat_wait) (linux_nat_kill, linux_nat_mourn_inferior) (linux_nat_xfer_partial, linux_nat_thread_alive) (linux_nat_update_thread_list, linux_nat_pid_to_str) (linux_nat_thread_name, linux_child_pid_to_exec_file) (linux_child_static_tracepoint_markers_by_strid) (linux_nat_is_async_p, linux_nat_can_async_p) (linux_nat_supports_non_stop, linux_nat_always_non_stop_p) (linux_nat_supports_multi_process) (linux_nat_supports_disable_randomization, linux_nat_async) (linux_nat_stop, linux_nat_close, linux_nat_thread_address_space) (linux_nat_core_of_thread, linux_nat_filesystem_is_local) (linux_nat_fileio_open, linux_nat_fileio_readlink) (linux_nat_fileio_unlink, linux_nat_thread_events): Refactor as methods of linux_nat_target. (linux_nat_wait_1, linux_xfer_siginfo, linux_proc_xfer_partial) (linux_proc_xfer_spu, linux_nat_xfer_osdata): Remove target_ops parameter. (check_stopped_by_watchpoint): Adjust. (linux_xfer_partial): Delete. (linux_target_install_ops, linux_target, linux_nat_add_target): Delete. (linux_nat_target::linux_nat_target): New. * linux-nat.h: Include "inf-ptrace.h". (linux_nat_target): New. (linux_target, linux_target_install_ops, linux_nat_add_target): Delete function declarations. (linux_target): Declare global. * linux-thread-db.c (thread_db_target): New. (thread_db_target::thread_db_target): New. (thread_db_ops): Delete. (the_thread_db_target): New. (thread_db_detach, thread_db_wait, thread_db_mourn_inferior) (thread_db_update_thread_list, thread_db_pid_to_str) (thread_db_extra_thread_info) (thread_db_thread_handle_to_thread_info) (thread_db_get_thread_local_address, thread_db_get_ada_task_ptid) (thread_db_resume): Refactor as methods of thread_db_target. (init_thread_db_ops): Delete. (_initialize_thread_db): Remove reference to init_thread_db_ops. * x86-linux-nat.c: Don't include "linux-nat.h". (super_post_startup_inferior): Delete. (x86_linux_nat_target::~x86_linux_nat_target): New. (x86_linux_child_post_startup_inferior) (x86_linux_read_description, x86_linux_enable_btrace) (x86_linux_disable_btrace, x86_linux_teardown_btrace) (x86_linux_read_btrace, x86_linux_btrace_conf): Refactor as methods of x86_linux_nat_target. (x86_linux_create_target): Delete. Bits folded ... (x86_linux_add_target): ... here. Now takes a linux_nat_target pointer. * x86-linux-nat.h: Include "linux-nat.h" and "x86-nat.h". (x86_linux_nat_target): New class. (x86_linux_create_target): Delete. (x86_linux_add_target): Now takes a linux_nat_target pointer. * x86-nat.c (x86_insert_watchpoint, x86_remove_watchpoint) (x86_region_ok_for_watchpoint, x86_stopped_data_address) (x86_stopped_by_watchpoint, x86_insert_hw_breakpoint) (x86_remove_hw_breakpoint, x86_can_use_hw_breakpoint) (x86_stopped_by_hw_breakpoint): Remove target_ops parameter and make extern. (x86_use_watchpoints): Delete. * x86-nat.h: Include "breakpoint.h" and "target.h". (x86_use_watchpoints): Delete. (x86_can_use_hw_breakpoint, x86_region_ok_for_hw_watchpoint) (x86_stopped_by_watchpoint, x86_stopped_data_address) (x86_insert_watchpoint, x86_remove_watchpoint) (x86_insert_hw_breakpoint, x86_remove_hw_breakpoint) (x86_stopped_by_hw_breakpoint): New declarations. (x86_nat_target): New template class. * ppc-linux-nat.c (ppc_linux_nat_target): New class. (the_ppc_linux_nat_target): New. (ppc_linux_fetch_inferior_registers) (ppc_linux_can_use_hw_breakpoint) (ppc_linux_region_ok_for_hw_watchpoint) (ppc_linux_ranged_break_num_registers) (ppc_linux_insert_hw_breakpoint, ppc_linux_remove_hw_breakpoint) (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_can_accel_watchpoint_condition) (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint) (ppc_linux_stopped_data_address, ppc_linux_stopped_by_watchpoint) (ppc_linux_watchpoint_addr_within_range) (ppc_linux_masked_watch_num_registers) (ppc_linux_store_inferior_registers, ppc_linux_auxv_parse) (ppc_linux_read_description): Refactor as methods of ppc_linux_nat_target. (_initialize_ppc_linux_nat): Adjust. Set linux_target. * procfs.c (procfs_xfer_partial): Delete forward declaration. (procfs_target): New class. (the_procfs_target): New. (procfs_target): Delete function. (procfs_auxv_parse, procfs_attach, procfs_detach) (procfs_fetch_registers, procfs_store_registers, procfs_wait) (procfs_xfer_partial, procfs_resume, procfs_pass_signals) (procfs_files_info, procfs_kill_inferior, procfs_mourn_inferior) (procfs_create_inferior, procfs_update_thread_list) (procfs_thread_alive, procfs_pid_to_str) (procfs_can_use_hw_breakpoint, procfs_stopped_by_watchpoint) (procfs_stopped_data_address, procfs_insert_watchpoint) (procfs_remove_watchpoint, procfs_region_ok_for_hw_watchpoint) (proc_find_memory_regions, procfs_info_proc) (procfs_make_note_section): Refactor as methods of procfs_target. (_initialize_procfs): Adjust. * sol-thread.c (sol_thread_target): New class. (sol_thread_ops): Now a sol_thread_target. (sol_thread_detach, sol_thread_resume, sol_thread_wait) (sol_thread_fetch_registers, sol_thread_store_registers) (sol_thread_xfer_partial, sol_thread_mourn_inferior) (sol_thread_alive, solaris_pid_to_str, sol_update_thread_list) (sol_get_ada_task_ptid): Refactor as methods of sol_thread_target. (init_sol_thread_ops): Delete. (_initialize_sol_thread): Adjust. Remove references to init_sol_thread_ops and complete_target_initialization. * windows-nat.c (windows_nat_target): New class. (windows_fetch_inferior_registers) (windows_store_inferior_registers, windows_resume, windows_wait) (windows_attach, windows_detach, windows_pid_to_exec_file) (windows_files_info, windows_create_inferior) (windows_mourn_inferior, windows_interrupt, windows_kill_inferior) (windows_close, windows_pid_to_str, windows_xfer_partial) (windows_get_tib_address, windows_get_ada_task_ptid) (windows_thread_name, windows_thread_alive): Refactor as windows_nat_target methods. (do_initial_windows_stuff): Adjust. (windows_target): Delete function. (_initialize_windows_nat): Adjust. * darwin-nat.c (darwin_resume, darwin_wait_to, darwin_interrupt) (darwin_mourn_inferior, darwin_kill_inferior) (darwin_create_inferior, darwin_attach, darwin_detach) (darwin_pid_to_str, darwin_thread_alive, darwin_xfer_partial) (darwin_pid_to_exec_file, darwin_get_ada_task_ptid) (darwin_supports_multi_process): Refactor as darwin_nat_target methods. (darwin_resume_to, darwin_files_info): Delete. (_initialize_darwin_inferior): Rename to ... (_initialize_darwin_nat): ... this. Adjust to C++ification. * darwin-nat.h: Include "inf-child.h". (darwin_nat_target): New class. (darwin_complete_target): Delete. * i386-darwin-nat.c (i386_darwin_nat_target): New class. (darwin_target): New. (i386_darwin_fetch_inferior_registers) (i386_darwin_store_inferior_registers): Refactor as methods of darwin_nat_target. (darwin_complete_target): Delete, with ... (_initialize_i386_darwin_nat): ... bits factored out here. * alpha-linux-nat.c (alpha_linux_nat_target): New class. (the_alpha_linux_nat_target): New. (alpha_linux_register_u_offset): Refactor as alpha_linux_nat_target method. (_initialize_alpha_linux_nat): Adjust. * linux-nat-trad.c (inf_ptrace_register_u_offset): Delete. (inf_ptrace_fetch_register, inf_ptrace_fetch_registers) (inf_ptrace_store_register, inf_ptrace_store_registers): Refact as methods of linux_nat_trad_target. (linux_trad_target): Delete. * linux-nat-trad.h (linux_trad_target): Delete function. (linux_nat_trad_target): New class. * mips-linux-nat.c (mips_linux_nat_target): New class. (super_fetch_registers, super_store_registers, super_close): Delete. (the_mips_linux_nat_target): New. (mips64_linux_regsets_fetch_registers) (mips64_linux_regsets_store_registers) (mips64_linux_fetch_registers, mips64_linux_store_registers) (mips_linux_register_u_offset, mips_linux_read_description) (mips_linux_can_use_hw_breakpoint) (mips_linux_stopped_by_watchpoint) (mips_linux_stopped_data_address) (mips_linux_region_ok_for_hw_watchpoint) (mips_linux_insert_watchpoint, mips_linux_remove_watchpoint) (mips_linux_close): Refactor as methods of mips_linux_nat. (_initialize_mips_linux_nat): Adjust to C++ification. * aix-thread.c (aix_thread_target): New class. (aix_thread_ops): Now an aix_thread_target. (aix_thread_detach, aix_thread_resume, aix_thread_wait) (aix_thread_fetch_registers, aix_thread_store_registers) (aix_thread_xfer_partial, aix_thread_mourn_inferior) (aix_thread_thread_alive, aix_thread_pid_to_str) (aix_thread_extra_thread_info, aix_thread_get_ada_task_ptid): Refactor as methods of aix_thread_target. (init_aix_thread_ops): Delete. (_initialize_aix_thread): Remove references to init_aix_thread_ops and complete_target_initialization. * rs6000-nat.c (rs6000_xfer_shared_libraries): Delete. (rs6000_nat_target): New class. (the_rs6000_nat_target): New. (rs6000_fetch_inferior_registers, rs6000_store_inferior_registers) (rs6000_xfer_partial, rs6000_wait, rs6000_create_inferior) (rs6000_xfer_shared_libraries): Refactor as rs6000_nat_target methods. (super_create_inferior): Delete. (_initialize_rs6000_nat): Adjust to C++ification. * arm-linux-nat.c (arm_linux_nat_target): New class. (the_arm_linux_nat_target): New. (arm_linux_fetch_inferior_registers) (arm_linux_store_inferior_registers, arm_linux_read_description) (arm_linux_can_use_hw_breakpoint, arm_linux_insert_hw_breakpoint) (arm_linux_remove_hw_breakpoint) (arm_linux_region_ok_for_hw_watchpoint) (arm_linux_insert_watchpoint, arm_linux_remove_watchpoint) (arm_linux_stopped_data_address, arm_linux_stopped_by_watchpoint) (arm_linux_watchpoint_addr_within_range): Refactor as methods of arm_linux_nat_target. (_initialize_arm_linux_nat): Adjust to C++ification. * aarch64-linux-nat.c (aarch64_linux_nat_target): New class. (the_aarch64_linux_nat_target): New. (aarch64_linux_fetch_inferior_registers) (aarch64_linux_store_inferior_registers) (aarch64_linux_child_post_startup_inferior) (aarch64_linux_read_description) (aarch64_linux_can_use_hw_breakpoint) (aarch64_linux_insert_hw_breakpoint) (aarch64_linux_remove_hw_breakpoint) (aarch64_linux_insert_watchpoint, aarch64_linux_remove_watchpoint) (aarch64_linux_region_ok_for_hw_watchpoint) (aarch64_linux_stopped_data_address) (aarch64_linux_stopped_by_watchpoint) (aarch64_linux_watchpoint_addr_within_range) (aarch64_linux_can_do_single_step): Refactor as methods of aarch64_linux_nat_target. (super_post_startup_inferior): Delete. (_initialize_aarch64_linux_nat): Adjust to C++ification. * hppa-linux-nat.c (hppa_linux_nat_target): New class. (the_hppa_linux_nat_target): New. (hppa_linux_fetch_inferior_registers) (hppa_linux_store_inferior_registers): Refactor as methods of hppa_linux_nat_target. (_initialize_hppa_linux_nat): Adjust to C++ification. * ia64-linux-nat.c (ia64_linux_nat_target): New class. (the_ia64_linux_nat_target): New. (ia64_linux_insert_watchpoint, ia64_linux_remove_watchpoint) (ia64_linux_stopped_data_address) (ia64_linux_stopped_by_watchpoint, ia64_linux_fetch_registers) (ia64_linux_store_registers, ia64_linux_xfer_partial): Refactor as ia64_linux_nat_target methods. (super_xfer_partial): Delete. (_initialize_ia64_linux_nat): Adjust to C++ification. * m32r-linux-nat.c (m32r_linux_nat_target): New class. (the_m32r_linux_nat_target): New. (m32r_linux_fetch_inferior_registers) (m32r_linux_store_inferior_registers): Refactor as m32r_linux_nat_target methods. (_initialize_m32r_linux_nat): Adjust to C++ification. * m68k-linux-nat.c (m68k_linux_nat_target): New class. (the_m68k_linux_nat_target): New. (m68k_linux_fetch_inferior_registers) (m68k_linux_store_inferior_registers): Refactor as m68k_linux_nat_target methods. (_initialize_m68k_linux_nat): Adjust to C++ification. * s390-linux-nat.c (s390_linux_nat_target): New class. (the_s390_linux_nat_target): New. (s390_linux_fetch_inferior_registers) (s390_linux_store_inferior_registers, s390_stopped_by_watchpoint) (s390_insert_watchpoint, s390_remove_watchpoint) (s390_can_use_hw_breakpoint, s390_insert_hw_breakpoint) (s390_remove_hw_breakpoint, s390_region_ok_for_hw_watchpoint) (s390_auxv_parse, s390_read_description): Refactor as methods of s390_linux_nat_target. (_initialize_s390_nat): Adjust to C++ification. * sparc-linux-nat.c (sparc_linux_nat_target): New class. (the_sparc_linux_nat_target): New. (_initialize_sparc_linux_nat): Adjust to C++ification. * sparc-nat.c (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc64-linux-nat.c (sparc64_linux_nat_target): New class. (the_sparc64_linux_nat_target): New. (_initialize_sparc64_linux_nat): Adjust to C++ification. * spu-linux-nat.c (spu_linux_nat_target): New class. (the_spu_linux_nat_target): New. (spu_child_post_startup_inferior, spu_child_post_attach) (spu_child_wait, spu_fetch_inferior_registers) (spu_store_inferior_registers, spu_xfer_partial) (spu_can_use_hw_breakpoint): Refactor as spu_linux_nat_target methods. (_initialize_spu_nat): Adjust to C++ification. * tilegx-linux-nat.c (tilegx_linux_nat_target): New class. (the_tilegx_linux_nat_target): New. (fetch_inferior_registers, store_inferior_registers): Refactor as methods. (_initialize_tile_linux_nat): Adjust to C++ification. * xtensa-linux-nat.c (xtensa_linux_nat_target): New class. (the_xtensa_linux_nat_target): New. (xtensa_linux_fetch_inferior_registers) (xtensa_linux_store_inferior_registers): Refactor as xtensa_linux_nat_target methods. (_initialize_xtensa_linux_nat): Adjust to C++ification. * fbsd-nat.c (USE_SIGTRAP_SIGINFO): Delete. (fbsd_pid_to_exec_file, fbsd_find_memory_regions) (fbsd_find_memory_regions, fbsd_info_proc, fbsd_xfer_partial) (fbsd_thread_alive, fbsd_pid_to_str, fbsd_thread_name) (fbsd_update_thread_list, fbsd_resume, fbsd_wait) (fbsd_stopped_by_sw_breakpoint) (fbsd_supports_stopped_by_sw_breakpoint, fbsd_follow_fork) (fbsd_insert_fork_catchpoint, fbsd_remove_fork_catchpoint) (fbsd_insert_vfork_catchpoint, fbsd_remove_vfork_catchpoint) (fbsd_post_startup_inferior, fbsd_post_attach) (fbsd_insert_exec_catchpoint, fbsd_remove_exec_catchpoint) (fbsd_set_syscall_catchpoint) (super_xfer_partial, super_resume, super_wait) (fbsd_supports_stopped_by_hw_breakpoint): Delete. (fbsd_handle_debug_trap): Remove target_ops parameter. (fbsd_nat_add_target): Delete. * fbsd-nat.h: Include "inf-ptrace.h". (fbsd_nat_add_target): Delete. (USE_SIGTRAP_SIGINFO): Define. (fbsd_nat_target): New class. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers) (amd64bsd_store_inferior_registers): Remove target_ops parameter. (amd64bsd_target): Delete. * amd64-bsd-nat.h: New file. * amd64-fbsd-nat.c: Include "amd64-bsd-nat.h" instead of "x86-bsd-nat.h". (amd64_fbsd_nat_target): New class. (the_amd64_fbsd_nat_target): New. (amd64fbsd_read_description): Refactor as method of amd64_fbsd_nat_target. (amd64_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_amd64fbsd_nat): Adjust to C++ification. * amd64-nat.h (amd64bsd_target): Delete function declaration. * i386-bsd-nat.c (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Remove target_ops parameter. (i386bsd_target): Delete. * i386-bsd-nat.h (i386bsd_target): Delete function declaration. (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Declare. (i386_bsd_nat_target): New class. * i386-fbsd-nat.c (i386_fbsd_nat_target): New class. (the_i386_fbsd_nat_target): New. (i386fbsd_resume, i386fbsd_read_description): Refactor as i386_fbsd_nat_target methods. (i386_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_i386fbsd_nat): Adjust to C++ification. * x86-bsd-nat.c (super_mourn_inferior): Delete. (x86bsd_mourn_inferior, x86bsd_target): Delete. (_initialize_x86_bsd_nat): Adjust to C++ification. * x86-bsd-nat.h: Include "x86-nat.h". (x86bsd_target): Delete declaration. (x86bsd_nat_target): New class. * aarch64-fbsd-nat.c (aarch64_fbsd_nat_target): New class. (the_aarch64_fbsd_nat_target): New. (aarch64_fbsd_fetch_inferior_registers) (aarch64_fbsd_store_inferior_registers): Refactor as methods of aarch64_fbsd_nat_target. (_initialize_aarch64_fbsd_nat): Adjust to C++ification. * alpha-bsd-nat.c (alpha_bsd_nat_target): New class. (the_alpha_bsd_nat_target): New. (alphabsd_fetch_inferior_registers) (alphabsd_store_inferior_registers): Refactor as alpha_bsd_nat_target methods. (_initialize_alphabsd_nat): Refactor as methods of alpha_bsd_nat_target. * amd64-nbsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_nbsd_nat_target): New. (_initialize_amd64nbsd_nat): Adjust to C++ification. * amd64-obsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_obsd_nat_target): New. (_initialize_amd64obsd_nat): Adjust to C++ification. * arm-fbsd-nat.c (arm_fbsd_nat_target): New. (the_arm_fbsd_nat_target): New. (arm_fbsd_fetch_inferior_registers) (arm_fbsd_store_inferior_registers, arm_fbsd_read_description): (_initialize_arm_fbsd_nat): Refactor as methods of arm_fbsd_nat_target. (_initialize_arm_fbsd_nat): Adjust to C++ification. * arm-nbsd-nat.c (arm_netbsd_nat_target): New class. (the_arm_netbsd_nat_target): New. (armnbsd_fetch_registers, armnbsd_store_registers): Refactor as arm_netbsd_nat_target. (_initialize_arm_netbsd_nat): Adjust to C++ification. * hppa-nbsd-nat.c (hppa_nbsd_nat_target): New class. (the_hppa_nbsd_nat_target): New. (hppanbsd_fetch_registers, hppanbsd_store_registers): Refactor as hppa_nbsd_nat_target methods. (_initialize_hppanbsd_nat): Adjust to C++ification. * hppa-obsd-nat.c (hppa_obsd_nat_target): New class. (the_hppa_obsd_nat_target): New. (hppaobsd_fetch_registers, hppaobsd_store_registers): Refactor as methods of hppa_obsd_nat_target. (_initialize_hppaobsd_nat): Adjust to C++ification. Use add_target. * i386-nbsd-nat.c (the_i386_nbsd_nat_target): New. (_initialize_i386nbsd_nat): Adjust to C++ification. Use add_target. * i386-obsd-nat.c (the_i386_obsd_nat_target): New. (_initialize_i386obsd_nat): Use add_target. * m68k-bsd-nat.c (m68k_bsd_nat_target): New class. (the_m68k_bsd_nat_target): New. (m68kbsd_fetch_inferior_registers) (m68kbsd_store_inferior_registers): Refactor as methods of m68k_bsd_nat_target. (_initialize_m68kbsd_nat): Adjust to C++ification. * mips-fbsd-nat.c (mips_fbsd_nat_target): New class. (the_mips_fbsd_nat_target): New. (mips_fbsd_fetch_inferior_registers) (mips_fbsd_store_inferior_registers): Refactor as methods of mips_fbsd_nat_target. (_initialize_mips_fbsd_nat): Adjust to C++ification. Use add_target. * mips-nbsd-nat.c (mips_nbsd_nat_target): New class. (the_mips_nbsd_nat_target): New. (mipsnbsd_fetch_inferior_registers) (mipsnbsd_store_inferior_registers): Refactor as methods of mips_nbsd_nat_target. (_initialize_mipsnbsd_nat): Adjust to C++ification. * mips64-obsd-nat.c (mips64_obsd_nat_target): New class. (the_mips64_obsd_nat_target): New. (mips64obsd_fetch_inferior_registers) (mips64obsd_store_inferior_registers): Refactor as methods of mips64_obsd_nat_target. (_initialize_mips64obsd_nat): Adjust to C++ification. Use add_target. * nbsd-nat.c (nbsd_pid_to_exec_file): Refactor as method of nbsd_nat_target. * nbsd-nat.h: Include "inf-ptrace.h". (nbsd_nat_target): New class. * obsd-nat.c (obsd_pid_to_str, obsd_update_thread_list) (obsd_wait): Refactor as methods of obsd_nat_target. (obsd_add_target): Delete. * obsd-nat.h: Include "inf-ptrace.h". (obsd_nat_target): New class. * ppc-fbsd-nat.c (ppc_fbsd_nat_target): New class. (the_ppc_fbsd_nat_target): New. (ppcfbsd_fetch_inferior_registers) (ppcfbsd_store_inferior_registers): Refactor as methods of ppc_fbsd_nat_target. (_initialize_ppcfbsd_nat): Adjust to C++ification. Use add_target. * ppc-nbsd-nat.c (ppc_nbsd_nat_target): New class. (the_ppc_nbsd_nat_target): New. (ppcnbsd_fetch_inferior_registers) (ppcnbsd_store_inferior_registers): Refactor as methods of ppc_nbsd_nat_target. (_initialize_ppcnbsd_nat): Adjust to C++ification. * ppc-obsd-nat.c (ppc_obsd_nat_target): New class. (the_ppc_obsd_nat_target): New. (ppcobsd_fetch_registers, ppcobsd_store_registers): Refactor as methods of ppc_obsd_nat_target. (_initialize_ppcobsd_nat): Adjust to C++ification. Use add_target. * sh-nbsd-nat.c (sh_nbsd_nat_target): New class. (the_sh_nbsd_nat_target): New. (shnbsd_fetch_inferior_registers) (shnbsd_store_inferior_registers): Refactor as methods of sh_nbsd_nat_target. (_initialize_shnbsd_nat): Adjust to C++ification. * sparc-nat.c (sparc_xfer_wcookie): Make extern. (inf_ptrace_xfer_partial): Delete. (sparc_xfer_partial, sparc_target): Delete. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers, sparc_xfer_wcookie): Declare. (sparc_target): Delete function declaration. (sparc_target): New template class. * sparc-nbsd-nat.c (the_sparc_nbsd_nat_target): New. (_initialize_sparcnbsd_nat): Adjust to C++ification. * sparc64-fbsd-nat.c (the_sparc64_fbsd_nat_target): New. (_initialize_sparc64fbsd_nat): Adjust to C++ification. Use add_target. * sparc64-nbsd-nat.c (the_sparc64_nbsd_nat_target): New. (_initialize_sparc64nbsd_nat): Adjust to C++ification. * sparc64-obsd-nat.c (the_sparc64_obsd_nat_target): New. (_initialize_sparc64obsd_nat): Adjust to C++ification. Use add_target. * vax-bsd-nat.c (vax_bsd_nat_target): New class. (the_vax_bsd_nat_target): New. (vaxbsd_fetch_inferior_registers) (vaxbsd_store_inferior_registers): Refactor as vax_bsd_nat_target methods. (_initialize_vaxbsd_nat): Adjust to C++ification. * bsd-kvm.c (bsd_kvm_target): New class. (bsd_kvm_ops): Now a bsd_kvm_target. (bsd_kvm_open, bsd_kvm_close, bsd_kvm_xfer_partial) (bsd_kvm_files_info, bsd_kvm_fetch_registers) (bsd_kvm_thread_alive, bsd_kvm_pid_to_str): Refactor as methods of bsd_kvm_target. (bsd_kvm_return_one): Delete. (bsd_kvm_add_target): Adjust to C++ification. * nto-procfs.c (nto_procfs_target, nto_procfs_target_native) (nto_procfs_target_procfs): New classes. (procfs_open_1, procfs_thread_alive, procfs_update_thread_list) (procfs_files_info, procfs_pid_to_exec_file, procfs_attach) (procfs_post_attach, procfs_wait, procfs_fetch_registers) (procfs_xfer_partial, procfs_detach, procfs_insert_breakpoint) (procfs_remove_breakpoint, procfs_insert_hw_breakpoint) (procfs_remove_hw_breakpoint, procfs_resume) (procfs_mourn_inferior, procfs_create_inferior, procfs_interrupt) (procfs_kill_inferior, procfs_store_registers) (procfs_pass_signals, procfs_pid_to_str, procfs_can_run): Refactor as methods of nto_procfs_target. (nto_procfs_ops): Now an nto_procfs_target_procfs. (nto_native_ops): Delete. (procfs_open, procfs_native_open): Delete. (nto_native_ops): Now an nto_procfs_target_native. (init_procfs_targets): Adjust to C++ification. (procfs_can_use_hw_breakpoint, procfs_remove_hw_watchpoint) (procfs_insert_hw_watchpoint, procfs_stopped_by_watchpoint): Refactor as methods of nto_procfs_target. * go32-nat.c (go32_nat_target): New class. (the_go32_nat_target): New. (go32_attach, go32_resume, go32_wait, go32_fetch_registers) (go32_store_registers, go32_xfer_partial, go32_files_info) (go32_kill_inferior, go32_create_inferior, go32_mourn_inferior) (go32_terminal_init, go32_terminal_info, go32_terminal_inferior) (go32_terminal_ours, go32_pass_ctrlc, go32_thread_alive) (go32_pid_to_str): Refactor as methods of go32_nat_target. (go32_target): Delete. (_initialize_go32_nat): Adjust to C++ification. * gnu-nat.c (gnu_wait, gnu_resume, gnu_kill_inferior) (gnu_mourn_inferior, gnu_create_inferior, gnu_attach, gnu_detach) (gnu_stop, gnu_thread_alive, gnu_xfer_partial) (gnu_find_memory_regions, gnu_pid_to_str): Refactor as methods of gnu_nat_target. (gnu_target): Delete. * gnu-nat.h (gnu_target): Delete. (gnu_nat_target): New class. * i386-gnu-nat.c (gnu_base_target): New. (i386_gnu_nat_target): New class. (the_i386_gnu_nat_target): New. (_initialize_i386gnu_nat): Adjust to C++ification. gdb/testsuite/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * gdb.base/breakpoint-in-ro-region.exp: Adjust to to_resume and to_log_command renames. * gdb.base/sss-bp-on-user-bp-2.exp: Likewise.
2018-05-03 07:37:22 +08:00
int
ppc_linux_nat_target::insert_mask_watchpoint (CORE_ADDR addr, CORE_ADDR mask,
target_hw_bp_type rw)
2011-05-06 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Implement support for PowerPC BookE masked watchpoints. gdb/ * NEWS: Mention masked watchpoint support. Create "Changed commands" section. * breakpoint.h (struct breakpoint_ops) <works_in_software_mode>: New method. Initialize to NULL in all existing breakpoint_ops instances. (struct breakpoint) <hw_wp_mask>: New field. * breakpoint.c (is_masked_watchpoint): Add prototype. (update_watchpoint): Don't set b->val for masked watchpoints. Call breakpoint's breakpoint_ops.works_in_software_mode if available. (watchpoints_triggered): Handle the case of a hardware masked watchpoint trigger. (watchpoint_check): Likewise. (works_in_software_mode_watchpoint): New function. (insert_masked_watchpoint, remove_masked_watchpoint) (resources_needed_masked_watchpoint) (works_in_software_mode_masked_watchpoint, print_it_masked_watchpoint) (print_one_detail_masked_watchpoint, print_mention_masked_watchpoint) (print_recreate_masked_watchpoint, is_masked_watchpoint): New functions. (masked_watchpoint_breakpoint_ops): New structure. (watch_command_1): Check for the existence of the `mask' parameter. Set b->ops according to the type of hardware watchpoint being created. * ppc-linux-nat.c (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_masked_watch_num_registers): New functions. (_initialize_ppc_linux_nat): Initialize to_insert_mask_watchpoint, to_remove_mask_watchpoint and to_masked_watch_num_registers. * target.c (update_current_target): Mention to_insert_mask_watchpoint, to_remove_mask_watchpoint, and to_masked_watch_num_registers. (target_insert_mask_watchpoint, target_remove_mask_watchpoint) (target_masked_watch_num_registers): New functions. * target.h (struct target_ops) <to_insert_mask_watchpoint>, <to_remove_mask_watchpoint>, <to_masked_watch_num_registers>: New methods. (target_insert_mask_watchpoint, target_remove_mask_watchpoint) (target_masked_watch_num_registers): Add prototypes. gdb/doc/ * gdb.texinfo (Set Watchpoints): Document mask parameter. (PowerPC Embedded): Mention support of masked watchpoints.
2011-05-07 02:46:33 +08:00
{
struct ppc_hw_breakpoint p;
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
gdb_assert (m_dreg_interface.hwdebug_p ());
2011-05-06 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Implement support for PowerPC BookE masked watchpoints. gdb/ * NEWS: Mention masked watchpoint support. Create "Changed commands" section. * breakpoint.h (struct breakpoint_ops) <works_in_software_mode>: New method. Initialize to NULL in all existing breakpoint_ops instances. (struct breakpoint) <hw_wp_mask>: New field. * breakpoint.c (is_masked_watchpoint): Add prototype. (update_watchpoint): Don't set b->val for masked watchpoints. Call breakpoint's breakpoint_ops.works_in_software_mode if available. (watchpoints_triggered): Handle the case of a hardware masked watchpoint trigger. (watchpoint_check): Likewise. (works_in_software_mode_watchpoint): New function. (insert_masked_watchpoint, remove_masked_watchpoint) (resources_needed_masked_watchpoint) (works_in_software_mode_masked_watchpoint, print_it_masked_watchpoint) (print_one_detail_masked_watchpoint, print_mention_masked_watchpoint) (print_recreate_masked_watchpoint, is_masked_watchpoint): New functions. (masked_watchpoint_breakpoint_ops): New structure. (watch_command_1): Check for the existence of the `mask' parameter. Set b->ops according to the type of hardware watchpoint being created. * ppc-linux-nat.c (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_masked_watch_num_registers): New functions. (_initialize_ppc_linux_nat): Initialize to_insert_mask_watchpoint, to_remove_mask_watchpoint and to_masked_watch_num_registers. * target.c (update_current_target): Mention to_insert_mask_watchpoint, to_remove_mask_watchpoint, and to_masked_watch_num_registers. (target_insert_mask_watchpoint, target_remove_mask_watchpoint) (target_masked_watch_num_registers): New functions. * target.h (struct target_ops) <to_insert_mask_watchpoint>, <to_remove_mask_watchpoint>, <to_masked_watch_num_registers>: New methods. (target_insert_mask_watchpoint, target_remove_mask_watchpoint) (target_masked_watch_num_registers): Add prototypes. gdb/doc/ * gdb.texinfo (Set Watchpoints): Document mask parameter. (PowerPC Embedded): Mention support of masked watchpoints.
2011-05-07 02:46:33 +08:00
p.version = PPC_DEBUG_CURRENT_VERSION;
p.trigger_type = get_trigger_type (rw);
p.addr_mode = PPC_BREAKPOINT_MODE_MASK;
p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
p.addr = addr;
p.addr2 = mask;
p.condition_value = 0;
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
register_hw_breakpoint (inferior_ptid.pid (), p);
2011-05-06 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Implement support for PowerPC BookE masked watchpoints. gdb/ * NEWS: Mention masked watchpoint support. Create "Changed commands" section. * breakpoint.h (struct breakpoint_ops) <works_in_software_mode>: New method. Initialize to NULL in all existing breakpoint_ops instances. (struct breakpoint) <hw_wp_mask>: New field. * breakpoint.c (is_masked_watchpoint): Add prototype. (update_watchpoint): Don't set b->val for masked watchpoints. Call breakpoint's breakpoint_ops.works_in_software_mode if available. (watchpoints_triggered): Handle the case of a hardware masked watchpoint trigger. (watchpoint_check): Likewise. (works_in_software_mode_watchpoint): New function. (insert_masked_watchpoint, remove_masked_watchpoint) (resources_needed_masked_watchpoint) (works_in_software_mode_masked_watchpoint, print_it_masked_watchpoint) (print_one_detail_masked_watchpoint, print_mention_masked_watchpoint) (print_recreate_masked_watchpoint, is_masked_watchpoint): New functions. (masked_watchpoint_breakpoint_ops): New structure. (watch_command_1): Check for the existence of the `mask' parameter. Set b->ops according to the type of hardware watchpoint being created. * ppc-linux-nat.c (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_masked_watch_num_registers): New functions. (_initialize_ppc_linux_nat): Initialize to_insert_mask_watchpoint, to_remove_mask_watchpoint and to_masked_watch_num_registers. * target.c (update_current_target): Mention to_insert_mask_watchpoint, to_remove_mask_watchpoint, and to_masked_watch_num_registers. (target_insert_mask_watchpoint, target_remove_mask_watchpoint) (target_masked_watch_num_registers): New functions. * target.h (struct target_ops) <to_insert_mask_watchpoint>, <to_remove_mask_watchpoint>, <to_masked_watch_num_registers>: New methods. (target_insert_mask_watchpoint, target_remove_mask_watchpoint) (target_masked_watch_num_registers): Add prototypes. gdb/doc/ * gdb.texinfo (Set Watchpoints): Document mask parameter. (PowerPC Embedded): Mention support of masked watchpoints.
2011-05-07 02:46:33 +08:00
return 0;
}
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
/* Clear a registration for a masked watchpoint at ADDR with the mask
MASK. It will be removed from the threads of inferior_ptid when they
are next resumed. RW may be hw_read for a read watchpoint, hw_write
for a write watchpoint or hw_access for an access watchpoint. */
2011-05-06 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Implement support for PowerPC BookE masked watchpoints. gdb/ * NEWS: Mention masked watchpoint support. Create "Changed commands" section. * breakpoint.h (struct breakpoint_ops) <works_in_software_mode>: New method. Initialize to NULL in all existing breakpoint_ops instances. (struct breakpoint) <hw_wp_mask>: New field. * breakpoint.c (is_masked_watchpoint): Add prototype. (update_watchpoint): Don't set b->val for masked watchpoints. Call breakpoint's breakpoint_ops.works_in_software_mode if available. (watchpoints_triggered): Handle the case of a hardware masked watchpoint trigger. (watchpoint_check): Likewise. (works_in_software_mode_watchpoint): New function. (insert_masked_watchpoint, remove_masked_watchpoint) (resources_needed_masked_watchpoint) (works_in_software_mode_masked_watchpoint, print_it_masked_watchpoint) (print_one_detail_masked_watchpoint, print_mention_masked_watchpoint) (print_recreate_masked_watchpoint, is_masked_watchpoint): New functions. (masked_watchpoint_breakpoint_ops): New structure. (watch_command_1): Check for the existence of the `mask' parameter. Set b->ops according to the type of hardware watchpoint being created. * ppc-linux-nat.c (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_masked_watch_num_registers): New functions. (_initialize_ppc_linux_nat): Initialize to_insert_mask_watchpoint, to_remove_mask_watchpoint and to_masked_watch_num_registers. * target.c (update_current_target): Mention to_insert_mask_watchpoint, to_remove_mask_watchpoint, and to_masked_watch_num_registers. (target_insert_mask_watchpoint, target_remove_mask_watchpoint) (target_masked_watch_num_registers): New functions. * target.h (struct target_ops) <to_insert_mask_watchpoint>, <to_remove_mask_watchpoint>, <to_masked_watch_num_registers>: New methods. (target_insert_mask_watchpoint, target_remove_mask_watchpoint) (target_masked_watch_num_registers): Add prototypes. gdb/doc/ * gdb.texinfo (Set Watchpoints): Document mask parameter. (PowerPC Embedded): Mention support of masked watchpoints.
2011-05-07 02:46:33 +08:00
Convert struct target_ops to C++ I.e., use C++ virtual methods and inheritance instead of tables of function pointers. Unfortunately, there's no way to do a smooth transition. ALL native targets in the tree must be converted at the same time. I've tested all I could with cross compilers and with help from GCC compile farm, but naturally I haven't been able to test many of the ports. Still, I made a best effort to port everything over, and while I expect some build problems due to typos and such, which should be trivial to fix, I don't expect any design problems. * Implementation notes: - The flattened current_target is gone. References to current_target or current_target.beneath are replaced with references to target_stack (the top of the stack) directly. - To keep "set debug target" working, this adds a new debug_stratum layer that sits on top of the stack, prints the debug, and delegates to the target beneath. In addition, this makes the shortname and longname properties of target_ops be virtual methods instead of data fields, and makes the debug target defer those to the target beneath. This is so that debug code sprinkled around that does "if (debugtarget) ..." can transparently print the name of the target beneath. A patch later in the series actually splits out the shortname/longname methods to a separate structure, but I preferred to keep that chance separate as it is associated with changing a bit the design of how targets are registered and open. - Since you can't check whether a C++ virtual method is overridden, the old method of checking whether a target_ops implements a method by comparing the function pointer must be replaced with something else. Some cases are fixed by adding a parallel "can_do_foo" target_ops methods. E.g.,: + for (t = target_stack; t != NULL; t = t->beneath) { - if (t->to_create_inferior != NULL) + if (t->can_create_inferior ()) break; } Others are fixed by changing void return type to bool or int return type, and have the default implementation return false or -1, to indicate lack of support. - make-target-delegates was adjusted to generate C++ classes and methods. It needed tweaks to grok "virtual" in front of the target method name, and for the fact that methods are no longer function pointers. (In particular, the current code parsing the return type was simple because it could simply parse up until the '(' in '(*to_foo)'. It now generates a couple C++ classes that inherit target_ops: dummy_target and debug_target. Since we need to generate the class declarations as well, i.e., we need to emit methods twice, we now generate the code in two passes. - The core_target global is renamed to avoid conflict with the "core_target" class. - ctf/tfile targets init_tracefile_ops is replaced by a base class that is inherited by both ctf and tfile. - bsd-uthread The bsd_uthread_ops_hack hack is gone. It's not needed because nothing was extending a target created by bsd_uthread_target. - remote/extended-remote targets This is a first pass, just enough to C++ify target_ops. A later pass will convert more free functions to methods, and make remote_state be truly per remote instance, allowing multiple simultaneous instances of remote targets. - inf-child/"native" is converted to an actual base class (inf_child_target), that is inherited by all native targets. - GNU/Linux The old weird double-target linux_ops mechanism in linux-nat.c, is gone, replaced by adding a few virtual methods to linux-nat.h's target_ops, called low_XXX, that the concrete linux-nat implementations override. Sort of like gdbserver's linux_target_ops, but simpler, for requiring only one target_ops-like hierarchy, which spares implementing the same method twice when we need to forward the method to a low implementation. The low target simply reimplements the target_ops method directly in that case. There are a few remaining linux-nat.c hooks that would be better converted to low_ methods like above too. E.g.: linux_nat_set_new_thread (t, x86_linux_new_thread); linux_nat_set_new_fork (t, x86_linux_new_fork); linux_nat_set_forget_process That'll be done in a follow up patch. - We can no longer use functions like x86_use_watchpoints to install custom methods on an arbitrary base target. The patch replaces instances of such a pattern with template mixins. For example memory_breakpoint_target defined in target.h, or x86_nat_target in x86-nat.h. - linux_trad_target, MIPS and Alpha GNU/Linux The code in the new linux-nat-trad.h/c files which was split off of inf-ptrace.h/c recently, is converted to a C++ base class, and used by the MIPS and Alpha GNU/Linux ports. - BSD targets The $architecture x NetBSD/OpenBSD/FreeBSD support matrix complicates things a bit. There's common BSD target code, and there's common architecture-specific code shared between the different BSDs. Currently, all that is stiched together to form a final target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target functions etc. This introduces new fbsd_nat_target, obsd_nat_target and nbsd_nat_target classes that serve as base/prototype target for the corresponding BSD variant. And introduces generic i386/AMD64 BSD targets, to be used as template mixin to build a final target. Similarly, a generic SPARC target is added, used by both BSD and Linux ports. - bsd_kvm_add_target, BSD libkvm target I considered making bsd_kvm_supply_pcb a virtual method, and then have each port inherit bsd_kvm_target and override that method, but that was resulting in lots of unjustified churn, so I left the function pointer mechanism alone. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> John Baldwin <jhb@freebsd.org> * target.h (enum strata) <debug_stratum>: New. (struct target_ops) <all delegation methods>: Replace by C++ virtual methods, and drop "to_" prefix. All references updated throughout. <to_shortname, to_longname, to_doc, to_data, to_have_steppable_watchpoint, to_have_continuable_watchpoint, to_has_thread_control, to_attach_no_wait>: Delete, replaced by virtual methods. All references updated throughout. <can_attach, supports_terminal_ours, can_create_inferior, get_thread_control_capabilities, attach_no_wait>: New virtual methods. <insert_breakpoint, remove_breakpoint>: Now TARGET_DEFAULT_NORETURN methods. <info_proc>: Now returns bool. <to_magic>: Delete. (OPS_MAGIC): Delete. (current_target): Delete. All references replaced by references to ... (target_stack): ... this. New. (target_shortname, target_longname): Adjust. (target_can_run): Now a function declaration. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (memory_breakpoint_target): New template class. (test_target_ops): Refactor as a C++ class with virtual methods. * make-target-delegates (NAME_PART): Tighten. (POINTER_PART, CP_SYMBOL): New. (SIMPLE_RETURN_PART): Reimplement. (VEC_RETURN_PART): Expect less. (RETURN_PART, VIRTUAL_PART): New. (METHOD): Adjust to C++ virtual methods. (scan_target_h): Remove reference to C99. (dname): Output "target_ops::" prefix. (write_function_header): Adjust to output a C++ class method. (write_declaration): New. (write_delegator): Adjust to output a C++ class method. (tdname): Output "dummy_target::" prefix. (write_tdefault, write_debugmethod): Adjust to output a C++ class method. (tdefault_names, debug_names): Delete. (return_types, tdefaults, styles, argtypes_array): New. (top level): All methods are delegators. (print_class): New. (top level): Print dummy_target and debug_target classes. * target-delegates.c: Regenerate. * target-debug.h (target_debug_print_enum_info_proc_what) (target_debug_print_thread_control_capabilities) (target_debug_print_thread_info_p): New. * target.c (dummy_target): Delete. (the_dummy_target, the_debug_target): New. (target_stack): Now extern. (set_targetdebug): Push/unpush debug target. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (add_target_with_completer): No longer call complete_target_initialization. (target_supports_terminal_ours): Use regular delegation. (update_current_target): Delete. (push_target): No longer check magic number. Don't call update_current_target. (unpush_target): Don't call update_current_target. (target_is_pushed): No longer check magic number. (target_require_runnable): Skip for all stratums over process_stratum. (target_ops::info_proc): New. (target_info_proc): Use find_target_at and find_default_run_target. (target_supports_disable_randomization): Use regular delegation. (target_get_osdata): Use find_target_at. (target_ops::open, target_ops::close, target_ops::can_attach) (target_ops::attach, target_ops::can_create_inferior) (target_ops::create_inferior, target_ops::can_run) (target_can_run): New. (default_fileio_target): Use regular delegation. (target_ops::fileio_open, target_ops::fileio_pwrite) (target_ops::fileio_pread, target_ops::fileio_fstat) (target_ops::fileio_close, target_ops::fileio_unlink) (target_ops::fileio_readlink): New. (target_fileio_open_1, target_fileio_unlink) (target_fileio_readlink): Always call the target method. Handle FILEIO_ENOSYS. (return_zero, return_zero_has_execution): Delete. (init_dummy_target): Delete. (dummy_target::dummy_target, dummy_target::shortname) (dummy_target::longname, dummy_target::doc) (debug_target::debug_target, debug_target::shortname) (debug_target::longname, debug_target::doc): New. (target_supports_delete_record): Use regular delegation. (setup_target_debug): Delete. (maintenance_print_target_stack): Skip debug_stratum. (initialize_targets): Instantiate the_dummy_target and the_debug_target. * auxv.c (target_auxv_parse): Remove 'ops' parameter. Adjust to use target_stack. (target_auxv_search, fprint_target_auxv): Adjust. (info_auxv_command): Adjust to use target_stack. * auxv.h (target_auxv_parse): Remove 'ops' parameter. * exceptions.c (print_flush): Handle a NULL target_stack. * regcache.c (target_ops_no_register): Refactor as class with virtual methods. * exec.c (exec_target): New class. (exec_ops): Now an exec_target. (exec_open, exec_close_1, exec_get_section_table) (exec_xfer_partial, exec_files_info, exec_has_memory) (exec_make_note_section): Refactor as exec_target methods. (exec_file_clear, ignore, exec_remove_breakpoint, init_exec_ops): Delete. (exec_target::find_memory_regions): New. (_initialize_exec): Don't call init_exec_ops. * gdbcore.h (exec_file_clear): Delete. * corefile.c (core_target): Delete. (core_file_command): Adjust. * corelow.c (core_target): New class. (the_core_target): New. (core_close): Remove target_ops parameter. (core_close_cleanup): Adjust. (core_target::close): New. (core_open, core_detach, get_core_registers, core_files_info) (core_xfer_partial, core_thread_alive, core_read_description) (core_pid_to_str, core_thread_name, core_has_memory) (core_has_stack, core_has_registers, core_info_proc): Rework as core_target methods. (ignore, core_remove_breakpoint, init_core_ops): Delete. (_initialize_corelow): Initialize the_core_target. * gdbcore.h (core_target): Delete. (the_core_target): New. * ctf.c: (ctf_target): New class. (ctf_ops): Now a ctf_target. (ctf_open, ctf_close, ctf_files_info, ctf_fetch_registers) (ctf_xfer_partial, ctf_get_trace_state_variable_value) (ctf_trace_find, ctf_traceframe_info): Refactor as ctf_target methods. (init_ctf_ops): Delete. (_initialize_ctf): Don't call it. * tracefile-tfile.c (tfile_target): New class. (tfile_ops): Now a tfile_target. (tfile_open, tfile_close, tfile_files_info) (tfile_get_tracepoint_status, tfile_trace_find) (tfile_fetch_registers, tfile_xfer_partial) (tfile_get_trace_state_variable_value, tfile_traceframe_info): Refactor as tfile_target methods. (tfile_xfer_partial_features): Remove target_ops parameter. (init_tfile_ops): Delete. (_initialize_tracefile_tfile): Don't call it. * tracefile.c (tracefile_has_all_memory, tracefile_has_memory) (tracefile_has_stack, tracefile_has_registers) (tracefile_thread_alive, tracefile_get_trace_status): Refactor as tracefile_target methods. (init_tracefile_ops): Delete. (tracefile_target::tracefile_target): New. * tracefile.h: Include "target.h". (tracefile_target): New class. (init_tracefile_ops): Delete. * spu-multiarch.c (spu_multiarch_target): New class. (spu_ops): Now a spu_multiarch_target. (spu_thread_architecture, spu_region_ok_for_hw_watchpoint) (spu_fetch_registers, spu_store_registers, spu_xfer_partial) (spu_search_memory, spu_mourn_inferior): Refactor as spu_multiarch_target methods. (init_spu_ops): Delete. (_initialize_spu_multiarch): Remove references to init_spu_ops, complete_target_initialization. * ravenscar-thread.c (ravenscar_thread_target): New class. (ravenscar_ops): Now a ravenscar_thread_target. (ravenscar_resume, ravenscar_wait, ravenscar_update_thread_list) (ravenscar_thread_alive, ravenscar_pid_to_str) (ravenscar_fetch_registers, ravenscar_store_registers) (ravenscar_prepare_to_store, ravenscar_stopped_by_sw_breakpoint) (ravenscar_stopped_by_hw_breakpoint) (ravenscar_stopped_by_watchpoint, ravenscar_stopped_data_address) (ravenscar_mourn_inferior, ravenscar_core_of_thread) (ravenscar_get_ada_task_ptid): Refactor as ravenscar_thread_target methods. (init_ravenscar_thread_ops): Delete. (_initialize_ravenscar): Remove references to init_ravenscar_thread_ops and complete_target_initialization. * bsd-uthread.c (bsd_uthread_ops_hack): Delete. (bsd_uthread_target): New class. (bsd_uthread_ops): Now a bsd_uthread_target. (bsd_uthread_activate): Adjust to refer to bsd_uthread_ops. (bsd_uthread_close, bsd_uthread_mourn_inferior) (bsd_uthread_fetch_registers, bsd_uthread_store_registers) (bsd_uthread_wait, bsd_uthread_resume, bsd_uthread_thread_alive) (bsd_uthread_update_thread_list, bsd_uthread_extra_thread_info) (bsd_uthread_pid_to_str): Refactor as bsd_uthread_target methods. (bsd_uthread_target): Delete function. (_initialize_bsd_uthread): Remove reference to complete_target_initialization. * bfd-target.c (target_bfd_data): Delete. Fields folded into ... (target_bfd): ... this new class. (target_bfd_xfer_partial, target_bfd_get_section_table) (target_bfd_close): Refactor as target_bfd methods. (target_bfd::~target_bfd): New. (target_bfd_reopen): Adjust. (target_bfd::close): New. * record-btrace.c (record_btrace_target): New class. (record_btrace_ops): Now a record_btrace_target. (record_btrace_open, record_btrace_stop_recording) (record_btrace_disconnect, record_btrace_close) (record_btrace_async, record_btrace_info) (record_btrace_insn_history, record_btrace_insn_history_range) (record_btrace_insn_history_from, record_btrace_call_history) (record_btrace_call_history_range) (record_btrace_call_history_from, record_btrace_record_method) (record_btrace_is_replaying, record_btrace_will_replay) (record_btrace_xfer_partial, record_btrace_insert_breakpoint) (record_btrace_remove_breakpoint, record_btrace_fetch_registers) (record_btrace_store_registers, record_btrace_prepare_to_store) (record_btrace_to_get_unwinder) (record_btrace_to_get_tailcall_unwinder, record_btrace_resume) (record_btrace_commit_resume, record_btrace_wait) (record_btrace_stop, record_btrace_can_execute_reverse) (record_btrace_stopped_by_sw_breakpoint) (record_btrace_supports_stopped_by_sw_breakpoint) (record_btrace_stopped_by_hw_breakpoint) (record_btrace_supports_stopped_by_hw_breakpoint) (record_btrace_update_thread_list, record_btrace_thread_alive) (record_btrace_goto_begin, record_btrace_goto_end) (record_btrace_goto, record_btrace_stop_replaying_all) (record_btrace_execution_direction) (record_btrace_prepare_to_generate_core) (record_btrace_done_generating_core): Refactor as record_btrace_target methods. (init_record_btrace_ops): Delete. (_initialize_record_btrace): Remove reference to init_record_btrace_ops. * record-full.c (RECORD_FULL_IS_REPLAY): Adjust to always refer to the execution_direction global. (record_full_base_target, record_full_target) (record_full_core_target): New classes. (record_full_ops): Now a record_full_target. (record_full_core_ops): Now a record_full_core_target. (record_full_target::detach, record_full_target::disconnect) (record_full_core_target::disconnect) (record_full_target::mourn_inferior, record_full_target::kill): New. (record_full_open, record_full_close, record_full_async): Refactor as methods of the record_full_base_target class. (record_full_resume, record_full_commit_resume): Refactor as methods of the record_full_target class. (record_full_wait, record_full_stopped_by_watchpoint) (record_full_stopped_data_address) (record_full_stopped_by_sw_breakpoint) (record_full_supports_stopped_by_sw_breakpoint) (record_full_stopped_by_hw_breakpoint) (record_full_supports_stopped_by_hw_breakpoint): Refactor as methods of the record_full_base_target class. (record_full_store_registers, record_full_xfer_partial) (record_full_insert_breakpoint, record_full_remove_breakpoint): Refactor as methods of the record_full_target class. (record_full_can_execute_reverse, record_full_get_bookmark) (record_full_goto_bookmark, record_full_execution_direction) (record_full_record_method, record_full_info, record_full_delete) (record_full_is_replaying, record_full_will_replay) (record_full_goto_begin, record_full_goto_end, record_full_goto) (record_full_stop_replaying): Refactor as methods of the record_full_base_target class. (record_full_core_resume, record_full_core_kill) (record_full_core_fetch_registers) (record_full_core_prepare_to_store) (record_full_core_store_registers, record_full_core_xfer_partial) (record_full_core_insert_breakpoint) (record_full_core_remove_breakpoint) (record_full_core_has_execution): Refactor as methods of the record_full_core_target class. (record_full_base_target::supports_delete_record): New. (init_record_full_ops): Delete. (init_record_full_core_ops): Delete. (record_full_save): Refactor as method of the record_full_base_target class. (_initialize_record_full): Remove references to init_record_full_ops and init_record_full_core_ops. * remote.c (remote_target, extended_remote_target): New classes. (remote_ops): Now a remote_target. (extended_remote_ops): Now an extended_remote_target. (remote_insert_fork_catchpoint, remote_remove_fork_catchpoint) (remote_insert_vfork_catchpoint, remote_remove_vfork_catchpoint) (remote_insert_exec_catchpoint, remote_remove_exec_catchpoint) (remote_pass_signals, remote_set_syscall_catchpoint) (remote_program_signals, ) (remote_thread_always_alive): Remove target_ops parameter. (remote_thread_alive, remote_thread_name) (remote_update_thread_list, remote_threads_extra_info) (remote_static_tracepoint_marker_at) (remote_static_tracepoint_markers_by_strid) (remote_get_ada_task_ptid, remote_close, remote_start_remote) (remote_open): Refactor as methods of remote_target. (extended_remote_open, extended_remote_detach) (extended_remote_attach, extended_remote_post_attach): (extended_remote_supports_disable_randomization) (extended_remote_create_inferior): : Refactor as method of extended_remote_target. (remote_set_permissions, remote_open_1, remote_detach) (remote_follow_fork, remote_follow_exec, remote_disconnect) (remote_resume, remote_commit_resume, remote_stop) (remote_interrupt, remote_pass_ctrlc, remote_terminal_inferior) (remote_terminal_ours, remote_wait, remote_fetch_registers) (remote_prepare_to_store, remote_store_registers) (remote_flash_erase, remote_flash_done, remote_files_info) (remote_kill, remote_mourn, remote_insert_breakpoint) (remote_remove_breakpoint, remote_insert_watchpoint) (remote_watchpoint_addr_within_range) (remote_remove_watchpoint, remote_region_ok_for_hw_watchpoint) (remote_check_watch_resources, remote_stopped_by_sw_breakpoint) (remote_supports_stopped_by_sw_breakpoint) (remote_stopped_by_hw_breakpoint) (remote_supports_stopped_by_hw_breakpoint) (remote_stopped_by_watchpoint, remote_stopped_data_address) (remote_insert_hw_breakpoint, remote_remove_hw_breakpoint) (remote_verify_memory): Refactor as methods of remote_target. (remote_write_qxfer, remote_read_qxfer): Remove target_ops parameter. (remote_xfer_partial, remote_get_memory_xfer_limit) (remote_search_memory, remote_rcmd, remote_memory_map) (remote_pid_to_str, remote_get_thread_local_address) (remote_get_tib_address, remote_read_description): Refactor as methods of remote_target. (remote_target::fileio_open, remote_target::fileio_pwrite) (remote_target::fileio_pread, remote_target::fileio_close): New. (remote_hostio_readlink, remote_hostio_fstat) (remote_filesystem_is_local, remote_can_execute_reverse) (remote_supports_non_stop, remote_supports_disable_randomization) (remote_supports_multi_process, remote_supports_cond_breakpoints) (remote_supports_enable_disable_tracepoint) (remote_supports_string_tracing) (remote_can_run_breakpoint_commands, remote_trace_init) (remote_download_tracepoint, remote_can_download_tracepoint) (remote_download_trace_state_variable, remote_enable_tracepoint) (remote_disable_tracepoint, remote_trace_set_readonly_regions) (remote_trace_start, remote_get_trace_status) (remote_get_tracepoint_status, remote_trace_stop) (remote_trace_find, remote_get_trace_state_variable_value) (remote_save_trace_data, remote_get_raw_trace_data) (remote_set_disconnected_tracing, remote_core_of_thread) (remote_set_circular_trace_buffer, remote_traceframe_info) (remote_get_min_fast_tracepoint_insn_len) (remote_set_trace_buffer_size, remote_set_trace_notes) (remote_use_agent, remote_can_use_agent, remote_enable_btrace) (remote_disable_btrace, remote_teardown_btrace) (remote_read_btrace, remote_btrace_conf) (remote_augmented_libraries_svr4_read, remote_load) (remote_pid_to_exec_file, remote_can_do_single_step) (remote_execution_direction, remote_thread_handle_to_thread_info): Refactor as methods of remote_target. (init_remote_ops, init_extended_remote_ops): Delete. (remote_can_async_p, remote_is_async_p, remote_async) (remote_thread_events, remote_upload_tracepoints) (remote_upload_trace_state_variables): Refactor as methods of remote_target. (_initialize_remote): Remove references to init_remote_ops and init_extended_remote_ops. * remote-sim.c (gdbsim_target): New class. (gdbsim_fetch_register, gdbsim_store_register, gdbsim_kill) (gdbsim_load, gdbsim_create_inferior, gdbsim_open, gdbsim_close) (gdbsim_detach, gdbsim_resume, gdbsim_interrupt) (gdbsim_wait, gdbsim_prepare_to_store, gdbsim_xfer_partial) (gdbsim_files_info, gdbsim_mourn_inferior, gdbsim_thread_alive) (gdbsim_pid_to_str, gdbsim_has_all_memory, gdbsim_has_memory): Refactor as methods of gdbsim_target. (gdbsim_ops): Now a gdbsim_target. (init_gdbsim_ops): Delete. (gdbsim_cntrl_c): Adjust. (_initialize_remote_sim): Remove reference to init_gdbsim_ops. * amd64-linux-nat.c (amd64_linux_nat_target): New class. (the_amd64_linux_nat_target): New. (amd64_linux_fetch_inferior_registers) (amd64_linux_store_inferior_registers): Refactor as methods of amd64_linux_nat_target. (_initialize_amd64_linux_nat): Adjust. Set linux_target. * i386-linux-nat.c: Don't include "linux-nat.h". (i386_linux_nat_target): New class. (the_i386_linux_nat_target): New. (i386_linux_fetch_inferior_registers) (i386_linux_store_inferior_registers, i386_linux_resume): Refactor as methods of i386_linux_nat_target. (_initialize_i386_linux_nat): Adjust. Set linux_target. * inf-child.c (inf_child_ops): Delete. (inf_child_fetch_inferior_registers) (inf_child_store_inferior_registers): Delete. (inf_child_post_attach, inf_child_prepare_to_store): Refactor as methods of inf_child_target. (inf_child_target::supports_terminal_ours) (inf_child_target::terminal_init) (inf_child_target::terminal_inferior) (inf_child_target::terminal_ours_for_output) (inf_child_target::terminal_ours, inf_child_target::interrupt) (inf_child_target::pass_ctrlc, inf_child_target::terminal_info): New. (inf_child_open, inf_child_disconnect, inf_child_close) (inf_child_mourn_inferior, inf_child_maybe_unpush_target) (inf_child_post_startup_inferior, inf_child_can_run) (inf_child_pid_to_exec_file): Refactor as methods of inf_child_target. (inf_child_follow_fork): Delete. (inf_child_target::can_create_inferior) (inf_child_target::can_attach): New. (inf_child_target::has_all_memory, inf_child_target::has_memory) (inf_child_target::has_stack, inf_child_target::has_registers) (inf_child_target::has_execution): New. (inf_child_fileio_open, inf_child_fileio_pwrite) (inf_child_fileio_pread, inf_child_fileio_fstat) (inf_child_fileio_close, inf_child_fileio_unlink) (inf_child_fileio_readlink, inf_child_use_agent) (inf_child_can_use_agent): Refactor as methods of inf_child_target. (return_zero, inf_child_target): Delete. (inf_child_target::inf_child_target): New. * inf-child.h: Include "target.h". (inf_child_target): Delete function prototype. (inf_child_target): New class. (inf_child_open_target, inf_child_mourn_inferior) (inf_child_maybe_unpush_target): Delete. * inf-ptrace.c (inf_ptrace_target::~inf_ptrace_target): New. (inf_ptrace_follow_fork, inf_ptrace_insert_fork_catchpoint) (inf_ptrace_remove_fork_catchpoint, inf_ptrace_create_inferior) (inf_ptrace_post_startup_inferior, inf_ptrace_mourn_inferior) (inf_ptrace_attach, inf_ptrace_post_attach, inf_ptrace_detach) (inf_ptrace_detach_success, inf_ptrace_kill, inf_ptrace_resume) (inf_ptrace_wait, inf_ptrace_xfer_partial) (inf_ptrace_thread_alive, inf_ptrace_files_info) (inf_ptrace_pid_to_str, inf_ptrace_auxv_parse): Refactor as methods of inf_ptrace_target. (inf_ptrace_target): Delete function. * inf-ptrace.h: Include "inf-child.h". (inf_ptrace_target): Delete function declaration. (inf_ptrace_target): New class. (inf_ptrace_trad_target, inf_ptrace_detach_success): Delete. * linux-nat.c (linux_target): New. (linux_ops, linux_ops_saved, super_xfer_partial): Delete. (linux_nat_target::~linux_nat_target): New. (linux_child_post_attach, linux_child_post_startup_inferior) (linux_child_follow_fork, linux_child_insert_fork_catchpoint) (linux_child_remove_fork_catchpoint) (linux_child_insert_vfork_catchpoint) (linux_child_remove_vfork_catchpoint) (linux_child_insert_exec_catchpoint) (linux_child_remove_exec_catchpoint) (linux_child_set_syscall_catchpoint, linux_nat_pass_signals) (linux_nat_create_inferior, linux_nat_attach, linux_nat_detach) (linux_nat_resume, linux_nat_stopped_by_watchpoint) (linux_nat_stopped_data_address) (linux_nat_stopped_by_sw_breakpoint) (linux_nat_supports_stopped_by_sw_breakpoint) (linux_nat_stopped_by_hw_breakpoint) (linux_nat_supports_stopped_by_hw_breakpoint, linux_nat_wait) (linux_nat_kill, linux_nat_mourn_inferior) (linux_nat_xfer_partial, linux_nat_thread_alive) (linux_nat_update_thread_list, linux_nat_pid_to_str) (linux_nat_thread_name, linux_child_pid_to_exec_file) (linux_child_static_tracepoint_markers_by_strid) (linux_nat_is_async_p, linux_nat_can_async_p) (linux_nat_supports_non_stop, linux_nat_always_non_stop_p) (linux_nat_supports_multi_process) (linux_nat_supports_disable_randomization, linux_nat_async) (linux_nat_stop, linux_nat_close, linux_nat_thread_address_space) (linux_nat_core_of_thread, linux_nat_filesystem_is_local) (linux_nat_fileio_open, linux_nat_fileio_readlink) (linux_nat_fileio_unlink, linux_nat_thread_events): Refactor as methods of linux_nat_target. (linux_nat_wait_1, linux_xfer_siginfo, linux_proc_xfer_partial) (linux_proc_xfer_spu, linux_nat_xfer_osdata): Remove target_ops parameter. (check_stopped_by_watchpoint): Adjust. (linux_xfer_partial): Delete. (linux_target_install_ops, linux_target, linux_nat_add_target): Delete. (linux_nat_target::linux_nat_target): New. * linux-nat.h: Include "inf-ptrace.h". (linux_nat_target): New. (linux_target, linux_target_install_ops, linux_nat_add_target): Delete function declarations. (linux_target): Declare global. * linux-thread-db.c (thread_db_target): New. (thread_db_target::thread_db_target): New. (thread_db_ops): Delete. (the_thread_db_target): New. (thread_db_detach, thread_db_wait, thread_db_mourn_inferior) (thread_db_update_thread_list, thread_db_pid_to_str) (thread_db_extra_thread_info) (thread_db_thread_handle_to_thread_info) (thread_db_get_thread_local_address, thread_db_get_ada_task_ptid) (thread_db_resume): Refactor as methods of thread_db_target. (init_thread_db_ops): Delete. (_initialize_thread_db): Remove reference to init_thread_db_ops. * x86-linux-nat.c: Don't include "linux-nat.h". (super_post_startup_inferior): Delete. (x86_linux_nat_target::~x86_linux_nat_target): New. (x86_linux_child_post_startup_inferior) (x86_linux_read_description, x86_linux_enable_btrace) (x86_linux_disable_btrace, x86_linux_teardown_btrace) (x86_linux_read_btrace, x86_linux_btrace_conf): Refactor as methods of x86_linux_nat_target. (x86_linux_create_target): Delete. Bits folded ... (x86_linux_add_target): ... here. Now takes a linux_nat_target pointer. * x86-linux-nat.h: Include "linux-nat.h" and "x86-nat.h". (x86_linux_nat_target): New class. (x86_linux_create_target): Delete. (x86_linux_add_target): Now takes a linux_nat_target pointer. * x86-nat.c (x86_insert_watchpoint, x86_remove_watchpoint) (x86_region_ok_for_watchpoint, x86_stopped_data_address) (x86_stopped_by_watchpoint, x86_insert_hw_breakpoint) (x86_remove_hw_breakpoint, x86_can_use_hw_breakpoint) (x86_stopped_by_hw_breakpoint): Remove target_ops parameter and make extern. (x86_use_watchpoints): Delete. * x86-nat.h: Include "breakpoint.h" and "target.h". (x86_use_watchpoints): Delete. (x86_can_use_hw_breakpoint, x86_region_ok_for_hw_watchpoint) (x86_stopped_by_watchpoint, x86_stopped_data_address) (x86_insert_watchpoint, x86_remove_watchpoint) (x86_insert_hw_breakpoint, x86_remove_hw_breakpoint) (x86_stopped_by_hw_breakpoint): New declarations. (x86_nat_target): New template class. * ppc-linux-nat.c (ppc_linux_nat_target): New class. (the_ppc_linux_nat_target): New. (ppc_linux_fetch_inferior_registers) (ppc_linux_can_use_hw_breakpoint) (ppc_linux_region_ok_for_hw_watchpoint) (ppc_linux_ranged_break_num_registers) (ppc_linux_insert_hw_breakpoint, ppc_linux_remove_hw_breakpoint) (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_can_accel_watchpoint_condition) (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint) (ppc_linux_stopped_data_address, ppc_linux_stopped_by_watchpoint) (ppc_linux_watchpoint_addr_within_range) (ppc_linux_masked_watch_num_registers) (ppc_linux_store_inferior_registers, ppc_linux_auxv_parse) (ppc_linux_read_description): Refactor as methods of ppc_linux_nat_target. (_initialize_ppc_linux_nat): Adjust. Set linux_target. * procfs.c (procfs_xfer_partial): Delete forward declaration. (procfs_target): New class. (the_procfs_target): New. (procfs_target): Delete function. (procfs_auxv_parse, procfs_attach, procfs_detach) (procfs_fetch_registers, procfs_store_registers, procfs_wait) (procfs_xfer_partial, procfs_resume, procfs_pass_signals) (procfs_files_info, procfs_kill_inferior, procfs_mourn_inferior) (procfs_create_inferior, procfs_update_thread_list) (procfs_thread_alive, procfs_pid_to_str) (procfs_can_use_hw_breakpoint, procfs_stopped_by_watchpoint) (procfs_stopped_data_address, procfs_insert_watchpoint) (procfs_remove_watchpoint, procfs_region_ok_for_hw_watchpoint) (proc_find_memory_regions, procfs_info_proc) (procfs_make_note_section): Refactor as methods of procfs_target. (_initialize_procfs): Adjust. * sol-thread.c (sol_thread_target): New class. (sol_thread_ops): Now a sol_thread_target. (sol_thread_detach, sol_thread_resume, sol_thread_wait) (sol_thread_fetch_registers, sol_thread_store_registers) (sol_thread_xfer_partial, sol_thread_mourn_inferior) (sol_thread_alive, solaris_pid_to_str, sol_update_thread_list) (sol_get_ada_task_ptid): Refactor as methods of sol_thread_target. (init_sol_thread_ops): Delete. (_initialize_sol_thread): Adjust. Remove references to init_sol_thread_ops and complete_target_initialization. * windows-nat.c (windows_nat_target): New class. (windows_fetch_inferior_registers) (windows_store_inferior_registers, windows_resume, windows_wait) (windows_attach, windows_detach, windows_pid_to_exec_file) (windows_files_info, windows_create_inferior) (windows_mourn_inferior, windows_interrupt, windows_kill_inferior) (windows_close, windows_pid_to_str, windows_xfer_partial) (windows_get_tib_address, windows_get_ada_task_ptid) (windows_thread_name, windows_thread_alive): Refactor as windows_nat_target methods. (do_initial_windows_stuff): Adjust. (windows_target): Delete function. (_initialize_windows_nat): Adjust. * darwin-nat.c (darwin_resume, darwin_wait_to, darwin_interrupt) (darwin_mourn_inferior, darwin_kill_inferior) (darwin_create_inferior, darwin_attach, darwin_detach) (darwin_pid_to_str, darwin_thread_alive, darwin_xfer_partial) (darwin_pid_to_exec_file, darwin_get_ada_task_ptid) (darwin_supports_multi_process): Refactor as darwin_nat_target methods. (darwin_resume_to, darwin_files_info): Delete. (_initialize_darwin_inferior): Rename to ... (_initialize_darwin_nat): ... this. Adjust to C++ification. * darwin-nat.h: Include "inf-child.h". (darwin_nat_target): New class. (darwin_complete_target): Delete. * i386-darwin-nat.c (i386_darwin_nat_target): New class. (darwin_target): New. (i386_darwin_fetch_inferior_registers) (i386_darwin_store_inferior_registers): Refactor as methods of darwin_nat_target. (darwin_complete_target): Delete, with ... (_initialize_i386_darwin_nat): ... bits factored out here. * alpha-linux-nat.c (alpha_linux_nat_target): New class. (the_alpha_linux_nat_target): New. (alpha_linux_register_u_offset): Refactor as alpha_linux_nat_target method. (_initialize_alpha_linux_nat): Adjust. * linux-nat-trad.c (inf_ptrace_register_u_offset): Delete. (inf_ptrace_fetch_register, inf_ptrace_fetch_registers) (inf_ptrace_store_register, inf_ptrace_store_registers): Refact as methods of linux_nat_trad_target. (linux_trad_target): Delete. * linux-nat-trad.h (linux_trad_target): Delete function. (linux_nat_trad_target): New class. * mips-linux-nat.c (mips_linux_nat_target): New class. (super_fetch_registers, super_store_registers, super_close): Delete. (the_mips_linux_nat_target): New. (mips64_linux_regsets_fetch_registers) (mips64_linux_regsets_store_registers) (mips64_linux_fetch_registers, mips64_linux_store_registers) (mips_linux_register_u_offset, mips_linux_read_description) (mips_linux_can_use_hw_breakpoint) (mips_linux_stopped_by_watchpoint) (mips_linux_stopped_data_address) (mips_linux_region_ok_for_hw_watchpoint) (mips_linux_insert_watchpoint, mips_linux_remove_watchpoint) (mips_linux_close): Refactor as methods of mips_linux_nat. (_initialize_mips_linux_nat): Adjust to C++ification. * aix-thread.c (aix_thread_target): New class. (aix_thread_ops): Now an aix_thread_target. (aix_thread_detach, aix_thread_resume, aix_thread_wait) (aix_thread_fetch_registers, aix_thread_store_registers) (aix_thread_xfer_partial, aix_thread_mourn_inferior) (aix_thread_thread_alive, aix_thread_pid_to_str) (aix_thread_extra_thread_info, aix_thread_get_ada_task_ptid): Refactor as methods of aix_thread_target. (init_aix_thread_ops): Delete. (_initialize_aix_thread): Remove references to init_aix_thread_ops and complete_target_initialization. * rs6000-nat.c (rs6000_xfer_shared_libraries): Delete. (rs6000_nat_target): New class. (the_rs6000_nat_target): New. (rs6000_fetch_inferior_registers, rs6000_store_inferior_registers) (rs6000_xfer_partial, rs6000_wait, rs6000_create_inferior) (rs6000_xfer_shared_libraries): Refactor as rs6000_nat_target methods. (super_create_inferior): Delete. (_initialize_rs6000_nat): Adjust to C++ification. * arm-linux-nat.c (arm_linux_nat_target): New class. (the_arm_linux_nat_target): New. (arm_linux_fetch_inferior_registers) (arm_linux_store_inferior_registers, arm_linux_read_description) (arm_linux_can_use_hw_breakpoint, arm_linux_insert_hw_breakpoint) (arm_linux_remove_hw_breakpoint) (arm_linux_region_ok_for_hw_watchpoint) (arm_linux_insert_watchpoint, arm_linux_remove_watchpoint) (arm_linux_stopped_data_address, arm_linux_stopped_by_watchpoint) (arm_linux_watchpoint_addr_within_range): Refactor as methods of arm_linux_nat_target. (_initialize_arm_linux_nat): Adjust to C++ification. * aarch64-linux-nat.c (aarch64_linux_nat_target): New class. (the_aarch64_linux_nat_target): New. (aarch64_linux_fetch_inferior_registers) (aarch64_linux_store_inferior_registers) (aarch64_linux_child_post_startup_inferior) (aarch64_linux_read_description) (aarch64_linux_can_use_hw_breakpoint) (aarch64_linux_insert_hw_breakpoint) (aarch64_linux_remove_hw_breakpoint) (aarch64_linux_insert_watchpoint, aarch64_linux_remove_watchpoint) (aarch64_linux_region_ok_for_hw_watchpoint) (aarch64_linux_stopped_data_address) (aarch64_linux_stopped_by_watchpoint) (aarch64_linux_watchpoint_addr_within_range) (aarch64_linux_can_do_single_step): Refactor as methods of aarch64_linux_nat_target. (super_post_startup_inferior): Delete. (_initialize_aarch64_linux_nat): Adjust to C++ification. * hppa-linux-nat.c (hppa_linux_nat_target): New class. (the_hppa_linux_nat_target): New. (hppa_linux_fetch_inferior_registers) (hppa_linux_store_inferior_registers): Refactor as methods of hppa_linux_nat_target. (_initialize_hppa_linux_nat): Adjust to C++ification. * ia64-linux-nat.c (ia64_linux_nat_target): New class. (the_ia64_linux_nat_target): New. (ia64_linux_insert_watchpoint, ia64_linux_remove_watchpoint) (ia64_linux_stopped_data_address) (ia64_linux_stopped_by_watchpoint, ia64_linux_fetch_registers) (ia64_linux_store_registers, ia64_linux_xfer_partial): Refactor as ia64_linux_nat_target methods. (super_xfer_partial): Delete. (_initialize_ia64_linux_nat): Adjust to C++ification. * m32r-linux-nat.c (m32r_linux_nat_target): New class. (the_m32r_linux_nat_target): New. (m32r_linux_fetch_inferior_registers) (m32r_linux_store_inferior_registers): Refactor as m32r_linux_nat_target methods. (_initialize_m32r_linux_nat): Adjust to C++ification. * m68k-linux-nat.c (m68k_linux_nat_target): New class. (the_m68k_linux_nat_target): New. (m68k_linux_fetch_inferior_registers) (m68k_linux_store_inferior_registers): Refactor as m68k_linux_nat_target methods. (_initialize_m68k_linux_nat): Adjust to C++ification. * s390-linux-nat.c (s390_linux_nat_target): New class. (the_s390_linux_nat_target): New. (s390_linux_fetch_inferior_registers) (s390_linux_store_inferior_registers, s390_stopped_by_watchpoint) (s390_insert_watchpoint, s390_remove_watchpoint) (s390_can_use_hw_breakpoint, s390_insert_hw_breakpoint) (s390_remove_hw_breakpoint, s390_region_ok_for_hw_watchpoint) (s390_auxv_parse, s390_read_description): Refactor as methods of s390_linux_nat_target. (_initialize_s390_nat): Adjust to C++ification. * sparc-linux-nat.c (sparc_linux_nat_target): New class. (the_sparc_linux_nat_target): New. (_initialize_sparc_linux_nat): Adjust to C++ification. * sparc-nat.c (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc64-linux-nat.c (sparc64_linux_nat_target): New class. (the_sparc64_linux_nat_target): New. (_initialize_sparc64_linux_nat): Adjust to C++ification. * spu-linux-nat.c (spu_linux_nat_target): New class. (the_spu_linux_nat_target): New. (spu_child_post_startup_inferior, spu_child_post_attach) (spu_child_wait, spu_fetch_inferior_registers) (spu_store_inferior_registers, spu_xfer_partial) (spu_can_use_hw_breakpoint): Refactor as spu_linux_nat_target methods. (_initialize_spu_nat): Adjust to C++ification. * tilegx-linux-nat.c (tilegx_linux_nat_target): New class. (the_tilegx_linux_nat_target): New. (fetch_inferior_registers, store_inferior_registers): Refactor as methods. (_initialize_tile_linux_nat): Adjust to C++ification. * xtensa-linux-nat.c (xtensa_linux_nat_target): New class. (the_xtensa_linux_nat_target): New. (xtensa_linux_fetch_inferior_registers) (xtensa_linux_store_inferior_registers): Refactor as xtensa_linux_nat_target methods. (_initialize_xtensa_linux_nat): Adjust to C++ification. * fbsd-nat.c (USE_SIGTRAP_SIGINFO): Delete. (fbsd_pid_to_exec_file, fbsd_find_memory_regions) (fbsd_find_memory_regions, fbsd_info_proc, fbsd_xfer_partial) (fbsd_thread_alive, fbsd_pid_to_str, fbsd_thread_name) (fbsd_update_thread_list, fbsd_resume, fbsd_wait) (fbsd_stopped_by_sw_breakpoint) (fbsd_supports_stopped_by_sw_breakpoint, fbsd_follow_fork) (fbsd_insert_fork_catchpoint, fbsd_remove_fork_catchpoint) (fbsd_insert_vfork_catchpoint, fbsd_remove_vfork_catchpoint) (fbsd_post_startup_inferior, fbsd_post_attach) (fbsd_insert_exec_catchpoint, fbsd_remove_exec_catchpoint) (fbsd_set_syscall_catchpoint) (super_xfer_partial, super_resume, super_wait) (fbsd_supports_stopped_by_hw_breakpoint): Delete. (fbsd_handle_debug_trap): Remove target_ops parameter. (fbsd_nat_add_target): Delete. * fbsd-nat.h: Include "inf-ptrace.h". (fbsd_nat_add_target): Delete. (USE_SIGTRAP_SIGINFO): Define. (fbsd_nat_target): New class. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers) (amd64bsd_store_inferior_registers): Remove target_ops parameter. (amd64bsd_target): Delete. * amd64-bsd-nat.h: New file. * amd64-fbsd-nat.c: Include "amd64-bsd-nat.h" instead of "x86-bsd-nat.h". (amd64_fbsd_nat_target): New class. (the_amd64_fbsd_nat_target): New. (amd64fbsd_read_description): Refactor as method of amd64_fbsd_nat_target. (amd64_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_amd64fbsd_nat): Adjust to C++ification. * amd64-nat.h (amd64bsd_target): Delete function declaration. * i386-bsd-nat.c (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Remove target_ops parameter. (i386bsd_target): Delete. * i386-bsd-nat.h (i386bsd_target): Delete function declaration. (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Declare. (i386_bsd_nat_target): New class. * i386-fbsd-nat.c (i386_fbsd_nat_target): New class. (the_i386_fbsd_nat_target): New. (i386fbsd_resume, i386fbsd_read_description): Refactor as i386_fbsd_nat_target methods. (i386_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_i386fbsd_nat): Adjust to C++ification. * x86-bsd-nat.c (super_mourn_inferior): Delete. (x86bsd_mourn_inferior, x86bsd_target): Delete. (_initialize_x86_bsd_nat): Adjust to C++ification. * x86-bsd-nat.h: Include "x86-nat.h". (x86bsd_target): Delete declaration. (x86bsd_nat_target): New class. * aarch64-fbsd-nat.c (aarch64_fbsd_nat_target): New class. (the_aarch64_fbsd_nat_target): New. (aarch64_fbsd_fetch_inferior_registers) (aarch64_fbsd_store_inferior_registers): Refactor as methods of aarch64_fbsd_nat_target. (_initialize_aarch64_fbsd_nat): Adjust to C++ification. * alpha-bsd-nat.c (alpha_bsd_nat_target): New class. (the_alpha_bsd_nat_target): New. (alphabsd_fetch_inferior_registers) (alphabsd_store_inferior_registers): Refactor as alpha_bsd_nat_target methods. (_initialize_alphabsd_nat): Refactor as methods of alpha_bsd_nat_target. * amd64-nbsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_nbsd_nat_target): New. (_initialize_amd64nbsd_nat): Adjust to C++ification. * amd64-obsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_obsd_nat_target): New. (_initialize_amd64obsd_nat): Adjust to C++ification. * arm-fbsd-nat.c (arm_fbsd_nat_target): New. (the_arm_fbsd_nat_target): New. (arm_fbsd_fetch_inferior_registers) (arm_fbsd_store_inferior_registers, arm_fbsd_read_description): (_initialize_arm_fbsd_nat): Refactor as methods of arm_fbsd_nat_target. (_initialize_arm_fbsd_nat): Adjust to C++ification. * arm-nbsd-nat.c (arm_netbsd_nat_target): New class. (the_arm_netbsd_nat_target): New. (armnbsd_fetch_registers, armnbsd_store_registers): Refactor as arm_netbsd_nat_target. (_initialize_arm_netbsd_nat): Adjust to C++ification. * hppa-nbsd-nat.c (hppa_nbsd_nat_target): New class. (the_hppa_nbsd_nat_target): New. (hppanbsd_fetch_registers, hppanbsd_store_registers): Refactor as hppa_nbsd_nat_target methods. (_initialize_hppanbsd_nat): Adjust to C++ification. * hppa-obsd-nat.c (hppa_obsd_nat_target): New class. (the_hppa_obsd_nat_target): New. (hppaobsd_fetch_registers, hppaobsd_store_registers): Refactor as methods of hppa_obsd_nat_target. (_initialize_hppaobsd_nat): Adjust to C++ification. Use add_target. * i386-nbsd-nat.c (the_i386_nbsd_nat_target): New. (_initialize_i386nbsd_nat): Adjust to C++ification. Use add_target. * i386-obsd-nat.c (the_i386_obsd_nat_target): New. (_initialize_i386obsd_nat): Use add_target. * m68k-bsd-nat.c (m68k_bsd_nat_target): New class. (the_m68k_bsd_nat_target): New. (m68kbsd_fetch_inferior_registers) (m68kbsd_store_inferior_registers): Refactor as methods of m68k_bsd_nat_target. (_initialize_m68kbsd_nat): Adjust to C++ification. * mips-fbsd-nat.c (mips_fbsd_nat_target): New class. (the_mips_fbsd_nat_target): New. (mips_fbsd_fetch_inferior_registers) (mips_fbsd_store_inferior_registers): Refactor as methods of mips_fbsd_nat_target. (_initialize_mips_fbsd_nat): Adjust to C++ification. Use add_target. * mips-nbsd-nat.c (mips_nbsd_nat_target): New class. (the_mips_nbsd_nat_target): New. (mipsnbsd_fetch_inferior_registers) (mipsnbsd_store_inferior_registers): Refactor as methods of mips_nbsd_nat_target. (_initialize_mipsnbsd_nat): Adjust to C++ification. * mips64-obsd-nat.c (mips64_obsd_nat_target): New class. (the_mips64_obsd_nat_target): New. (mips64obsd_fetch_inferior_registers) (mips64obsd_store_inferior_registers): Refactor as methods of mips64_obsd_nat_target. (_initialize_mips64obsd_nat): Adjust to C++ification. Use add_target. * nbsd-nat.c (nbsd_pid_to_exec_file): Refactor as method of nbsd_nat_target. * nbsd-nat.h: Include "inf-ptrace.h". (nbsd_nat_target): New class. * obsd-nat.c (obsd_pid_to_str, obsd_update_thread_list) (obsd_wait): Refactor as methods of obsd_nat_target. (obsd_add_target): Delete. * obsd-nat.h: Include "inf-ptrace.h". (obsd_nat_target): New class. * ppc-fbsd-nat.c (ppc_fbsd_nat_target): New class. (the_ppc_fbsd_nat_target): New. (ppcfbsd_fetch_inferior_registers) (ppcfbsd_store_inferior_registers): Refactor as methods of ppc_fbsd_nat_target. (_initialize_ppcfbsd_nat): Adjust to C++ification. Use add_target. * ppc-nbsd-nat.c (ppc_nbsd_nat_target): New class. (the_ppc_nbsd_nat_target): New. (ppcnbsd_fetch_inferior_registers) (ppcnbsd_store_inferior_registers): Refactor as methods of ppc_nbsd_nat_target. (_initialize_ppcnbsd_nat): Adjust to C++ification. * ppc-obsd-nat.c (ppc_obsd_nat_target): New class. (the_ppc_obsd_nat_target): New. (ppcobsd_fetch_registers, ppcobsd_store_registers): Refactor as methods of ppc_obsd_nat_target. (_initialize_ppcobsd_nat): Adjust to C++ification. Use add_target. * sh-nbsd-nat.c (sh_nbsd_nat_target): New class. (the_sh_nbsd_nat_target): New. (shnbsd_fetch_inferior_registers) (shnbsd_store_inferior_registers): Refactor as methods of sh_nbsd_nat_target. (_initialize_shnbsd_nat): Adjust to C++ification. * sparc-nat.c (sparc_xfer_wcookie): Make extern. (inf_ptrace_xfer_partial): Delete. (sparc_xfer_partial, sparc_target): Delete. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers, sparc_xfer_wcookie): Declare. (sparc_target): Delete function declaration. (sparc_target): New template class. * sparc-nbsd-nat.c (the_sparc_nbsd_nat_target): New. (_initialize_sparcnbsd_nat): Adjust to C++ification. * sparc64-fbsd-nat.c (the_sparc64_fbsd_nat_target): New. (_initialize_sparc64fbsd_nat): Adjust to C++ification. Use add_target. * sparc64-nbsd-nat.c (the_sparc64_nbsd_nat_target): New. (_initialize_sparc64nbsd_nat): Adjust to C++ification. * sparc64-obsd-nat.c (the_sparc64_obsd_nat_target): New. (_initialize_sparc64obsd_nat): Adjust to C++ification. Use add_target. * vax-bsd-nat.c (vax_bsd_nat_target): New class. (the_vax_bsd_nat_target): New. (vaxbsd_fetch_inferior_registers) (vaxbsd_store_inferior_registers): Refactor as vax_bsd_nat_target methods. (_initialize_vaxbsd_nat): Adjust to C++ification. * bsd-kvm.c (bsd_kvm_target): New class. (bsd_kvm_ops): Now a bsd_kvm_target. (bsd_kvm_open, bsd_kvm_close, bsd_kvm_xfer_partial) (bsd_kvm_files_info, bsd_kvm_fetch_registers) (bsd_kvm_thread_alive, bsd_kvm_pid_to_str): Refactor as methods of bsd_kvm_target. (bsd_kvm_return_one): Delete. (bsd_kvm_add_target): Adjust to C++ification. * nto-procfs.c (nto_procfs_target, nto_procfs_target_native) (nto_procfs_target_procfs): New classes. (procfs_open_1, procfs_thread_alive, procfs_update_thread_list) (procfs_files_info, procfs_pid_to_exec_file, procfs_attach) (procfs_post_attach, procfs_wait, procfs_fetch_registers) (procfs_xfer_partial, procfs_detach, procfs_insert_breakpoint) (procfs_remove_breakpoint, procfs_insert_hw_breakpoint) (procfs_remove_hw_breakpoint, procfs_resume) (procfs_mourn_inferior, procfs_create_inferior, procfs_interrupt) (procfs_kill_inferior, procfs_store_registers) (procfs_pass_signals, procfs_pid_to_str, procfs_can_run): Refactor as methods of nto_procfs_target. (nto_procfs_ops): Now an nto_procfs_target_procfs. (nto_native_ops): Delete. (procfs_open, procfs_native_open): Delete. (nto_native_ops): Now an nto_procfs_target_native. (init_procfs_targets): Adjust to C++ification. (procfs_can_use_hw_breakpoint, procfs_remove_hw_watchpoint) (procfs_insert_hw_watchpoint, procfs_stopped_by_watchpoint): Refactor as methods of nto_procfs_target. * go32-nat.c (go32_nat_target): New class. (the_go32_nat_target): New. (go32_attach, go32_resume, go32_wait, go32_fetch_registers) (go32_store_registers, go32_xfer_partial, go32_files_info) (go32_kill_inferior, go32_create_inferior, go32_mourn_inferior) (go32_terminal_init, go32_terminal_info, go32_terminal_inferior) (go32_terminal_ours, go32_pass_ctrlc, go32_thread_alive) (go32_pid_to_str): Refactor as methods of go32_nat_target. (go32_target): Delete. (_initialize_go32_nat): Adjust to C++ification. * gnu-nat.c (gnu_wait, gnu_resume, gnu_kill_inferior) (gnu_mourn_inferior, gnu_create_inferior, gnu_attach, gnu_detach) (gnu_stop, gnu_thread_alive, gnu_xfer_partial) (gnu_find_memory_regions, gnu_pid_to_str): Refactor as methods of gnu_nat_target. (gnu_target): Delete. * gnu-nat.h (gnu_target): Delete. (gnu_nat_target): New class. * i386-gnu-nat.c (gnu_base_target): New. (i386_gnu_nat_target): New class. (the_i386_gnu_nat_target): New. (_initialize_i386gnu_nat): Adjust to C++ification. gdb/testsuite/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * gdb.base/breakpoint-in-ro-region.exp: Adjust to to_resume and to_log_command renames. * gdb.base/sss-bp-on-user-bp-2.exp: Likewise.
2018-05-03 07:37:22 +08:00
int
ppc_linux_nat_target::remove_mask_watchpoint (CORE_ADDR addr, CORE_ADDR mask,
target_hw_bp_type rw)
2011-05-06 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Implement support for PowerPC BookE masked watchpoints. gdb/ * NEWS: Mention masked watchpoint support. Create "Changed commands" section. * breakpoint.h (struct breakpoint_ops) <works_in_software_mode>: New method. Initialize to NULL in all existing breakpoint_ops instances. (struct breakpoint) <hw_wp_mask>: New field. * breakpoint.c (is_masked_watchpoint): Add prototype. (update_watchpoint): Don't set b->val for masked watchpoints. Call breakpoint's breakpoint_ops.works_in_software_mode if available. (watchpoints_triggered): Handle the case of a hardware masked watchpoint trigger. (watchpoint_check): Likewise. (works_in_software_mode_watchpoint): New function. (insert_masked_watchpoint, remove_masked_watchpoint) (resources_needed_masked_watchpoint) (works_in_software_mode_masked_watchpoint, print_it_masked_watchpoint) (print_one_detail_masked_watchpoint, print_mention_masked_watchpoint) (print_recreate_masked_watchpoint, is_masked_watchpoint): New functions. (masked_watchpoint_breakpoint_ops): New structure. (watch_command_1): Check for the existence of the `mask' parameter. Set b->ops according to the type of hardware watchpoint being created. * ppc-linux-nat.c (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_masked_watch_num_registers): New functions. (_initialize_ppc_linux_nat): Initialize to_insert_mask_watchpoint, to_remove_mask_watchpoint and to_masked_watch_num_registers. * target.c (update_current_target): Mention to_insert_mask_watchpoint, to_remove_mask_watchpoint, and to_masked_watch_num_registers. (target_insert_mask_watchpoint, target_remove_mask_watchpoint) (target_masked_watch_num_registers): New functions. * target.h (struct target_ops) <to_insert_mask_watchpoint>, <to_remove_mask_watchpoint>, <to_masked_watch_num_registers>: New methods. (target_insert_mask_watchpoint, target_remove_mask_watchpoint) (target_masked_watch_num_registers): Add prototypes. gdb/doc/ * gdb.texinfo (Set Watchpoints): Document mask parameter. (PowerPC Embedded): Mention support of masked watchpoints.
2011-05-07 02:46:33 +08:00
{
struct ppc_hw_breakpoint p;
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
gdb_assert (m_dreg_interface.hwdebug_p ());
2011-05-06 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Implement support for PowerPC BookE masked watchpoints. gdb/ * NEWS: Mention masked watchpoint support. Create "Changed commands" section. * breakpoint.h (struct breakpoint_ops) <works_in_software_mode>: New method. Initialize to NULL in all existing breakpoint_ops instances. (struct breakpoint) <hw_wp_mask>: New field. * breakpoint.c (is_masked_watchpoint): Add prototype. (update_watchpoint): Don't set b->val for masked watchpoints. Call breakpoint's breakpoint_ops.works_in_software_mode if available. (watchpoints_triggered): Handle the case of a hardware masked watchpoint trigger. (watchpoint_check): Likewise. (works_in_software_mode_watchpoint): New function. (insert_masked_watchpoint, remove_masked_watchpoint) (resources_needed_masked_watchpoint) (works_in_software_mode_masked_watchpoint, print_it_masked_watchpoint) (print_one_detail_masked_watchpoint, print_mention_masked_watchpoint) (print_recreate_masked_watchpoint, is_masked_watchpoint): New functions. (masked_watchpoint_breakpoint_ops): New structure. (watch_command_1): Check for the existence of the `mask' parameter. Set b->ops according to the type of hardware watchpoint being created. * ppc-linux-nat.c (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_masked_watch_num_registers): New functions. (_initialize_ppc_linux_nat): Initialize to_insert_mask_watchpoint, to_remove_mask_watchpoint and to_masked_watch_num_registers. * target.c (update_current_target): Mention to_insert_mask_watchpoint, to_remove_mask_watchpoint, and to_masked_watch_num_registers. (target_insert_mask_watchpoint, target_remove_mask_watchpoint) (target_masked_watch_num_registers): New functions. * target.h (struct target_ops) <to_insert_mask_watchpoint>, <to_remove_mask_watchpoint>, <to_masked_watch_num_registers>: New methods. (target_insert_mask_watchpoint, target_remove_mask_watchpoint) (target_masked_watch_num_registers): Add prototypes. gdb/doc/ * gdb.texinfo (Set Watchpoints): Document mask parameter. (PowerPC Embedded): Mention support of masked watchpoints.
2011-05-07 02:46:33 +08:00
p.version = PPC_DEBUG_CURRENT_VERSION;
p.trigger_type = get_trigger_type (rw);
p.addr_mode = PPC_BREAKPOINT_MODE_MASK;
p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
p.addr = addr;
p.addr2 = mask;
p.condition_value = 0;
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
clear_hw_breakpoint (inferior_ptid.pid (), p);
2011-05-06 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Implement support for PowerPC BookE masked watchpoints. gdb/ * NEWS: Mention masked watchpoint support. Create "Changed commands" section. * breakpoint.h (struct breakpoint_ops) <works_in_software_mode>: New method. Initialize to NULL in all existing breakpoint_ops instances. (struct breakpoint) <hw_wp_mask>: New field. * breakpoint.c (is_masked_watchpoint): Add prototype. (update_watchpoint): Don't set b->val for masked watchpoints. Call breakpoint's breakpoint_ops.works_in_software_mode if available. (watchpoints_triggered): Handle the case of a hardware masked watchpoint trigger. (watchpoint_check): Likewise. (works_in_software_mode_watchpoint): New function. (insert_masked_watchpoint, remove_masked_watchpoint) (resources_needed_masked_watchpoint) (works_in_software_mode_masked_watchpoint, print_it_masked_watchpoint) (print_one_detail_masked_watchpoint, print_mention_masked_watchpoint) (print_recreate_masked_watchpoint, is_masked_watchpoint): New functions. (masked_watchpoint_breakpoint_ops): New structure. (watch_command_1): Check for the existence of the `mask' parameter. Set b->ops according to the type of hardware watchpoint being created. * ppc-linux-nat.c (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_masked_watch_num_registers): New functions. (_initialize_ppc_linux_nat): Initialize to_insert_mask_watchpoint, to_remove_mask_watchpoint and to_masked_watch_num_registers. * target.c (update_current_target): Mention to_insert_mask_watchpoint, to_remove_mask_watchpoint, and to_masked_watch_num_registers. (target_insert_mask_watchpoint, target_remove_mask_watchpoint) (target_masked_watch_num_registers): New functions. * target.h (struct target_ops) <to_insert_mask_watchpoint>, <to_remove_mask_watchpoint>, <to_masked_watch_num_registers>: New methods. (target_insert_mask_watchpoint, target_remove_mask_watchpoint) (target_masked_watch_num_registers): Add prototypes. gdb/doc/ * gdb.texinfo (Set Watchpoints): Document mask parameter. (PowerPC Embedded): Mention support of masked watchpoints.
2011-05-07 02:46:33 +08:00
return 0;
}
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
/* Check whether we have at least one free DVC register for the threads
of the pid of inferior_ptid. */
bool
ppc_linux_nat_target::can_use_watchpoint_cond_accel (void)
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
{
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
m_dreg_interface.detect (inferior_ptid);
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
if (!m_dreg_interface.hwdebug_p ())
return false;
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
int cnt = m_dreg_interface.hwdebug_info ().num_condition_regs;
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
if (cnt == 0)
return false;
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
auto process_it = m_process_info.find (inferior_ptid.pid ());
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
/* No breakpoints or watchpoints have been requested for this process,
we have at least one free DVC register. */
if (process_it == m_process_info.end ())
return true;
for (const ppc_hw_breakpoint &bp : process_it->second.requested_hw_bps)
if (bp.condition_mode != PPC_BREAKPOINT_CONDITION_NONE)
cnt--;
if (cnt <= 0)
return false;
return true;
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
}
/* Calculate the enable bits and the contents of the Data Value Compare
debug register present in BookE processors.
ADDR is the address to be watched, LEN is the length of watched data
and DATA_VALUE is the value which will trigger the watchpoint.
On exit, CONDITION_MODE will hold the enable bits for the DVC, and
CONDITION_VALUE will hold the value which should be put in the
DVC register. */
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
void
ppc_linux_nat_target::calculate_dvc (CORE_ADDR addr, int len,
CORE_ADDR data_value,
uint32_t *condition_mode,
uint64_t *condition_value)
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
{
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
const struct ppc_debug_info &hwdebug_info = (m_dreg_interface.
hwdebug_info ());
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
int i, num_byte_enable, align_offset, num_bytes_off_dvc,
rightmost_enabled_byte;
CORE_ADDR addr_end_data, addr_end_dvc;
/* The DVC register compares bytes within fixed-length windows which
are word-aligned, with length equal to that of the DVC register.
We need to calculate where our watch region is relative to that
window and enable comparison of the bytes which fall within it. */
align_offset = addr % hwdebug_info.sizeof_condition;
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
addr_end_data = addr + len;
addr_end_dvc = (addr - align_offset
+ hwdebug_info.sizeof_condition);
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
num_bytes_off_dvc = (addr_end_data > addr_end_dvc)?
addr_end_data - addr_end_dvc : 0;
num_byte_enable = len - num_bytes_off_dvc;
/* Here, bytes are numbered from right to left. */
rightmost_enabled_byte = (addr_end_data < addr_end_dvc)?
addr_end_dvc - addr_end_data : 0;
*condition_mode = PPC_BREAKPOINT_CONDITION_AND;
for (i = 0; i < num_byte_enable; i++)
*condition_mode
|= PPC_BREAKPOINT_CONDITION_BE (i + rightmost_enabled_byte);
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
/* Now we need to match the position within the DVC of the comparison
value with where the watch region is relative to the window
(i.e., the ALIGN_OFFSET). */
*condition_value = ((uint64_t) data_value >> num_bytes_off_dvc * 8
<< rightmost_enabled_byte * 8);
}
/* Return the number of memory locations that need to be accessed to
evaluate the expression which generated the given value chain.
Returns -1 if there's any register access involved, or if there are
other kinds of values which are not acceptable in a condition
expression (e.g., lval_computed or lval_internalvar). */
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
int
ppc_linux_nat_target::num_memory_accesses (const std::vector<value_ref_ptr>
&chain)
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
{
int found_memory_cnt = 0;
/* The idea here is that evaluating an expression generates a series
of values, one holding the value of every subexpression. (The
expression a*b+c has five subexpressions: a, b, a*b, c, and
a*b+c.) GDB's values hold almost enough information to establish
the criteria given above --- they identify memory lvalues,
register lvalues, computed values, etcetera. So we can evaluate
the expression, and then scan the chain of values that leaves
behind to determine the memory locations involved in the evaluation
of an expression.
However, I don't think that the values returned by inferior
function calls are special in any way. So this function may not
notice that an expression contains an inferior function call.
FIXME. */
for (const value_ref_ptr &iter : chain)
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
{
struct value *v = iter.get ();
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
/* Constants and values from the history are fine. */
if (VALUE_LVAL (v) == not_lval || deprecated_value_modifiable (v) == 0)
continue;
else if (VALUE_LVAL (v) == lval_memory)
{
/* A lazy memory lvalue is one that GDB never needed to fetch;
we either just used its address (e.g., `a' in `a.b') or
we never needed it at all (e.g., `a' in `a,b'). */
if (!value_lazy (v))
found_memory_cnt++;
}
/* Other kinds of values are not fine. */
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
else
return -1;
}
return found_memory_cnt;
}
/* Verifies whether the expression COND can be implemented using the
DVC (Data Value Compare) register in BookE processors. The expression
must test the watch value for equality with a constant expression.
If the function returns 1, DATA_VALUE will contain the constant against
which the watch value should be compared and LEN will contain the size
of the constant. */
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
int
ppc_linux_nat_target::check_condition (CORE_ADDR watch_addr,
struct expression *cond,
CORE_ADDR *data_value, int *len)
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
{
int pc = 1, num_accesses_left, num_accesses_right;
struct value *left_val, *right_val;
std::vector<value_ref_ptr> left_chain, right_chain;
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
if (cond->elts[0].opcode != BINOP_EQUAL)
return 0;
fetch_subexp_value (cond, &pc, &left_val, NULL, &left_chain, 0);
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
num_accesses_left = num_memory_accesses (left_chain);
if (left_val == NULL || num_accesses_left < 0)
return 0;
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
fetch_subexp_value (cond, &pc, &right_val, NULL, &right_chain, 0);
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
num_accesses_right = num_memory_accesses (right_chain);
if (right_val == NULL || num_accesses_right < 0)
return 0;
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
if (num_accesses_left == 1 && num_accesses_right == 0
&& VALUE_LVAL (left_val) == lval_memory
&& value_address (left_val) == watch_addr)
{
*data_value = value_as_long (right_val);
/* DATA_VALUE is the constant in RIGHT_VAL, but actually has
the same type as the memory region referenced by LEFT_VAL. */
*len = TYPE_LENGTH (check_typedef (value_type (left_val)));
}
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
else if (num_accesses_left == 0 && num_accesses_right == 1
&& VALUE_LVAL (right_val) == lval_memory
&& value_address (right_val) == watch_addr)
{
*data_value = value_as_long (left_val);
/* DATA_VALUE is the constant in LEFT_VAL, but actually has
the same type as the memory region referenced by RIGHT_VAL. */
*len = TYPE_LENGTH (check_typedef (value_type (right_val)));
}
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
else
return 0;
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
return 1;
}
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
/* Return true if the target is capable of using hardware to evaluate the
condition expression, thus only triggering the watchpoint when it is
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
true. */
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
target_ops: Use bool throughout After the previous target_ops/C++ patches are all squashed and merged, this one can go in separately. This patch adjusts all the target methods to return bool instead of int when they're returning a boolean. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * target.h (target_ops) <stopped_by_sw_breakpoint, supports_stopped_by_sw_breakpoint, stopped_by_hw_breakpoint, supports_stopped_by_hw_breakpoint, stopped_by_watchpoint, have_continuable_watchpoint, stopped_data_address, watchpoint_addr_within_range, can_accel_watchpoint_condition, can_run, thread_alive, has_all_memory, has_memory, has_stack, has_registers, has_execution, can_async_p, is_async_p, supports_non_stop, always_non_stop_p, can_execute_reverse, supports_multi_process, supports_enable_disable_tracepoint, supports_disable_randomization, supports_string_tracing, supports_evaluation_of_breakpoint_conditions, can_run_breakpoint_commands, filesystem_is_local, can_download_tracepoint, get_trace_state_variable_value, set_trace_notes, get_tib_address, use_agent, can_use_agent, record_is_replaying, record_will_replay, augmented_libraries_svr4_read>: Adjust to return bool. * aarch64-linux-nat.c: All implementations adjusted. * aix-thread.c: All implementations adjusted. * arm-linux-nat.c: All implementations adjusted. * breakpoint.c: All implementations adjusted. * bsd-kvm.c: All implementations adjusted. * bsd-uthread.c: All implementations adjusted. * corelow.c: All implementations adjusted. * ctf.c: All implementations adjusted. * darwin-nat.c: All implementations adjusted. * darwin-nat.h: All implementations adjusted. * exec.c: All implementations adjusted. * fbsd-nat.c: All implementations adjusted. * fbsd-nat.h: All implementations adjusted. * gnu-nat.c: All implementations adjusted. * gnu-nat.h: All implementations adjusted. * go32-nat.c: All implementations adjusted. * ia64-linux-nat.c: All implementations adjusted. * inf-child.c: All implementations adjusted. * inf-child.h: All implementations adjusted. * inf-ptrace.c: All implementations adjusted. * inf-ptrace.h: All implementations adjusted. * linux-nat.c: All implementations adjusted. * linux-nat.h: All implementations adjusted. * mips-linux-nat.c: All implementations adjusted. * nto-procfs.c: All implementations adjusted. * ppc-linux-nat.c: All implementations adjusted. * procfs.c: All implementations adjusted. * ravenscar-thread.c: All implementations adjusted. * record-btrace.c: All implementations adjusted. * record-full.c: All implementations adjusted. * remote-sim.c: All implementations adjusted. * remote.c: All implementations adjusted. * s390-linux-nat.c: All implementations adjusted. * sol-thread.c: All implementations adjusted. * spu-multiarch.c: All implementations adjusted. * target-delegates.c: All implementations adjusted. * target.c: All implementations adjusted. * target.h: All implementations adjusted. * tracefile-tfile.c: All implementations adjusted. * tracefile.c: All implementations adjusted. * tracefile.h: All implementations adjusted. * windows-nat.c: All implementations adjusted. * x86-linux-nat.h: All implementations adjusted. * x86-nat.h: All implementations adjusted.
2018-05-03 07:37:26 +08:00
bool
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
ppc_linux_nat_target::can_accel_watchpoint_condition (CORE_ADDR addr,
int len, int rw,
Convert struct target_ops to C++ I.e., use C++ virtual methods and inheritance instead of tables of function pointers. Unfortunately, there's no way to do a smooth transition. ALL native targets in the tree must be converted at the same time. I've tested all I could with cross compilers and with help from GCC compile farm, but naturally I haven't been able to test many of the ports. Still, I made a best effort to port everything over, and while I expect some build problems due to typos and such, which should be trivial to fix, I don't expect any design problems. * Implementation notes: - The flattened current_target is gone. References to current_target or current_target.beneath are replaced with references to target_stack (the top of the stack) directly. - To keep "set debug target" working, this adds a new debug_stratum layer that sits on top of the stack, prints the debug, and delegates to the target beneath. In addition, this makes the shortname and longname properties of target_ops be virtual methods instead of data fields, and makes the debug target defer those to the target beneath. This is so that debug code sprinkled around that does "if (debugtarget) ..." can transparently print the name of the target beneath. A patch later in the series actually splits out the shortname/longname methods to a separate structure, but I preferred to keep that chance separate as it is associated with changing a bit the design of how targets are registered and open. - Since you can't check whether a C++ virtual method is overridden, the old method of checking whether a target_ops implements a method by comparing the function pointer must be replaced with something else. Some cases are fixed by adding a parallel "can_do_foo" target_ops methods. E.g.,: + for (t = target_stack; t != NULL; t = t->beneath) { - if (t->to_create_inferior != NULL) + if (t->can_create_inferior ()) break; } Others are fixed by changing void return type to bool or int return type, and have the default implementation return false or -1, to indicate lack of support. - make-target-delegates was adjusted to generate C++ classes and methods. It needed tweaks to grok "virtual" in front of the target method name, and for the fact that methods are no longer function pointers. (In particular, the current code parsing the return type was simple because it could simply parse up until the '(' in '(*to_foo)'. It now generates a couple C++ classes that inherit target_ops: dummy_target and debug_target. Since we need to generate the class declarations as well, i.e., we need to emit methods twice, we now generate the code in two passes. - The core_target global is renamed to avoid conflict with the "core_target" class. - ctf/tfile targets init_tracefile_ops is replaced by a base class that is inherited by both ctf and tfile. - bsd-uthread The bsd_uthread_ops_hack hack is gone. It's not needed because nothing was extending a target created by bsd_uthread_target. - remote/extended-remote targets This is a first pass, just enough to C++ify target_ops. A later pass will convert more free functions to methods, and make remote_state be truly per remote instance, allowing multiple simultaneous instances of remote targets. - inf-child/"native" is converted to an actual base class (inf_child_target), that is inherited by all native targets. - GNU/Linux The old weird double-target linux_ops mechanism in linux-nat.c, is gone, replaced by adding a few virtual methods to linux-nat.h's target_ops, called low_XXX, that the concrete linux-nat implementations override. Sort of like gdbserver's linux_target_ops, but simpler, for requiring only one target_ops-like hierarchy, which spares implementing the same method twice when we need to forward the method to a low implementation. The low target simply reimplements the target_ops method directly in that case. There are a few remaining linux-nat.c hooks that would be better converted to low_ methods like above too. E.g.: linux_nat_set_new_thread (t, x86_linux_new_thread); linux_nat_set_new_fork (t, x86_linux_new_fork); linux_nat_set_forget_process That'll be done in a follow up patch. - We can no longer use functions like x86_use_watchpoints to install custom methods on an arbitrary base target. The patch replaces instances of such a pattern with template mixins. For example memory_breakpoint_target defined in target.h, or x86_nat_target in x86-nat.h. - linux_trad_target, MIPS and Alpha GNU/Linux The code in the new linux-nat-trad.h/c files which was split off of inf-ptrace.h/c recently, is converted to a C++ base class, and used by the MIPS and Alpha GNU/Linux ports. - BSD targets The $architecture x NetBSD/OpenBSD/FreeBSD support matrix complicates things a bit. There's common BSD target code, and there's common architecture-specific code shared between the different BSDs. Currently, all that is stiched together to form a final target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target functions etc. This introduces new fbsd_nat_target, obsd_nat_target and nbsd_nat_target classes that serve as base/prototype target for the corresponding BSD variant. And introduces generic i386/AMD64 BSD targets, to be used as template mixin to build a final target. Similarly, a generic SPARC target is added, used by both BSD and Linux ports. - bsd_kvm_add_target, BSD libkvm target I considered making bsd_kvm_supply_pcb a virtual method, and then have each port inherit bsd_kvm_target and override that method, but that was resulting in lots of unjustified churn, so I left the function pointer mechanism alone. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> John Baldwin <jhb@freebsd.org> * target.h (enum strata) <debug_stratum>: New. (struct target_ops) <all delegation methods>: Replace by C++ virtual methods, and drop "to_" prefix. All references updated throughout. <to_shortname, to_longname, to_doc, to_data, to_have_steppable_watchpoint, to_have_continuable_watchpoint, to_has_thread_control, to_attach_no_wait>: Delete, replaced by virtual methods. All references updated throughout. <can_attach, supports_terminal_ours, can_create_inferior, get_thread_control_capabilities, attach_no_wait>: New virtual methods. <insert_breakpoint, remove_breakpoint>: Now TARGET_DEFAULT_NORETURN methods. <info_proc>: Now returns bool. <to_magic>: Delete. (OPS_MAGIC): Delete. (current_target): Delete. All references replaced by references to ... (target_stack): ... this. New. (target_shortname, target_longname): Adjust. (target_can_run): Now a function declaration. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (memory_breakpoint_target): New template class. (test_target_ops): Refactor as a C++ class with virtual methods. * make-target-delegates (NAME_PART): Tighten. (POINTER_PART, CP_SYMBOL): New. (SIMPLE_RETURN_PART): Reimplement. (VEC_RETURN_PART): Expect less. (RETURN_PART, VIRTUAL_PART): New. (METHOD): Adjust to C++ virtual methods. (scan_target_h): Remove reference to C99. (dname): Output "target_ops::" prefix. (write_function_header): Adjust to output a C++ class method. (write_declaration): New. (write_delegator): Adjust to output a C++ class method. (tdname): Output "dummy_target::" prefix. (write_tdefault, write_debugmethod): Adjust to output a C++ class method. (tdefault_names, debug_names): Delete. (return_types, tdefaults, styles, argtypes_array): New. (top level): All methods are delegators. (print_class): New. (top level): Print dummy_target and debug_target classes. * target-delegates.c: Regenerate. * target-debug.h (target_debug_print_enum_info_proc_what) (target_debug_print_thread_control_capabilities) (target_debug_print_thread_info_p): New. * target.c (dummy_target): Delete. (the_dummy_target, the_debug_target): New. (target_stack): Now extern. (set_targetdebug): Push/unpush debug target. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (add_target_with_completer): No longer call complete_target_initialization. (target_supports_terminal_ours): Use regular delegation. (update_current_target): Delete. (push_target): No longer check magic number. Don't call update_current_target. (unpush_target): Don't call update_current_target. (target_is_pushed): No longer check magic number. (target_require_runnable): Skip for all stratums over process_stratum. (target_ops::info_proc): New. (target_info_proc): Use find_target_at and find_default_run_target. (target_supports_disable_randomization): Use regular delegation. (target_get_osdata): Use find_target_at. (target_ops::open, target_ops::close, target_ops::can_attach) (target_ops::attach, target_ops::can_create_inferior) (target_ops::create_inferior, target_ops::can_run) (target_can_run): New. (default_fileio_target): Use regular delegation. (target_ops::fileio_open, target_ops::fileio_pwrite) (target_ops::fileio_pread, target_ops::fileio_fstat) (target_ops::fileio_close, target_ops::fileio_unlink) (target_ops::fileio_readlink): New. (target_fileio_open_1, target_fileio_unlink) (target_fileio_readlink): Always call the target method. Handle FILEIO_ENOSYS. (return_zero, return_zero_has_execution): Delete. (init_dummy_target): Delete. (dummy_target::dummy_target, dummy_target::shortname) (dummy_target::longname, dummy_target::doc) (debug_target::debug_target, debug_target::shortname) (debug_target::longname, debug_target::doc): New. (target_supports_delete_record): Use regular delegation. (setup_target_debug): Delete. (maintenance_print_target_stack): Skip debug_stratum. (initialize_targets): Instantiate the_dummy_target and the_debug_target. * auxv.c (target_auxv_parse): Remove 'ops' parameter. Adjust to use target_stack. (target_auxv_search, fprint_target_auxv): Adjust. (info_auxv_command): Adjust to use target_stack. * auxv.h (target_auxv_parse): Remove 'ops' parameter. * exceptions.c (print_flush): Handle a NULL target_stack. * regcache.c (target_ops_no_register): Refactor as class with virtual methods. * exec.c (exec_target): New class. (exec_ops): Now an exec_target. (exec_open, exec_close_1, exec_get_section_table) (exec_xfer_partial, exec_files_info, exec_has_memory) (exec_make_note_section): Refactor as exec_target methods. (exec_file_clear, ignore, exec_remove_breakpoint, init_exec_ops): Delete. (exec_target::find_memory_regions): New. (_initialize_exec): Don't call init_exec_ops. * gdbcore.h (exec_file_clear): Delete. * corefile.c (core_target): Delete. (core_file_command): Adjust. * corelow.c (core_target): New class. (the_core_target): New. (core_close): Remove target_ops parameter. (core_close_cleanup): Adjust. (core_target::close): New. (core_open, core_detach, get_core_registers, core_files_info) (core_xfer_partial, core_thread_alive, core_read_description) (core_pid_to_str, core_thread_name, core_has_memory) (core_has_stack, core_has_registers, core_info_proc): Rework as core_target methods. (ignore, core_remove_breakpoint, init_core_ops): Delete. (_initialize_corelow): Initialize the_core_target. * gdbcore.h (core_target): Delete. (the_core_target): New. * ctf.c: (ctf_target): New class. (ctf_ops): Now a ctf_target. (ctf_open, ctf_close, ctf_files_info, ctf_fetch_registers) (ctf_xfer_partial, ctf_get_trace_state_variable_value) (ctf_trace_find, ctf_traceframe_info): Refactor as ctf_target methods. (init_ctf_ops): Delete. (_initialize_ctf): Don't call it. * tracefile-tfile.c (tfile_target): New class. (tfile_ops): Now a tfile_target. (tfile_open, tfile_close, tfile_files_info) (tfile_get_tracepoint_status, tfile_trace_find) (tfile_fetch_registers, tfile_xfer_partial) (tfile_get_trace_state_variable_value, tfile_traceframe_info): Refactor as tfile_target methods. (tfile_xfer_partial_features): Remove target_ops parameter. (init_tfile_ops): Delete. (_initialize_tracefile_tfile): Don't call it. * tracefile.c (tracefile_has_all_memory, tracefile_has_memory) (tracefile_has_stack, tracefile_has_registers) (tracefile_thread_alive, tracefile_get_trace_status): Refactor as tracefile_target methods. (init_tracefile_ops): Delete. (tracefile_target::tracefile_target): New. * tracefile.h: Include "target.h". (tracefile_target): New class. (init_tracefile_ops): Delete. * spu-multiarch.c (spu_multiarch_target): New class. (spu_ops): Now a spu_multiarch_target. (spu_thread_architecture, spu_region_ok_for_hw_watchpoint) (spu_fetch_registers, spu_store_registers, spu_xfer_partial) (spu_search_memory, spu_mourn_inferior): Refactor as spu_multiarch_target methods. (init_spu_ops): Delete. (_initialize_spu_multiarch): Remove references to init_spu_ops, complete_target_initialization. * ravenscar-thread.c (ravenscar_thread_target): New class. (ravenscar_ops): Now a ravenscar_thread_target. (ravenscar_resume, ravenscar_wait, ravenscar_update_thread_list) (ravenscar_thread_alive, ravenscar_pid_to_str) (ravenscar_fetch_registers, ravenscar_store_registers) (ravenscar_prepare_to_store, ravenscar_stopped_by_sw_breakpoint) (ravenscar_stopped_by_hw_breakpoint) (ravenscar_stopped_by_watchpoint, ravenscar_stopped_data_address) (ravenscar_mourn_inferior, ravenscar_core_of_thread) (ravenscar_get_ada_task_ptid): Refactor as ravenscar_thread_target methods. (init_ravenscar_thread_ops): Delete. (_initialize_ravenscar): Remove references to init_ravenscar_thread_ops and complete_target_initialization. * bsd-uthread.c (bsd_uthread_ops_hack): Delete. (bsd_uthread_target): New class. (bsd_uthread_ops): Now a bsd_uthread_target. (bsd_uthread_activate): Adjust to refer to bsd_uthread_ops. (bsd_uthread_close, bsd_uthread_mourn_inferior) (bsd_uthread_fetch_registers, bsd_uthread_store_registers) (bsd_uthread_wait, bsd_uthread_resume, bsd_uthread_thread_alive) (bsd_uthread_update_thread_list, bsd_uthread_extra_thread_info) (bsd_uthread_pid_to_str): Refactor as bsd_uthread_target methods. (bsd_uthread_target): Delete function. (_initialize_bsd_uthread): Remove reference to complete_target_initialization. * bfd-target.c (target_bfd_data): Delete. Fields folded into ... (target_bfd): ... this new class. (target_bfd_xfer_partial, target_bfd_get_section_table) (target_bfd_close): Refactor as target_bfd methods. (target_bfd::~target_bfd): New. (target_bfd_reopen): Adjust. (target_bfd::close): New. * record-btrace.c (record_btrace_target): New class. (record_btrace_ops): Now a record_btrace_target. (record_btrace_open, record_btrace_stop_recording) (record_btrace_disconnect, record_btrace_close) (record_btrace_async, record_btrace_info) (record_btrace_insn_history, record_btrace_insn_history_range) (record_btrace_insn_history_from, record_btrace_call_history) (record_btrace_call_history_range) (record_btrace_call_history_from, record_btrace_record_method) (record_btrace_is_replaying, record_btrace_will_replay) (record_btrace_xfer_partial, record_btrace_insert_breakpoint) (record_btrace_remove_breakpoint, record_btrace_fetch_registers) (record_btrace_store_registers, record_btrace_prepare_to_store) (record_btrace_to_get_unwinder) (record_btrace_to_get_tailcall_unwinder, record_btrace_resume) (record_btrace_commit_resume, record_btrace_wait) (record_btrace_stop, record_btrace_can_execute_reverse) (record_btrace_stopped_by_sw_breakpoint) (record_btrace_supports_stopped_by_sw_breakpoint) (record_btrace_stopped_by_hw_breakpoint) (record_btrace_supports_stopped_by_hw_breakpoint) (record_btrace_update_thread_list, record_btrace_thread_alive) (record_btrace_goto_begin, record_btrace_goto_end) (record_btrace_goto, record_btrace_stop_replaying_all) (record_btrace_execution_direction) (record_btrace_prepare_to_generate_core) (record_btrace_done_generating_core): Refactor as record_btrace_target methods. (init_record_btrace_ops): Delete. (_initialize_record_btrace): Remove reference to init_record_btrace_ops. * record-full.c (RECORD_FULL_IS_REPLAY): Adjust to always refer to the execution_direction global. (record_full_base_target, record_full_target) (record_full_core_target): New classes. (record_full_ops): Now a record_full_target. (record_full_core_ops): Now a record_full_core_target. (record_full_target::detach, record_full_target::disconnect) (record_full_core_target::disconnect) (record_full_target::mourn_inferior, record_full_target::kill): New. (record_full_open, record_full_close, record_full_async): Refactor as methods of the record_full_base_target class. (record_full_resume, record_full_commit_resume): Refactor as methods of the record_full_target class. (record_full_wait, record_full_stopped_by_watchpoint) (record_full_stopped_data_address) (record_full_stopped_by_sw_breakpoint) (record_full_supports_stopped_by_sw_breakpoint) (record_full_stopped_by_hw_breakpoint) (record_full_supports_stopped_by_hw_breakpoint): Refactor as methods of the record_full_base_target class. (record_full_store_registers, record_full_xfer_partial) (record_full_insert_breakpoint, record_full_remove_breakpoint): Refactor as methods of the record_full_target class. (record_full_can_execute_reverse, record_full_get_bookmark) (record_full_goto_bookmark, record_full_execution_direction) (record_full_record_method, record_full_info, record_full_delete) (record_full_is_replaying, record_full_will_replay) (record_full_goto_begin, record_full_goto_end, record_full_goto) (record_full_stop_replaying): Refactor as methods of the record_full_base_target class. (record_full_core_resume, record_full_core_kill) (record_full_core_fetch_registers) (record_full_core_prepare_to_store) (record_full_core_store_registers, record_full_core_xfer_partial) (record_full_core_insert_breakpoint) (record_full_core_remove_breakpoint) (record_full_core_has_execution): Refactor as methods of the record_full_core_target class. (record_full_base_target::supports_delete_record): New. (init_record_full_ops): Delete. (init_record_full_core_ops): Delete. (record_full_save): Refactor as method of the record_full_base_target class. (_initialize_record_full): Remove references to init_record_full_ops and init_record_full_core_ops. * remote.c (remote_target, extended_remote_target): New classes. (remote_ops): Now a remote_target. (extended_remote_ops): Now an extended_remote_target. (remote_insert_fork_catchpoint, remote_remove_fork_catchpoint) (remote_insert_vfork_catchpoint, remote_remove_vfork_catchpoint) (remote_insert_exec_catchpoint, remote_remove_exec_catchpoint) (remote_pass_signals, remote_set_syscall_catchpoint) (remote_program_signals, ) (remote_thread_always_alive): Remove target_ops parameter. (remote_thread_alive, remote_thread_name) (remote_update_thread_list, remote_threads_extra_info) (remote_static_tracepoint_marker_at) (remote_static_tracepoint_markers_by_strid) (remote_get_ada_task_ptid, remote_close, remote_start_remote) (remote_open): Refactor as methods of remote_target. (extended_remote_open, extended_remote_detach) (extended_remote_attach, extended_remote_post_attach): (extended_remote_supports_disable_randomization) (extended_remote_create_inferior): : Refactor as method of extended_remote_target. (remote_set_permissions, remote_open_1, remote_detach) (remote_follow_fork, remote_follow_exec, remote_disconnect) (remote_resume, remote_commit_resume, remote_stop) (remote_interrupt, remote_pass_ctrlc, remote_terminal_inferior) (remote_terminal_ours, remote_wait, remote_fetch_registers) (remote_prepare_to_store, remote_store_registers) (remote_flash_erase, remote_flash_done, remote_files_info) (remote_kill, remote_mourn, remote_insert_breakpoint) (remote_remove_breakpoint, remote_insert_watchpoint) (remote_watchpoint_addr_within_range) (remote_remove_watchpoint, remote_region_ok_for_hw_watchpoint) (remote_check_watch_resources, remote_stopped_by_sw_breakpoint) (remote_supports_stopped_by_sw_breakpoint) (remote_stopped_by_hw_breakpoint) (remote_supports_stopped_by_hw_breakpoint) (remote_stopped_by_watchpoint, remote_stopped_data_address) (remote_insert_hw_breakpoint, remote_remove_hw_breakpoint) (remote_verify_memory): Refactor as methods of remote_target. (remote_write_qxfer, remote_read_qxfer): Remove target_ops parameter. (remote_xfer_partial, remote_get_memory_xfer_limit) (remote_search_memory, remote_rcmd, remote_memory_map) (remote_pid_to_str, remote_get_thread_local_address) (remote_get_tib_address, remote_read_description): Refactor as methods of remote_target. (remote_target::fileio_open, remote_target::fileio_pwrite) (remote_target::fileio_pread, remote_target::fileio_close): New. (remote_hostio_readlink, remote_hostio_fstat) (remote_filesystem_is_local, remote_can_execute_reverse) (remote_supports_non_stop, remote_supports_disable_randomization) (remote_supports_multi_process, remote_supports_cond_breakpoints) (remote_supports_enable_disable_tracepoint) (remote_supports_string_tracing) (remote_can_run_breakpoint_commands, remote_trace_init) (remote_download_tracepoint, remote_can_download_tracepoint) (remote_download_trace_state_variable, remote_enable_tracepoint) (remote_disable_tracepoint, remote_trace_set_readonly_regions) (remote_trace_start, remote_get_trace_status) (remote_get_tracepoint_status, remote_trace_stop) (remote_trace_find, remote_get_trace_state_variable_value) (remote_save_trace_data, remote_get_raw_trace_data) (remote_set_disconnected_tracing, remote_core_of_thread) (remote_set_circular_trace_buffer, remote_traceframe_info) (remote_get_min_fast_tracepoint_insn_len) (remote_set_trace_buffer_size, remote_set_trace_notes) (remote_use_agent, remote_can_use_agent, remote_enable_btrace) (remote_disable_btrace, remote_teardown_btrace) (remote_read_btrace, remote_btrace_conf) (remote_augmented_libraries_svr4_read, remote_load) (remote_pid_to_exec_file, remote_can_do_single_step) (remote_execution_direction, remote_thread_handle_to_thread_info): Refactor as methods of remote_target. (init_remote_ops, init_extended_remote_ops): Delete. (remote_can_async_p, remote_is_async_p, remote_async) (remote_thread_events, remote_upload_tracepoints) (remote_upload_trace_state_variables): Refactor as methods of remote_target. (_initialize_remote): Remove references to init_remote_ops and init_extended_remote_ops. * remote-sim.c (gdbsim_target): New class. (gdbsim_fetch_register, gdbsim_store_register, gdbsim_kill) (gdbsim_load, gdbsim_create_inferior, gdbsim_open, gdbsim_close) (gdbsim_detach, gdbsim_resume, gdbsim_interrupt) (gdbsim_wait, gdbsim_prepare_to_store, gdbsim_xfer_partial) (gdbsim_files_info, gdbsim_mourn_inferior, gdbsim_thread_alive) (gdbsim_pid_to_str, gdbsim_has_all_memory, gdbsim_has_memory): Refactor as methods of gdbsim_target. (gdbsim_ops): Now a gdbsim_target. (init_gdbsim_ops): Delete. (gdbsim_cntrl_c): Adjust. (_initialize_remote_sim): Remove reference to init_gdbsim_ops. * amd64-linux-nat.c (amd64_linux_nat_target): New class. (the_amd64_linux_nat_target): New. (amd64_linux_fetch_inferior_registers) (amd64_linux_store_inferior_registers): Refactor as methods of amd64_linux_nat_target. (_initialize_amd64_linux_nat): Adjust. Set linux_target. * i386-linux-nat.c: Don't include "linux-nat.h". (i386_linux_nat_target): New class. (the_i386_linux_nat_target): New. (i386_linux_fetch_inferior_registers) (i386_linux_store_inferior_registers, i386_linux_resume): Refactor as methods of i386_linux_nat_target. (_initialize_i386_linux_nat): Adjust. Set linux_target. * inf-child.c (inf_child_ops): Delete. (inf_child_fetch_inferior_registers) (inf_child_store_inferior_registers): Delete. (inf_child_post_attach, inf_child_prepare_to_store): Refactor as methods of inf_child_target. (inf_child_target::supports_terminal_ours) (inf_child_target::terminal_init) (inf_child_target::terminal_inferior) (inf_child_target::terminal_ours_for_output) (inf_child_target::terminal_ours, inf_child_target::interrupt) (inf_child_target::pass_ctrlc, inf_child_target::terminal_info): New. (inf_child_open, inf_child_disconnect, inf_child_close) (inf_child_mourn_inferior, inf_child_maybe_unpush_target) (inf_child_post_startup_inferior, inf_child_can_run) (inf_child_pid_to_exec_file): Refactor as methods of inf_child_target. (inf_child_follow_fork): Delete. (inf_child_target::can_create_inferior) (inf_child_target::can_attach): New. (inf_child_target::has_all_memory, inf_child_target::has_memory) (inf_child_target::has_stack, inf_child_target::has_registers) (inf_child_target::has_execution): New. (inf_child_fileio_open, inf_child_fileio_pwrite) (inf_child_fileio_pread, inf_child_fileio_fstat) (inf_child_fileio_close, inf_child_fileio_unlink) (inf_child_fileio_readlink, inf_child_use_agent) (inf_child_can_use_agent): Refactor as methods of inf_child_target. (return_zero, inf_child_target): Delete. (inf_child_target::inf_child_target): New. * inf-child.h: Include "target.h". (inf_child_target): Delete function prototype. (inf_child_target): New class. (inf_child_open_target, inf_child_mourn_inferior) (inf_child_maybe_unpush_target): Delete. * inf-ptrace.c (inf_ptrace_target::~inf_ptrace_target): New. (inf_ptrace_follow_fork, inf_ptrace_insert_fork_catchpoint) (inf_ptrace_remove_fork_catchpoint, inf_ptrace_create_inferior) (inf_ptrace_post_startup_inferior, inf_ptrace_mourn_inferior) (inf_ptrace_attach, inf_ptrace_post_attach, inf_ptrace_detach) (inf_ptrace_detach_success, inf_ptrace_kill, inf_ptrace_resume) (inf_ptrace_wait, inf_ptrace_xfer_partial) (inf_ptrace_thread_alive, inf_ptrace_files_info) (inf_ptrace_pid_to_str, inf_ptrace_auxv_parse): Refactor as methods of inf_ptrace_target. (inf_ptrace_target): Delete function. * inf-ptrace.h: Include "inf-child.h". (inf_ptrace_target): Delete function declaration. (inf_ptrace_target): New class. (inf_ptrace_trad_target, inf_ptrace_detach_success): Delete. * linux-nat.c (linux_target): New. (linux_ops, linux_ops_saved, super_xfer_partial): Delete. (linux_nat_target::~linux_nat_target): New. (linux_child_post_attach, linux_child_post_startup_inferior) (linux_child_follow_fork, linux_child_insert_fork_catchpoint) (linux_child_remove_fork_catchpoint) (linux_child_insert_vfork_catchpoint) (linux_child_remove_vfork_catchpoint) (linux_child_insert_exec_catchpoint) (linux_child_remove_exec_catchpoint) (linux_child_set_syscall_catchpoint, linux_nat_pass_signals) (linux_nat_create_inferior, linux_nat_attach, linux_nat_detach) (linux_nat_resume, linux_nat_stopped_by_watchpoint) (linux_nat_stopped_data_address) (linux_nat_stopped_by_sw_breakpoint) (linux_nat_supports_stopped_by_sw_breakpoint) (linux_nat_stopped_by_hw_breakpoint) (linux_nat_supports_stopped_by_hw_breakpoint, linux_nat_wait) (linux_nat_kill, linux_nat_mourn_inferior) (linux_nat_xfer_partial, linux_nat_thread_alive) (linux_nat_update_thread_list, linux_nat_pid_to_str) (linux_nat_thread_name, linux_child_pid_to_exec_file) (linux_child_static_tracepoint_markers_by_strid) (linux_nat_is_async_p, linux_nat_can_async_p) (linux_nat_supports_non_stop, linux_nat_always_non_stop_p) (linux_nat_supports_multi_process) (linux_nat_supports_disable_randomization, linux_nat_async) (linux_nat_stop, linux_nat_close, linux_nat_thread_address_space) (linux_nat_core_of_thread, linux_nat_filesystem_is_local) (linux_nat_fileio_open, linux_nat_fileio_readlink) (linux_nat_fileio_unlink, linux_nat_thread_events): Refactor as methods of linux_nat_target. (linux_nat_wait_1, linux_xfer_siginfo, linux_proc_xfer_partial) (linux_proc_xfer_spu, linux_nat_xfer_osdata): Remove target_ops parameter. (check_stopped_by_watchpoint): Adjust. (linux_xfer_partial): Delete. (linux_target_install_ops, linux_target, linux_nat_add_target): Delete. (linux_nat_target::linux_nat_target): New. * linux-nat.h: Include "inf-ptrace.h". (linux_nat_target): New. (linux_target, linux_target_install_ops, linux_nat_add_target): Delete function declarations. (linux_target): Declare global. * linux-thread-db.c (thread_db_target): New. (thread_db_target::thread_db_target): New. (thread_db_ops): Delete. (the_thread_db_target): New. (thread_db_detach, thread_db_wait, thread_db_mourn_inferior) (thread_db_update_thread_list, thread_db_pid_to_str) (thread_db_extra_thread_info) (thread_db_thread_handle_to_thread_info) (thread_db_get_thread_local_address, thread_db_get_ada_task_ptid) (thread_db_resume): Refactor as methods of thread_db_target. (init_thread_db_ops): Delete. (_initialize_thread_db): Remove reference to init_thread_db_ops. * x86-linux-nat.c: Don't include "linux-nat.h". (super_post_startup_inferior): Delete. (x86_linux_nat_target::~x86_linux_nat_target): New. (x86_linux_child_post_startup_inferior) (x86_linux_read_description, x86_linux_enable_btrace) (x86_linux_disable_btrace, x86_linux_teardown_btrace) (x86_linux_read_btrace, x86_linux_btrace_conf): Refactor as methods of x86_linux_nat_target. (x86_linux_create_target): Delete. Bits folded ... (x86_linux_add_target): ... here. Now takes a linux_nat_target pointer. * x86-linux-nat.h: Include "linux-nat.h" and "x86-nat.h". (x86_linux_nat_target): New class. (x86_linux_create_target): Delete. (x86_linux_add_target): Now takes a linux_nat_target pointer. * x86-nat.c (x86_insert_watchpoint, x86_remove_watchpoint) (x86_region_ok_for_watchpoint, x86_stopped_data_address) (x86_stopped_by_watchpoint, x86_insert_hw_breakpoint) (x86_remove_hw_breakpoint, x86_can_use_hw_breakpoint) (x86_stopped_by_hw_breakpoint): Remove target_ops parameter and make extern. (x86_use_watchpoints): Delete. * x86-nat.h: Include "breakpoint.h" and "target.h". (x86_use_watchpoints): Delete. (x86_can_use_hw_breakpoint, x86_region_ok_for_hw_watchpoint) (x86_stopped_by_watchpoint, x86_stopped_data_address) (x86_insert_watchpoint, x86_remove_watchpoint) (x86_insert_hw_breakpoint, x86_remove_hw_breakpoint) (x86_stopped_by_hw_breakpoint): New declarations. (x86_nat_target): New template class. * ppc-linux-nat.c (ppc_linux_nat_target): New class. (the_ppc_linux_nat_target): New. (ppc_linux_fetch_inferior_registers) (ppc_linux_can_use_hw_breakpoint) (ppc_linux_region_ok_for_hw_watchpoint) (ppc_linux_ranged_break_num_registers) (ppc_linux_insert_hw_breakpoint, ppc_linux_remove_hw_breakpoint) (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_can_accel_watchpoint_condition) (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint) (ppc_linux_stopped_data_address, ppc_linux_stopped_by_watchpoint) (ppc_linux_watchpoint_addr_within_range) (ppc_linux_masked_watch_num_registers) (ppc_linux_store_inferior_registers, ppc_linux_auxv_parse) (ppc_linux_read_description): Refactor as methods of ppc_linux_nat_target. (_initialize_ppc_linux_nat): Adjust. Set linux_target. * procfs.c (procfs_xfer_partial): Delete forward declaration. (procfs_target): New class. (the_procfs_target): New. (procfs_target): Delete function. (procfs_auxv_parse, procfs_attach, procfs_detach) (procfs_fetch_registers, procfs_store_registers, procfs_wait) (procfs_xfer_partial, procfs_resume, procfs_pass_signals) (procfs_files_info, procfs_kill_inferior, procfs_mourn_inferior) (procfs_create_inferior, procfs_update_thread_list) (procfs_thread_alive, procfs_pid_to_str) (procfs_can_use_hw_breakpoint, procfs_stopped_by_watchpoint) (procfs_stopped_data_address, procfs_insert_watchpoint) (procfs_remove_watchpoint, procfs_region_ok_for_hw_watchpoint) (proc_find_memory_regions, procfs_info_proc) (procfs_make_note_section): Refactor as methods of procfs_target. (_initialize_procfs): Adjust. * sol-thread.c (sol_thread_target): New class. (sol_thread_ops): Now a sol_thread_target. (sol_thread_detach, sol_thread_resume, sol_thread_wait) (sol_thread_fetch_registers, sol_thread_store_registers) (sol_thread_xfer_partial, sol_thread_mourn_inferior) (sol_thread_alive, solaris_pid_to_str, sol_update_thread_list) (sol_get_ada_task_ptid): Refactor as methods of sol_thread_target. (init_sol_thread_ops): Delete. (_initialize_sol_thread): Adjust. Remove references to init_sol_thread_ops and complete_target_initialization. * windows-nat.c (windows_nat_target): New class. (windows_fetch_inferior_registers) (windows_store_inferior_registers, windows_resume, windows_wait) (windows_attach, windows_detach, windows_pid_to_exec_file) (windows_files_info, windows_create_inferior) (windows_mourn_inferior, windows_interrupt, windows_kill_inferior) (windows_close, windows_pid_to_str, windows_xfer_partial) (windows_get_tib_address, windows_get_ada_task_ptid) (windows_thread_name, windows_thread_alive): Refactor as windows_nat_target methods. (do_initial_windows_stuff): Adjust. (windows_target): Delete function. (_initialize_windows_nat): Adjust. * darwin-nat.c (darwin_resume, darwin_wait_to, darwin_interrupt) (darwin_mourn_inferior, darwin_kill_inferior) (darwin_create_inferior, darwin_attach, darwin_detach) (darwin_pid_to_str, darwin_thread_alive, darwin_xfer_partial) (darwin_pid_to_exec_file, darwin_get_ada_task_ptid) (darwin_supports_multi_process): Refactor as darwin_nat_target methods. (darwin_resume_to, darwin_files_info): Delete. (_initialize_darwin_inferior): Rename to ... (_initialize_darwin_nat): ... this. Adjust to C++ification. * darwin-nat.h: Include "inf-child.h". (darwin_nat_target): New class. (darwin_complete_target): Delete. * i386-darwin-nat.c (i386_darwin_nat_target): New class. (darwin_target): New. (i386_darwin_fetch_inferior_registers) (i386_darwin_store_inferior_registers): Refactor as methods of darwin_nat_target. (darwin_complete_target): Delete, with ... (_initialize_i386_darwin_nat): ... bits factored out here. * alpha-linux-nat.c (alpha_linux_nat_target): New class. (the_alpha_linux_nat_target): New. (alpha_linux_register_u_offset): Refactor as alpha_linux_nat_target method. (_initialize_alpha_linux_nat): Adjust. * linux-nat-trad.c (inf_ptrace_register_u_offset): Delete. (inf_ptrace_fetch_register, inf_ptrace_fetch_registers) (inf_ptrace_store_register, inf_ptrace_store_registers): Refact as methods of linux_nat_trad_target. (linux_trad_target): Delete. * linux-nat-trad.h (linux_trad_target): Delete function. (linux_nat_trad_target): New class. * mips-linux-nat.c (mips_linux_nat_target): New class. (super_fetch_registers, super_store_registers, super_close): Delete. (the_mips_linux_nat_target): New. (mips64_linux_regsets_fetch_registers) (mips64_linux_regsets_store_registers) (mips64_linux_fetch_registers, mips64_linux_store_registers) (mips_linux_register_u_offset, mips_linux_read_description) (mips_linux_can_use_hw_breakpoint) (mips_linux_stopped_by_watchpoint) (mips_linux_stopped_data_address) (mips_linux_region_ok_for_hw_watchpoint) (mips_linux_insert_watchpoint, mips_linux_remove_watchpoint) (mips_linux_close): Refactor as methods of mips_linux_nat. (_initialize_mips_linux_nat): Adjust to C++ification. * aix-thread.c (aix_thread_target): New class. (aix_thread_ops): Now an aix_thread_target. (aix_thread_detach, aix_thread_resume, aix_thread_wait) (aix_thread_fetch_registers, aix_thread_store_registers) (aix_thread_xfer_partial, aix_thread_mourn_inferior) (aix_thread_thread_alive, aix_thread_pid_to_str) (aix_thread_extra_thread_info, aix_thread_get_ada_task_ptid): Refactor as methods of aix_thread_target. (init_aix_thread_ops): Delete. (_initialize_aix_thread): Remove references to init_aix_thread_ops and complete_target_initialization. * rs6000-nat.c (rs6000_xfer_shared_libraries): Delete. (rs6000_nat_target): New class. (the_rs6000_nat_target): New. (rs6000_fetch_inferior_registers, rs6000_store_inferior_registers) (rs6000_xfer_partial, rs6000_wait, rs6000_create_inferior) (rs6000_xfer_shared_libraries): Refactor as rs6000_nat_target methods. (super_create_inferior): Delete. (_initialize_rs6000_nat): Adjust to C++ification. * arm-linux-nat.c (arm_linux_nat_target): New class. (the_arm_linux_nat_target): New. (arm_linux_fetch_inferior_registers) (arm_linux_store_inferior_registers, arm_linux_read_description) (arm_linux_can_use_hw_breakpoint, arm_linux_insert_hw_breakpoint) (arm_linux_remove_hw_breakpoint) (arm_linux_region_ok_for_hw_watchpoint) (arm_linux_insert_watchpoint, arm_linux_remove_watchpoint) (arm_linux_stopped_data_address, arm_linux_stopped_by_watchpoint) (arm_linux_watchpoint_addr_within_range): Refactor as methods of arm_linux_nat_target. (_initialize_arm_linux_nat): Adjust to C++ification. * aarch64-linux-nat.c (aarch64_linux_nat_target): New class. (the_aarch64_linux_nat_target): New. (aarch64_linux_fetch_inferior_registers) (aarch64_linux_store_inferior_registers) (aarch64_linux_child_post_startup_inferior) (aarch64_linux_read_description) (aarch64_linux_can_use_hw_breakpoint) (aarch64_linux_insert_hw_breakpoint) (aarch64_linux_remove_hw_breakpoint) (aarch64_linux_insert_watchpoint, aarch64_linux_remove_watchpoint) (aarch64_linux_region_ok_for_hw_watchpoint) (aarch64_linux_stopped_data_address) (aarch64_linux_stopped_by_watchpoint) (aarch64_linux_watchpoint_addr_within_range) (aarch64_linux_can_do_single_step): Refactor as methods of aarch64_linux_nat_target. (super_post_startup_inferior): Delete. (_initialize_aarch64_linux_nat): Adjust to C++ification. * hppa-linux-nat.c (hppa_linux_nat_target): New class. (the_hppa_linux_nat_target): New. (hppa_linux_fetch_inferior_registers) (hppa_linux_store_inferior_registers): Refactor as methods of hppa_linux_nat_target. (_initialize_hppa_linux_nat): Adjust to C++ification. * ia64-linux-nat.c (ia64_linux_nat_target): New class. (the_ia64_linux_nat_target): New. (ia64_linux_insert_watchpoint, ia64_linux_remove_watchpoint) (ia64_linux_stopped_data_address) (ia64_linux_stopped_by_watchpoint, ia64_linux_fetch_registers) (ia64_linux_store_registers, ia64_linux_xfer_partial): Refactor as ia64_linux_nat_target methods. (super_xfer_partial): Delete. (_initialize_ia64_linux_nat): Adjust to C++ification. * m32r-linux-nat.c (m32r_linux_nat_target): New class. (the_m32r_linux_nat_target): New. (m32r_linux_fetch_inferior_registers) (m32r_linux_store_inferior_registers): Refactor as m32r_linux_nat_target methods. (_initialize_m32r_linux_nat): Adjust to C++ification. * m68k-linux-nat.c (m68k_linux_nat_target): New class. (the_m68k_linux_nat_target): New. (m68k_linux_fetch_inferior_registers) (m68k_linux_store_inferior_registers): Refactor as m68k_linux_nat_target methods. (_initialize_m68k_linux_nat): Adjust to C++ification. * s390-linux-nat.c (s390_linux_nat_target): New class. (the_s390_linux_nat_target): New. (s390_linux_fetch_inferior_registers) (s390_linux_store_inferior_registers, s390_stopped_by_watchpoint) (s390_insert_watchpoint, s390_remove_watchpoint) (s390_can_use_hw_breakpoint, s390_insert_hw_breakpoint) (s390_remove_hw_breakpoint, s390_region_ok_for_hw_watchpoint) (s390_auxv_parse, s390_read_description): Refactor as methods of s390_linux_nat_target. (_initialize_s390_nat): Adjust to C++ification. * sparc-linux-nat.c (sparc_linux_nat_target): New class. (the_sparc_linux_nat_target): New. (_initialize_sparc_linux_nat): Adjust to C++ification. * sparc-nat.c (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc64-linux-nat.c (sparc64_linux_nat_target): New class. (the_sparc64_linux_nat_target): New. (_initialize_sparc64_linux_nat): Adjust to C++ification. * spu-linux-nat.c (spu_linux_nat_target): New class. (the_spu_linux_nat_target): New. (spu_child_post_startup_inferior, spu_child_post_attach) (spu_child_wait, spu_fetch_inferior_registers) (spu_store_inferior_registers, spu_xfer_partial) (spu_can_use_hw_breakpoint): Refactor as spu_linux_nat_target methods. (_initialize_spu_nat): Adjust to C++ification. * tilegx-linux-nat.c (tilegx_linux_nat_target): New class. (the_tilegx_linux_nat_target): New. (fetch_inferior_registers, store_inferior_registers): Refactor as methods. (_initialize_tile_linux_nat): Adjust to C++ification. * xtensa-linux-nat.c (xtensa_linux_nat_target): New class. (the_xtensa_linux_nat_target): New. (xtensa_linux_fetch_inferior_registers) (xtensa_linux_store_inferior_registers): Refactor as xtensa_linux_nat_target methods. (_initialize_xtensa_linux_nat): Adjust to C++ification. * fbsd-nat.c (USE_SIGTRAP_SIGINFO): Delete. (fbsd_pid_to_exec_file, fbsd_find_memory_regions) (fbsd_find_memory_regions, fbsd_info_proc, fbsd_xfer_partial) (fbsd_thread_alive, fbsd_pid_to_str, fbsd_thread_name) (fbsd_update_thread_list, fbsd_resume, fbsd_wait) (fbsd_stopped_by_sw_breakpoint) (fbsd_supports_stopped_by_sw_breakpoint, fbsd_follow_fork) (fbsd_insert_fork_catchpoint, fbsd_remove_fork_catchpoint) (fbsd_insert_vfork_catchpoint, fbsd_remove_vfork_catchpoint) (fbsd_post_startup_inferior, fbsd_post_attach) (fbsd_insert_exec_catchpoint, fbsd_remove_exec_catchpoint) (fbsd_set_syscall_catchpoint) (super_xfer_partial, super_resume, super_wait) (fbsd_supports_stopped_by_hw_breakpoint): Delete. (fbsd_handle_debug_trap): Remove target_ops parameter. (fbsd_nat_add_target): Delete. * fbsd-nat.h: Include "inf-ptrace.h". (fbsd_nat_add_target): Delete. (USE_SIGTRAP_SIGINFO): Define. (fbsd_nat_target): New class. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers) (amd64bsd_store_inferior_registers): Remove target_ops parameter. (amd64bsd_target): Delete. * amd64-bsd-nat.h: New file. * amd64-fbsd-nat.c: Include "amd64-bsd-nat.h" instead of "x86-bsd-nat.h". (amd64_fbsd_nat_target): New class. (the_amd64_fbsd_nat_target): New. (amd64fbsd_read_description): Refactor as method of amd64_fbsd_nat_target. (amd64_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_amd64fbsd_nat): Adjust to C++ification. * amd64-nat.h (amd64bsd_target): Delete function declaration. * i386-bsd-nat.c (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Remove target_ops parameter. (i386bsd_target): Delete. * i386-bsd-nat.h (i386bsd_target): Delete function declaration. (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Declare. (i386_bsd_nat_target): New class. * i386-fbsd-nat.c (i386_fbsd_nat_target): New class. (the_i386_fbsd_nat_target): New. (i386fbsd_resume, i386fbsd_read_description): Refactor as i386_fbsd_nat_target methods. (i386_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_i386fbsd_nat): Adjust to C++ification. * x86-bsd-nat.c (super_mourn_inferior): Delete. (x86bsd_mourn_inferior, x86bsd_target): Delete. (_initialize_x86_bsd_nat): Adjust to C++ification. * x86-bsd-nat.h: Include "x86-nat.h". (x86bsd_target): Delete declaration. (x86bsd_nat_target): New class. * aarch64-fbsd-nat.c (aarch64_fbsd_nat_target): New class. (the_aarch64_fbsd_nat_target): New. (aarch64_fbsd_fetch_inferior_registers) (aarch64_fbsd_store_inferior_registers): Refactor as methods of aarch64_fbsd_nat_target. (_initialize_aarch64_fbsd_nat): Adjust to C++ification. * alpha-bsd-nat.c (alpha_bsd_nat_target): New class. (the_alpha_bsd_nat_target): New. (alphabsd_fetch_inferior_registers) (alphabsd_store_inferior_registers): Refactor as alpha_bsd_nat_target methods. (_initialize_alphabsd_nat): Refactor as methods of alpha_bsd_nat_target. * amd64-nbsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_nbsd_nat_target): New. (_initialize_amd64nbsd_nat): Adjust to C++ification. * amd64-obsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_obsd_nat_target): New. (_initialize_amd64obsd_nat): Adjust to C++ification. * arm-fbsd-nat.c (arm_fbsd_nat_target): New. (the_arm_fbsd_nat_target): New. (arm_fbsd_fetch_inferior_registers) (arm_fbsd_store_inferior_registers, arm_fbsd_read_description): (_initialize_arm_fbsd_nat): Refactor as methods of arm_fbsd_nat_target. (_initialize_arm_fbsd_nat): Adjust to C++ification. * arm-nbsd-nat.c (arm_netbsd_nat_target): New class. (the_arm_netbsd_nat_target): New. (armnbsd_fetch_registers, armnbsd_store_registers): Refactor as arm_netbsd_nat_target. (_initialize_arm_netbsd_nat): Adjust to C++ification. * hppa-nbsd-nat.c (hppa_nbsd_nat_target): New class. (the_hppa_nbsd_nat_target): New. (hppanbsd_fetch_registers, hppanbsd_store_registers): Refactor as hppa_nbsd_nat_target methods. (_initialize_hppanbsd_nat): Adjust to C++ification. * hppa-obsd-nat.c (hppa_obsd_nat_target): New class. (the_hppa_obsd_nat_target): New. (hppaobsd_fetch_registers, hppaobsd_store_registers): Refactor as methods of hppa_obsd_nat_target. (_initialize_hppaobsd_nat): Adjust to C++ification. Use add_target. * i386-nbsd-nat.c (the_i386_nbsd_nat_target): New. (_initialize_i386nbsd_nat): Adjust to C++ification. Use add_target. * i386-obsd-nat.c (the_i386_obsd_nat_target): New. (_initialize_i386obsd_nat): Use add_target. * m68k-bsd-nat.c (m68k_bsd_nat_target): New class. (the_m68k_bsd_nat_target): New. (m68kbsd_fetch_inferior_registers) (m68kbsd_store_inferior_registers): Refactor as methods of m68k_bsd_nat_target. (_initialize_m68kbsd_nat): Adjust to C++ification. * mips-fbsd-nat.c (mips_fbsd_nat_target): New class. (the_mips_fbsd_nat_target): New. (mips_fbsd_fetch_inferior_registers) (mips_fbsd_store_inferior_registers): Refactor as methods of mips_fbsd_nat_target. (_initialize_mips_fbsd_nat): Adjust to C++ification. Use add_target. * mips-nbsd-nat.c (mips_nbsd_nat_target): New class. (the_mips_nbsd_nat_target): New. (mipsnbsd_fetch_inferior_registers) (mipsnbsd_store_inferior_registers): Refactor as methods of mips_nbsd_nat_target. (_initialize_mipsnbsd_nat): Adjust to C++ification. * mips64-obsd-nat.c (mips64_obsd_nat_target): New class. (the_mips64_obsd_nat_target): New. (mips64obsd_fetch_inferior_registers) (mips64obsd_store_inferior_registers): Refactor as methods of mips64_obsd_nat_target. (_initialize_mips64obsd_nat): Adjust to C++ification. Use add_target. * nbsd-nat.c (nbsd_pid_to_exec_file): Refactor as method of nbsd_nat_target. * nbsd-nat.h: Include "inf-ptrace.h". (nbsd_nat_target): New class. * obsd-nat.c (obsd_pid_to_str, obsd_update_thread_list) (obsd_wait): Refactor as methods of obsd_nat_target. (obsd_add_target): Delete. * obsd-nat.h: Include "inf-ptrace.h". (obsd_nat_target): New class. * ppc-fbsd-nat.c (ppc_fbsd_nat_target): New class. (the_ppc_fbsd_nat_target): New. (ppcfbsd_fetch_inferior_registers) (ppcfbsd_store_inferior_registers): Refactor as methods of ppc_fbsd_nat_target. (_initialize_ppcfbsd_nat): Adjust to C++ification. Use add_target. * ppc-nbsd-nat.c (ppc_nbsd_nat_target): New class. (the_ppc_nbsd_nat_target): New. (ppcnbsd_fetch_inferior_registers) (ppcnbsd_store_inferior_registers): Refactor as methods of ppc_nbsd_nat_target. (_initialize_ppcnbsd_nat): Adjust to C++ification. * ppc-obsd-nat.c (ppc_obsd_nat_target): New class. (the_ppc_obsd_nat_target): New. (ppcobsd_fetch_registers, ppcobsd_store_registers): Refactor as methods of ppc_obsd_nat_target. (_initialize_ppcobsd_nat): Adjust to C++ification. Use add_target. * sh-nbsd-nat.c (sh_nbsd_nat_target): New class. (the_sh_nbsd_nat_target): New. (shnbsd_fetch_inferior_registers) (shnbsd_store_inferior_registers): Refactor as methods of sh_nbsd_nat_target. (_initialize_shnbsd_nat): Adjust to C++ification. * sparc-nat.c (sparc_xfer_wcookie): Make extern. (inf_ptrace_xfer_partial): Delete. (sparc_xfer_partial, sparc_target): Delete. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers, sparc_xfer_wcookie): Declare. (sparc_target): Delete function declaration. (sparc_target): New template class. * sparc-nbsd-nat.c (the_sparc_nbsd_nat_target): New. (_initialize_sparcnbsd_nat): Adjust to C++ification. * sparc64-fbsd-nat.c (the_sparc64_fbsd_nat_target): New. (_initialize_sparc64fbsd_nat): Adjust to C++ification. Use add_target. * sparc64-nbsd-nat.c (the_sparc64_nbsd_nat_target): New. (_initialize_sparc64nbsd_nat): Adjust to C++ification. * sparc64-obsd-nat.c (the_sparc64_obsd_nat_target): New. (_initialize_sparc64obsd_nat): Adjust to C++ification. Use add_target. * vax-bsd-nat.c (vax_bsd_nat_target): New class. (the_vax_bsd_nat_target): New. (vaxbsd_fetch_inferior_registers) (vaxbsd_store_inferior_registers): Refactor as vax_bsd_nat_target methods. (_initialize_vaxbsd_nat): Adjust to C++ification. * bsd-kvm.c (bsd_kvm_target): New class. (bsd_kvm_ops): Now a bsd_kvm_target. (bsd_kvm_open, bsd_kvm_close, bsd_kvm_xfer_partial) (bsd_kvm_files_info, bsd_kvm_fetch_registers) (bsd_kvm_thread_alive, bsd_kvm_pid_to_str): Refactor as methods of bsd_kvm_target. (bsd_kvm_return_one): Delete. (bsd_kvm_add_target): Adjust to C++ification. * nto-procfs.c (nto_procfs_target, nto_procfs_target_native) (nto_procfs_target_procfs): New classes. (procfs_open_1, procfs_thread_alive, procfs_update_thread_list) (procfs_files_info, procfs_pid_to_exec_file, procfs_attach) (procfs_post_attach, procfs_wait, procfs_fetch_registers) (procfs_xfer_partial, procfs_detach, procfs_insert_breakpoint) (procfs_remove_breakpoint, procfs_insert_hw_breakpoint) (procfs_remove_hw_breakpoint, procfs_resume) (procfs_mourn_inferior, procfs_create_inferior, procfs_interrupt) (procfs_kill_inferior, procfs_store_registers) (procfs_pass_signals, procfs_pid_to_str, procfs_can_run): Refactor as methods of nto_procfs_target. (nto_procfs_ops): Now an nto_procfs_target_procfs. (nto_native_ops): Delete. (procfs_open, procfs_native_open): Delete. (nto_native_ops): Now an nto_procfs_target_native. (init_procfs_targets): Adjust to C++ification. (procfs_can_use_hw_breakpoint, procfs_remove_hw_watchpoint) (procfs_insert_hw_watchpoint, procfs_stopped_by_watchpoint): Refactor as methods of nto_procfs_target. * go32-nat.c (go32_nat_target): New class. (the_go32_nat_target): New. (go32_attach, go32_resume, go32_wait, go32_fetch_registers) (go32_store_registers, go32_xfer_partial, go32_files_info) (go32_kill_inferior, go32_create_inferior, go32_mourn_inferior) (go32_terminal_init, go32_terminal_info, go32_terminal_inferior) (go32_terminal_ours, go32_pass_ctrlc, go32_thread_alive) (go32_pid_to_str): Refactor as methods of go32_nat_target. (go32_target): Delete. (_initialize_go32_nat): Adjust to C++ification. * gnu-nat.c (gnu_wait, gnu_resume, gnu_kill_inferior) (gnu_mourn_inferior, gnu_create_inferior, gnu_attach, gnu_detach) (gnu_stop, gnu_thread_alive, gnu_xfer_partial) (gnu_find_memory_regions, gnu_pid_to_str): Refactor as methods of gnu_nat_target. (gnu_target): Delete. * gnu-nat.h (gnu_target): Delete. (gnu_nat_target): New class. * i386-gnu-nat.c (gnu_base_target): New. (i386_gnu_nat_target): New class. (the_i386_gnu_nat_target): New. (_initialize_i386gnu_nat): Adjust to C++ification. gdb/testsuite/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * gdb.base/breakpoint-in-ro-region.exp: Adjust to to_resume and to_log_command renames. * gdb.base/sss-bp-on-user-bp-2.exp: Likewise.
2018-05-03 07:37:22 +08:00
struct expression *cond)
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
{
CORE_ADDR data_value;
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
m_dreg_interface.detect (inferior_ptid);
return (m_dreg_interface.hwdebug_p ()
&& (m_dreg_interface.hwdebug_info ().num_condition_regs > 0)
&& check_condition (addr, cond, &data_value, &len));
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
}
2011-01-11 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Implement support for PowerPC BookE ranged watchpoints. gdb/ * breakpoint.h (struct breakpoint_ops) <resources_needed>: New method. Initialize to NULL in all existing breakpoint_ops instances. (struct breakpoint) <exact>: New field. (target_exact_watchpoints): Declare external global. * breakpoint.c (target_exact_watchpoints): New global flag. (update_watchpoint): Set b->type to bp_hardware_watchpoint and b->enable_state to bp_enabled before calling hw_watchpoint_used_count. (hw_watchpoint_used_count): Iterate over all bp_locations in a watchpoint. Call breakpoint's breakpoint_ops.resources_needed if available. (insert_watchpoint, remove_watchpoint): Use fixed length of 1 byte if the watchpoint is exact. (resources_needed_watchpoint): New function. (watchpoint_breakpoint_ops): Add resources_needed_watchpoint. (watch_command_1): Set b->exact if the user asked for an exact watchpoint and one can be set. (can_use_hardware_watchpoint): Add exact_watchpoints argument. Pass fixed length of 1 to target_region_ok_for_hw_watchpoint if the user asks for an exact watchpoint and one can be set. Return number of needed debug registers to watch the expression. * gdbtypes.c (is_scalar_type): New function, based on valprint.c:scalar_type_p. (is_scalar_type_recursive): New function. * gdbtypes.h (is_scalar_type_recursive): Declare. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Always handle regions when ranged watchpoints are available. (create_watchpoint_request): New function. (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint): Use create_watchpoint_request. * rs6000-tdep.c (show_powerpc_exact_watchpoints): New function. (_initialize_rs6000_tdep): Add `exact-watchpoints' boolean to the `set powerpc' and `show powerpc' commands. * target.h (struct target_ops) <to_region_ok_for_hw_watchpoint>: Mention documentation comment in the target macro. (target_region_ok_for_hw_watchpoint): Document return value. gdb/doc/ * gdb.texinfo (PowerPC Embedded): Document ranged watchpoints and the "set powerpc exact-watchpoints" flag.
2011-01-12 03:23:03 +08:00
/* Set up P with the parameters necessary to request a watchpoint covering
LEN bytes starting at ADDR and if possible with condition expression COND
evaluated by hardware. INSERT tells if we are creating a request for
inserting or removing the watchpoint. */
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
void
ppc_linux_nat_target::create_watchpoint_request (struct ppc_hw_breakpoint *p,
CORE_ADDR addr, int len,
enum target_hw_bp_type type,
struct expression *cond,
int insert)
2011-01-11 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Implement support for PowerPC BookE ranged watchpoints. gdb/ * breakpoint.h (struct breakpoint_ops) <resources_needed>: New method. Initialize to NULL in all existing breakpoint_ops instances. (struct breakpoint) <exact>: New field. (target_exact_watchpoints): Declare external global. * breakpoint.c (target_exact_watchpoints): New global flag. (update_watchpoint): Set b->type to bp_hardware_watchpoint and b->enable_state to bp_enabled before calling hw_watchpoint_used_count. (hw_watchpoint_used_count): Iterate over all bp_locations in a watchpoint. Call breakpoint's breakpoint_ops.resources_needed if available. (insert_watchpoint, remove_watchpoint): Use fixed length of 1 byte if the watchpoint is exact. (resources_needed_watchpoint): New function. (watchpoint_breakpoint_ops): Add resources_needed_watchpoint. (watch_command_1): Set b->exact if the user asked for an exact watchpoint and one can be set. (can_use_hardware_watchpoint): Add exact_watchpoints argument. Pass fixed length of 1 to target_region_ok_for_hw_watchpoint if the user asks for an exact watchpoint and one can be set. Return number of needed debug registers to watch the expression. * gdbtypes.c (is_scalar_type): New function, based on valprint.c:scalar_type_p. (is_scalar_type_recursive): New function. * gdbtypes.h (is_scalar_type_recursive): Declare. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Always handle regions when ranged watchpoints are available. (create_watchpoint_request): New function. (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint): Use create_watchpoint_request. * rs6000-tdep.c (show_powerpc_exact_watchpoints): New function. (_initialize_rs6000_tdep): Add `exact-watchpoints' boolean to the `set powerpc' and `show powerpc' commands. * target.h (struct target_ops) <to_region_ok_for_hw_watchpoint>: Mention documentation comment in the target macro. (target_region_ok_for_hw_watchpoint): Document return value. gdb/doc/ * gdb.texinfo (PowerPC Embedded): Document ranged watchpoints and the "set powerpc exact-watchpoints" flag.
2011-01-12 03:23:03 +08:00
{
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
const struct ppc_debug_info &hwdebug_info = (m_dreg_interface
.hwdebug_info ());
if (len == 1
|| !(hwdebug_info.features & PPC_DEBUG_FEATURE_DATA_BP_RANGE))
2011-01-11 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Implement support for PowerPC BookE ranged watchpoints. gdb/ * breakpoint.h (struct breakpoint_ops) <resources_needed>: New method. Initialize to NULL in all existing breakpoint_ops instances. (struct breakpoint) <exact>: New field. (target_exact_watchpoints): Declare external global. * breakpoint.c (target_exact_watchpoints): New global flag. (update_watchpoint): Set b->type to bp_hardware_watchpoint and b->enable_state to bp_enabled before calling hw_watchpoint_used_count. (hw_watchpoint_used_count): Iterate over all bp_locations in a watchpoint. Call breakpoint's breakpoint_ops.resources_needed if available. (insert_watchpoint, remove_watchpoint): Use fixed length of 1 byte if the watchpoint is exact. (resources_needed_watchpoint): New function. (watchpoint_breakpoint_ops): Add resources_needed_watchpoint. (watch_command_1): Set b->exact if the user asked for an exact watchpoint and one can be set. (can_use_hardware_watchpoint): Add exact_watchpoints argument. Pass fixed length of 1 to target_region_ok_for_hw_watchpoint if the user asks for an exact watchpoint and one can be set. Return number of needed debug registers to watch the expression. * gdbtypes.c (is_scalar_type): New function, based on valprint.c:scalar_type_p. (is_scalar_type_recursive): New function. * gdbtypes.h (is_scalar_type_recursive): Declare. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Always handle regions when ranged watchpoints are available. (create_watchpoint_request): New function. (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint): Use create_watchpoint_request. * rs6000-tdep.c (show_powerpc_exact_watchpoints): New function. (_initialize_rs6000_tdep): Add `exact-watchpoints' boolean to the `set powerpc' and `show powerpc' commands. * target.h (struct target_ops) <to_region_ok_for_hw_watchpoint>: Mention documentation comment in the target macro. (target_region_ok_for_hw_watchpoint): Document return value. gdb/doc/ * gdb.texinfo (PowerPC Embedded): Document ranged watchpoints and the "set powerpc exact-watchpoints" flag.
2011-01-12 03:23:03 +08:00
{
int use_condition;
CORE_ADDR data_value;
use_condition = (insert? can_use_watchpoint_cond_accel ()
: hwdebug_info.num_condition_regs > 0);
if (cond && use_condition && check_condition (addr, cond,
&data_value, &len))
2011-01-11 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Implement support for PowerPC BookE ranged watchpoints. gdb/ * breakpoint.h (struct breakpoint_ops) <resources_needed>: New method. Initialize to NULL in all existing breakpoint_ops instances. (struct breakpoint) <exact>: New field. (target_exact_watchpoints): Declare external global. * breakpoint.c (target_exact_watchpoints): New global flag. (update_watchpoint): Set b->type to bp_hardware_watchpoint and b->enable_state to bp_enabled before calling hw_watchpoint_used_count. (hw_watchpoint_used_count): Iterate over all bp_locations in a watchpoint. Call breakpoint's breakpoint_ops.resources_needed if available. (insert_watchpoint, remove_watchpoint): Use fixed length of 1 byte if the watchpoint is exact. (resources_needed_watchpoint): New function. (watchpoint_breakpoint_ops): Add resources_needed_watchpoint. (watch_command_1): Set b->exact if the user asked for an exact watchpoint and one can be set. (can_use_hardware_watchpoint): Add exact_watchpoints argument. Pass fixed length of 1 to target_region_ok_for_hw_watchpoint if the user asks for an exact watchpoint and one can be set. Return number of needed debug registers to watch the expression. * gdbtypes.c (is_scalar_type): New function, based on valprint.c:scalar_type_p. (is_scalar_type_recursive): New function. * gdbtypes.h (is_scalar_type_recursive): Declare. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Always handle regions when ranged watchpoints are available. (create_watchpoint_request): New function. (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint): Use create_watchpoint_request. * rs6000-tdep.c (show_powerpc_exact_watchpoints): New function. (_initialize_rs6000_tdep): Add `exact-watchpoints' boolean to the `set powerpc' and `show powerpc' commands. * target.h (struct target_ops) <to_region_ok_for_hw_watchpoint>: Mention documentation comment in the target macro. (target_region_ok_for_hw_watchpoint): Document return value. gdb/doc/ * gdb.texinfo (PowerPC Embedded): Document ranged watchpoints and the "set powerpc exact-watchpoints" flag.
2011-01-12 03:23:03 +08:00
calculate_dvc (addr, len, data_value, &p->condition_mode,
&p->condition_value);
else
{
p->condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
p->condition_value = 0;
}
p->addr_mode = PPC_BREAKPOINT_MODE_EXACT;
p->addr2 = 0;
}
else
{
p->addr_mode = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
p->condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
p->condition_value = 0;
/* The watchpoint will trigger if the address of the memory access is
within the defined range, as follows: p->addr <= address < p->addr2.
Note that the above sentence just documents how ptrace interprets
its arguments; the watchpoint is set to watch the range defined by
the user _inclusively_, as specified by the user interface. */
p->addr2 = (uint64_t) addr + len;
}
p->version = PPC_DEBUG_CURRENT_VERSION;
p->trigger_type = get_trigger_type (type);
2011-01-11 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Implement support for PowerPC BookE ranged watchpoints. gdb/ * breakpoint.h (struct breakpoint_ops) <resources_needed>: New method. Initialize to NULL in all existing breakpoint_ops instances. (struct breakpoint) <exact>: New field. (target_exact_watchpoints): Declare external global. * breakpoint.c (target_exact_watchpoints): New global flag. (update_watchpoint): Set b->type to bp_hardware_watchpoint and b->enable_state to bp_enabled before calling hw_watchpoint_used_count. (hw_watchpoint_used_count): Iterate over all bp_locations in a watchpoint. Call breakpoint's breakpoint_ops.resources_needed if available. (insert_watchpoint, remove_watchpoint): Use fixed length of 1 byte if the watchpoint is exact. (resources_needed_watchpoint): New function. (watchpoint_breakpoint_ops): Add resources_needed_watchpoint. (watch_command_1): Set b->exact if the user asked for an exact watchpoint and one can be set. (can_use_hardware_watchpoint): Add exact_watchpoints argument. Pass fixed length of 1 to target_region_ok_for_hw_watchpoint if the user asks for an exact watchpoint and one can be set. Return number of needed debug registers to watch the expression. * gdbtypes.c (is_scalar_type): New function, based on valprint.c:scalar_type_p. (is_scalar_type_recursive): New function. * gdbtypes.h (is_scalar_type_recursive): Declare. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Always handle regions when ranged watchpoints are available. (create_watchpoint_request): New function. (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint): Use create_watchpoint_request. * rs6000-tdep.c (show_powerpc_exact_watchpoints): New function. (_initialize_rs6000_tdep): Add `exact-watchpoints' boolean to the `set powerpc' and `show powerpc' commands. * target.h (struct target_ops) <to_region_ok_for_hw_watchpoint>: Mention documentation comment in the target macro. (target_region_ok_for_hw_watchpoint): Document return value. gdb/doc/ * gdb.texinfo (PowerPC Embedded): Document ranged watchpoints and the "set powerpc exact-watchpoints" flag.
2011-01-12 03:23:03 +08:00
p->addr = (uint64_t) addr;
}
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
/* Register a watchpoint, to be inserted when the threads of the group of
inferior_ptid are next resumed. Returns 0 on success, and -1 if there
is no ptrace interface available to install the watchpoint. */
Convert struct target_ops to C++ I.e., use C++ virtual methods and inheritance instead of tables of function pointers. Unfortunately, there's no way to do a smooth transition. ALL native targets in the tree must be converted at the same time. I've tested all I could with cross compilers and with help from GCC compile farm, but naturally I haven't been able to test many of the ports. Still, I made a best effort to port everything over, and while I expect some build problems due to typos and such, which should be trivial to fix, I don't expect any design problems. * Implementation notes: - The flattened current_target is gone. References to current_target or current_target.beneath are replaced with references to target_stack (the top of the stack) directly. - To keep "set debug target" working, this adds a new debug_stratum layer that sits on top of the stack, prints the debug, and delegates to the target beneath. In addition, this makes the shortname and longname properties of target_ops be virtual methods instead of data fields, and makes the debug target defer those to the target beneath. This is so that debug code sprinkled around that does "if (debugtarget) ..." can transparently print the name of the target beneath. A patch later in the series actually splits out the shortname/longname methods to a separate structure, but I preferred to keep that chance separate as it is associated with changing a bit the design of how targets are registered and open. - Since you can't check whether a C++ virtual method is overridden, the old method of checking whether a target_ops implements a method by comparing the function pointer must be replaced with something else. Some cases are fixed by adding a parallel "can_do_foo" target_ops methods. E.g.,: + for (t = target_stack; t != NULL; t = t->beneath) { - if (t->to_create_inferior != NULL) + if (t->can_create_inferior ()) break; } Others are fixed by changing void return type to bool or int return type, and have the default implementation return false or -1, to indicate lack of support. - make-target-delegates was adjusted to generate C++ classes and methods. It needed tweaks to grok "virtual" in front of the target method name, and for the fact that methods are no longer function pointers. (In particular, the current code parsing the return type was simple because it could simply parse up until the '(' in '(*to_foo)'. It now generates a couple C++ classes that inherit target_ops: dummy_target and debug_target. Since we need to generate the class declarations as well, i.e., we need to emit methods twice, we now generate the code in two passes. - The core_target global is renamed to avoid conflict with the "core_target" class. - ctf/tfile targets init_tracefile_ops is replaced by a base class that is inherited by both ctf and tfile. - bsd-uthread The bsd_uthread_ops_hack hack is gone. It's not needed because nothing was extending a target created by bsd_uthread_target. - remote/extended-remote targets This is a first pass, just enough to C++ify target_ops. A later pass will convert more free functions to methods, and make remote_state be truly per remote instance, allowing multiple simultaneous instances of remote targets. - inf-child/"native" is converted to an actual base class (inf_child_target), that is inherited by all native targets. - GNU/Linux The old weird double-target linux_ops mechanism in linux-nat.c, is gone, replaced by adding a few virtual methods to linux-nat.h's target_ops, called low_XXX, that the concrete linux-nat implementations override. Sort of like gdbserver's linux_target_ops, but simpler, for requiring only one target_ops-like hierarchy, which spares implementing the same method twice when we need to forward the method to a low implementation. The low target simply reimplements the target_ops method directly in that case. There are a few remaining linux-nat.c hooks that would be better converted to low_ methods like above too. E.g.: linux_nat_set_new_thread (t, x86_linux_new_thread); linux_nat_set_new_fork (t, x86_linux_new_fork); linux_nat_set_forget_process That'll be done in a follow up patch. - We can no longer use functions like x86_use_watchpoints to install custom methods on an arbitrary base target. The patch replaces instances of such a pattern with template mixins. For example memory_breakpoint_target defined in target.h, or x86_nat_target in x86-nat.h. - linux_trad_target, MIPS and Alpha GNU/Linux The code in the new linux-nat-trad.h/c files which was split off of inf-ptrace.h/c recently, is converted to a C++ base class, and used by the MIPS and Alpha GNU/Linux ports. - BSD targets The $architecture x NetBSD/OpenBSD/FreeBSD support matrix complicates things a bit. There's common BSD target code, and there's common architecture-specific code shared between the different BSDs. Currently, all that is stiched together to form a final target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target functions etc. This introduces new fbsd_nat_target, obsd_nat_target and nbsd_nat_target classes that serve as base/prototype target for the corresponding BSD variant. And introduces generic i386/AMD64 BSD targets, to be used as template mixin to build a final target. Similarly, a generic SPARC target is added, used by both BSD and Linux ports. - bsd_kvm_add_target, BSD libkvm target I considered making bsd_kvm_supply_pcb a virtual method, and then have each port inherit bsd_kvm_target and override that method, but that was resulting in lots of unjustified churn, so I left the function pointer mechanism alone. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> John Baldwin <jhb@freebsd.org> * target.h (enum strata) <debug_stratum>: New. (struct target_ops) <all delegation methods>: Replace by C++ virtual methods, and drop "to_" prefix. All references updated throughout. <to_shortname, to_longname, to_doc, to_data, to_have_steppable_watchpoint, to_have_continuable_watchpoint, to_has_thread_control, to_attach_no_wait>: Delete, replaced by virtual methods. All references updated throughout. <can_attach, supports_terminal_ours, can_create_inferior, get_thread_control_capabilities, attach_no_wait>: New virtual methods. <insert_breakpoint, remove_breakpoint>: Now TARGET_DEFAULT_NORETURN methods. <info_proc>: Now returns bool. <to_magic>: Delete. (OPS_MAGIC): Delete. (current_target): Delete. All references replaced by references to ... (target_stack): ... this. New. (target_shortname, target_longname): Adjust. (target_can_run): Now a function declaration. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (memory_breakpoint_target): New template class. (test_target_ops): Refactor as a C++ class with virtual methods. * make-target-delegates (NAME_PART): Tighten. (POINTER_PART, CP_SYMBOL): New. (SIMPLE_RETURN_PART): Reimplement. (VEC_RETURN_PART): Expect less. (RETURN_PART, VIRTUAL_PART): New. (METHOD): Adjust to C++ virtual methods. (scan_target_h): Remove reference to C99. (dname): Output "target_ops::" prefix. (write_function_header): Adjust to output a C++ class method. (write_declaration): New. (write_delegator): Adjust to output a C++ class method. (tdname): Output "dummy_target::" prefix. (write_tdefault, write_debugmethod): Adjust to output a C++ class method. (tdefault_names, debug_names): Delete. (return_types, tdefaults, styles, argtypes_array): New. (top level): All methods are delegators. (print_class): New. (top level): Print dummy_target and debug_target classes. * target-delegates.c: Regenerate. * target-debug.h (target_debug_print_enum_info_proc_what) (target_debug_print_thread_control_capabilities) (target_debug_print_thread_info_p): New. * target.c (dummy_target): Delete. (the_dummy_target, the_debug_target): New. (target_stack): Now extern. (set_targetdebug): Push/unpush debug target. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (add_target_with_completer): No longer call complete_target_initialization. (target_supports_terminal_ours): Use regular delegation. (update_current_target): Delete. (push_target): No longer check magic number. Don't call update_current_target. (unpush_target): Don't call update_current_target. (target_is_pushed): No longer check magic number. (target_require_runnable): Skip for all stratums over process_stratum. (target_ops::info_proc): New. (target_info_proc): Use find_target_at and find_default_run_target. (target_supports_disable_randomization): Use regular delegation. (target_get_osdata): Use find_target_at. (target_ops::open, target_ops::close, target_ops::can_attach) (target_ops::attach, target_ops::can_create_inferior) (target_ops::create_inferior, target_ops::can_run) (target_can_run): New. (default_fileio_target): Use regular delegation. (target_ops::fileio_open, target_ops::fileio_pwrite) (target_ops::fileio_pread, target_ops::fileio_fstat) (target_ops::fileio_close, target_ops::fileio_unlink) (target_ops::fileio_readlink): New. (target_fileio_open_1, target_fileio_unlink) (target_fileio_readlink): Always call the target method. Handle FILEIO_ENOSYS. (return_zero, return_zero_has_execution): Delete. (init_dummy_target): Delete. (dummy_target::dummy_target, dummy_target::shortname) (dummy_target::longname, dummy_target::doc) (debug_target::debug_target, debug_target::shortname) (debug_target::longname, debug_target::doc): New. (target_supports_delete_record): Use regular delegation. (setup_target_debug): Delete. (maintenance_print_target_stack): Skip debug_stratum. (initialize_targets): Instantiate the_dummy_target and the_debug_target. * auxv.c (target_auxv_parse): Remove 'ops' parameter. Adjust to use target_stack. (target_auxv_search, fprint_target_auxv): Adjust. (info_auxv_command): Adjust to use target_stack. * auxv.h (target_auxv_parse): Remove 'ops' parameter. * exceptions.c (print_flush): Handle a NULL target_stack. * regcache.c (target_ops_no_register): Refactor as class with virtual methods. * exec.c (exec_target): New class. (exec_ops): Now an exec_target. (exec_open, exec_close_1, exec_get_section_table) (exec_xfer_partial, exec_files_info, exec_has_memory) (exec_make_note_section): Refactor as exec_target methods. (exec_file_clear, ignore, exec_remove_breakpoint, init_exec_ops): Delete. (exec_target::find_memory_regions): New. (_initialize_exec): Don't call init_exec_ops. * gdbcore.h (exec_file_clear): Delete. * corefile.c (core_target): Delete. (core_file_command): Adjust. * corelow.c (core_target): New class. (the_core_target): New. (core_close): Remove target_ops parameter. (core_close_cleanup): Adjust. (core_target::close): New. (core_open, core_detach, get_core_registers, core_files_info) (core_xfer_partial, core_thread_alive, core_read_description) (core_pid_to_str, core_thread_name, core_has_memory) (core_has_stack, core_has_registers, core_info_proc): Rework as core_target methods. (ignore, core_remove_breakpoint, init_core_ops): Delete. (_initialize_corelow): Initialize the_core_target. * gdbcore.h (core_target): Delete. (the_core_target): New. * ctf.c: (ctf_target): New class. (ctf_ops): Now a ctf_target. (ctf_open, ctf_close, ctf_files_info, ctf_fetch_registers) (ctf_xfer_partial, ctf_get_trace_state_variable_value) (ctf_trace_find, ctf_traceframe_info): Refactor as ctf_target methods. (init_ctf_ops): Delete. (_initialize_ctf): Don't call it. * tracefile-tfile.c (tfile_target): New class. (tfile_ops): Now a tfile_target. (tfile_open, tfile_close, tfile_files_info) (tfile_get_tracepoint_status, tfile_trace_find) (tfile_fetch_registers, tfile_xfer_partial) (tfile_get_trace_state_variable_value, tfile_traceframe_info): Refactor as tfile_target methods. (tfile_xfer_partial_features): Remove target_ops parameter. (init_tfile_ops): Delete. (_initialize_tracefile_tfile): Don't call it. * tracefile.c (tracefile_has_all_memory, tracefile_has_memory) (tracefile_has_stack, tracefile_has_registers) (tracefile_thread_alive, tracefile_get_trace_status): Refactor as tracefile_target methods. (init_tracefile_ops): Delete. (tracefile_target::tracefile_target): New. * tracefile.h: Include "target.h". (tracefile_target): New class. (init_tracefile_ops): Delete. * spu-multiarch.c (spu_multiarch_target): New class. (spu_ops): Now a spu_multiarch_target. (spu_thread_architecture, spu_region_ok_for_hw_watchpoint) (spu_fetch_registers, spu_store_registers, spu_xfer_partial) (spu_search_memory, spu_mourn_inferior): Refactor as spu_multiarch_target methods. (init_spu_ops): Delete. (_initialize_spu_multiarch): Remove references to init_spu_ops, complete_target_initialization. * ravenscar-thread.c (ravenscar_thread_target): New class. (ravenscar_ops): Now a ravenscar_thread_target. (ravenscar_resume, ravenscar_wait, ravenscar_update_thread_list) (ravenscar_thread_alive, ravenscar_pid_to_str) (ravenscar_fetch_registers, ravenscar_store_registers) (ravenscar_prepare_to_store, ravenscar_stopped_by_sw_breakpoint) (ravenscar_stopped_by_hw_breakpoint) (ravenscar_stopped_by_watchpoint, ravenscar_stopped_data_address) (ravenscar_mourn_inferior, ravenscar_core_of_thread) (ravenscar_get_ada_task_ptid): Refactor as ravenscar_thread_target methods. (init_ravenscar_thread_ops): Delete. (_initialize_ravenscar): Remove references to init_ravenscar_thread_ops and complete_target_initialization. * bsd-uthread.c (bsd_uthread_ops_hack): Delete. (bsd_uthread_target): New class. (bsd_uthread_ops): Now a bsd_uthread_target. (bsd_uthread_activate): Adjust to refer to bsd_uthread_ops. (bsd_uthread_close, bsd_uthread_mourn_inferior) (bsd_uthread_fetch_registers, bsd_uthread_store_registers) (bsd_uthread_wait, bsd_uthread_resume, bsd_uthread_thread_alive) (bsd_uthread_update_thread_list, bsd_uthread_extra_thread_info) (bsd_uthread_pid_to_str): Refactor as bsd_uthread_target methods. (bsd_uthread_target): Delete function. (_initialize_bsd_uthread): Remove reference to complete_target_initialization. * bfd-target.c (target_bfd_data): Delete. Fields folded into ... (target_bfd): ... this new class. (target_bfd_xfer_partial, target_bfd_get_section_table) (target_bfd_close): Refactor as target_bfd methods. (target_bfd::~target_bfd): New. (target_bfd_reopen): Adjust. (target_bfd::close): New. * record-btrace.c (record_btrace_target): New class. (record_btrace_ops): Now a record_btrace_target. (record_btrace_open, record_btrace_stop_recording) (record_btrace_disconnect, record_btrace_close) (record_btrace_async, record_btrace_info) (record_btrace_insn_history, record_btrace_insn_history_range) (record_btrace_insn_history_from, record_btrace_call_history) (record_btrace_call_history_range) (record_btrace_call_history_from, record_btrace_record_method) (record_btrace_is_replaying, record_btrace_will_replay) (record_btrace_xfer_partial, record_btrace_insert_breakpoint) (record_btrace_remove_breakpoint, record_btrace_fetch_registers) (record_btrace_store_registers, record_btrace_prepare_to_store) (record_btrace_to_get_unwinder) (record_btrace_to_get_tailcall_unwinder, record_btrace_resume) (record_btrace_commit_resume, record_btrace_wait) (record_btrace_stop, record_btrace_can_execute_reverse) (record_btrace_stopped_by_sw_breakpoint) (record_btrace_supports_stopped_by_sw_breakpoint) (record_btrace_stopped_by_hw_breakpoint) (record_btrace_supports_stopped_by_hw_breakpoint) (record_btrace_update_thread_list, record_btrace_thread_alive) (record_btrace_goto_begin, record_btrace_goto_end) (record_btrace_goto, record_btrace_stop_replaying_all) (record_btrace_execution_direction) (record_btrace_prepare_to_generate_core) (record_btrace_done_generating_core): Refactor as record_btrace_target methods. (init_record_btrace_ops): Delete. (_initialize_record_btrace): Remove reference to init_record_btrace_ops. * record-full.c (RECORD_FULL_IS_REPLAY): Adjust to always refer to the execution_direction global. (record_full_base_target, record_full_target) (record_full_core_target): New classes. (record_full_ops): Now a record_full_target. (record_full_core_ops): Now a record_full_core_target. (record_full_target::detach, record_full_target::disconnect) (record_full_core_target::disconnect) (record_full_target::mourn_inferior, record_full_target::kill): New. (record_full_open, record_full_close, record_full_async): Refactor as methods of the record_full_base_target class. (record_full_resume, record_full_commit_resume): Refactor as methods of the record_full_target class. (record_full_wait, record_full_stopped_by_watchpoint) (record_full_stopped_data_address) (record_full_stopped_by_sw_breakpoint) (record_full_supports_stopped_by_sw_breakpoint) (record_full_stopped_by_hw_breakpoint) (record_full_supports_stopped_by_hw_breakpoint): Refactor as methods of the record_full_base_target class. (record_full_store_registers, record_full_xfer_partial) (record_full_insert_breakpoint, record_full_remove_breakpoint): Refactor as methods of the record_full_target class. (record_full_can_execute_reverse, record_full_get_bookmark) (record_full_goto_bookmark, record_full_execution_direction) (record_full_record_method, record_full_info, record_full_delete) (record_full_is_replaying, record_full_will_replay) (record_full_goto_begin, record_full_goto_end, record_full_goto) (record_full_stop_replaying): Refactor as methods of the record_full_base_target class. (record_full_core_resume, record_full_core_kill) (record_full_core_fetch_registers) (record_full_core_prepare_to_store) (record_full_core_store_registers, record_full_core_xfer_partial) (record_full_core_insert_breakpoint) (record_full_core_remove_breakpoint) (record_full_core_has_execution): Refactor as methods of the record_full_core_target class. (record_full_base_target::supports_delete_record): New. (init_record_full_ops): Delete. (init_record_full_core_ops): Delete. (record_full_save): Refactor as method of the record_full_base_target class. (_initialize_record_full): Remove references to init_record_full_ops and init_record_full_core_ops. * remote.c (remote_target, extended_remote_target): New classes. (remote_ops): Now a remote_target. (extended_remote_ops): Now an extended_remote_target. (remote_insert_fork_catchpoint, remote_remove_fork_catchpoint) (remote_insert_vfork_catchpoint, remote_remove_vfork_catchpoint) (remote_insert_exec_catchpoint, remote_remove_exec_catchpoint) (remote_pass_signals, remote_set_syscall_catchpoint) (remote_program_signals, ) (remote_thread_always_alive): Remove target_ops parameter. (remote_thread_alive, remote_thread_name) (remote_update_thread_list, remote_threads_extra_info) (remote_static_tracepoint_marker_at) (remote_static_tracepoint_markers_by_strid) (remote_get_ada_task_ptid, remote_close, remote_start_remote) (remote_open): Refactor as methods of remote_target. (extended_remote_open, extended_remote_detach) (extended_remote_attach, extended_remote_post_attach): (extended_remote_supports_disable_randomization) (extended_remote_create_inferior): : Refactor as method of extended_remote_target. (remote_set_permissions, remote_open_1, remote_detach) (remote_follow_fork, remote_follow_exec, remote_disconnect) (remote_resume, remote_commit_resume, remote_stop) (remote_interrupt, remote_pass_ctrlc, remote_terminal_inferior) (remote_terminal_ours, remote_wait, remote_fetch_registers) (remote_prepare_to_store, remote_store_registers) (remote_flash_erase, remote_flash_done, remote_files_info) (remote_kill, remote_mourn, remote_insert_breakpoint) (remote_remove_breakpoint, remote_insert_watchpoint) (remote_watchpoint_addr_within_range) (remote_remove_watchpoint, remote_region_ok_for_hw_watchpoint) (remote_check_watch_resources, remote_stopped_by_sw_breakpoint) (remote_supports_stopped_by_sw_breakpoint) (remote_stopped_by_hw_breakpoint) (remote_supports_stopped_by_hw_breakpoint) (remote_stopped_by_watchpoint, remote_stopped_data_address) (remote_insert_hw_breakpoint, remote_remove_hw_breakpoint) (remote_verify_memory): Refactor as methods of remote_target. (remote_write_qxfer, remote_read_qxfer): Remove target_ops parameter. (remote_xfer_partial, remote_get_memory_xfer_limit) (remote_search_memory, remote_rcmd, remote_memory_map) (remote_pid_to_str, remote_get_thread_local_address) (remote_get_tib_address, remote_read_description): Refactor as methods of remote_target. (remote_target::fileio_open, remote_target::fileio_pwrite) (remote_target::fileio_pread, remote_target::fileio_close): New. (remote_hostio_readlink, remote_hostio_fstat) (remote_filesystem_is_local, remote_can_execute_reverse) (remote_supports_non_stop, remote_supports_disable_randomization) (remote_supports_multi_process, remote_supports_cond_breakpoints) (remote_supports_enable_disable_tracepoint) (remote_supports_string_tracing) (remote_can_run_breakpoint_commands, remote_trace_init) (remote_download_tracepoint, remote_can_download_tracepoint) (remote_download_trace_state_variable, remote_enable_tracepoint) (remote_disable_tracepoint, remote_trace_set_readonly_regions) (remote_trace_start, remote_get_trace_status) (remote_get_tracepoint_status, remote_trace_stop) (remote_trace_find, remote_get_trace_state_variable_value) (remote_save_trace_data, remote_get_raw_trace_data) (remote_set_disconnected_tracing, remote_core_of_thread) (remote_set_circular_trace_buffer, remote_traceframe_info) (remote_get_min_fast_tracepoint_insn_len) (remote_set_trace_buffer_size, remote_set_trace_notes) (remote_use_agent, remote_can_use_agent, remote_enable_btrace) (remote_disable_btrace, remote_teardown_btrace) (remote_read_btrace, remote_btrace_conf) (remote_augmented_libraries_svr4_read, remote_load) (remote_pid_to_exec_file, remote_can_do_single_step) (remote_execution_direction, remote_thread_handle_to_thread_info): Refactor as methods of remote_target. (init_remote_ops, init_extended_remote_ops): Delete. (remote_can_async_p, remote_is_async_p, remote_async) (remote_thread_events, remote_upload_tracepoints) (remote_upload_trace_state_variables): Refactor as methods of remote_target. (_initialize_remote): Remove references to init_remote_ops and init_extended_remote_ops. * remote-sim.c (gdbsim_target): New class. (gdbsim_fetch_register, gdbsim_store_register, gdbsim_kill) (gdbsim_load, gdbsim_create_inferior, gdbsim_open, gdbsim_close) (gdbsim_detach, gdbsim_resume, gdbsim_interrupt) (gdbsim_wait, gdbsim_prepare_to_store, gdbsim_xfer_partial) (gdbsim_files_info, gdbsim_mourn_inferior, gdbsim_thread_alive) (gdbsim_pid_to_str, gdbsim_has_all_memory, gdbsim_has_memory): Refactor as methods of gdbsim_target. (gdbsim_ops): Now a gdbsim_target. (init_gdbsim_ops): Delete. (gdbsim_cntrl_c): Adjust. (_initialize_remote_sim): Remove reference to init_gdbsim_ops. * amd64-linux-nat.c (amd64_linux_nat_target): New class. (the_amd64_linux_nat_target): New. (amd64_linux_fetch_inferior_registers) (amd64_linux_store_inferior_registers): Refactor as methods of amd64_linux_nat_target. (_initialize_amd64_linux_nat): Adjust. Set linux_target. * i386-linux-nat.c: Don't include "linux-nat.h". (i386_linux_nat_target): New class. (the_i386_linux_nat_target): New. (i386_linux_fetch_inferior_registers) (i386_linux_store_inferior_registers, i386_linux_resume): Refactor as methods of i386_linux_nat_target. (_initialize_i386_linux_nat): Adjust. Set linux_target. * inf-child.c (inf_child_ops): Delete. (inf_child_fetch_inferior_registers) (inf_child_store_inferior_registers): Delete. (inf_child_post_attach, inf_child_prepare_to_store): Refactor as methods of inf_child_target. (inf_child_target::supports_terminal_ours) (inf_child_target::terminal_init) (inf_child_target::terminal_inferior) (inf_child_target::terminal_ours_for_output) (inf_child_target::terminal_ours, inf_child_target::interrupt) (inf_child_target::pass_ctrlc, inf_child_target::terminal_info): New. (inf_child_open, inf_child_disconnect, inf_child_close) (inf_child_mourn_inferior, inf_child_maybe_unpush_target) (inf_child_post_startup_inferior, inf_child_can_run) (inf_child_pid_to_exec_file): Refactor as methods of inf_child_target. (inf_child_follow_fork): Delete. (inf_child_target::can_create_inferior) (inf_child_target::can_attach): New. (inf_child_target::has_all_memory, inf_child_target::has_memory) (inf_child_target::has_stack, inf_child_target::has_registers) (inf_child_target::has_execution): New. (inf_child_fileio_open, inf_child_fileio_pwrite) (inf_child_fileio_pread, inf_child_fileio_fstat) (inf_child_fileio_close, inf_child_fileio_unlink) (inf_child_fileio_readlink, inf_child_use_agent) (inf_child_can_use_agent): Refactor as methods of inf_child_target. (return_zero, inf_child_target): Delete. (inf_child_target::inf_child_target): New. * inf-child.h: Include "target.h". (inf_child_target): Delete function prototype. (inf_child_target): New class. (inf_child_open_target, inf_child_mourn_inferior) (inf_child_maybe_unpush_target): Delete. * inf-ptrace.c (inf_ptrace_target::~inf_ptrace_target): New. (inf_ptrace_follow_fork, inf_ptrace_insert_fork_catchpoint) (inf_ptrace_remove_fork_catchpoint, inf_ptrace_create_inferior) (inf_ptrace_post_startup_inferior, inf_ptrace_mourn_inferior) (inf_ptrace_attach, inf_ptrace_post_attach, inf_ptrace_detach) (inf_ptrace_detach_success, inf_ptrace_kill, inf_ptrace_resume) (inf_ptrace_wait, inf_ptrace_xfer_partial) (inf_ptrace_thread_alive, inf_ptrace_files_info) (inf_ptrace_pid_to_str, inf_ptrace_auxv_parse): Refactor as methods of inf_ptrace_target. (inf_ptrace_target): Delete function. * inf-ptrace.h: Include "inf-child.h". (inf_ptrace_target): Delete function declaration. (inf_ptrace_target): New class. (inf_ptrace_trad_target, inf_ptrace_detach_success): Delete. * linux-nat.c (linux_target): New. (linux_ops, linux_ops_saved, super_xfer_partial): Delete. (linux_nat_target::~linux_nat_target): New. (linux_child_post_attach, linux_child_post_startup_inferior) (linux_child_follow_fork, linux_child_insert_fork_catchpoint) (linux_child_remove_fork_catchpoint) (linux_child_insert_vfork_catchpoint) (linux_child_remove_vfork_catchpoint) (linux_child_insert_exec_catchpoint) (linux_child_remove_exec_catchpoint) (linux_child_set_syscall_catchpoint, linux_nat_pass_signals) (linux_nat_create_inferior, linux_nat_attach, linux_nat_detach) (linux_nat_resume, linux_nat_stopped_by_watchpoint) (linux_nat_stopped_data_address) (linux_nat_stopped_by_sw_breakpoint) (linux_nat_supports_stopped_by_sw_breakpoint) (linux_nat_stopped_by_hw_breakpoint) (linux_nat_supports_stopped_by_hw_breakpoint, linux_nat_wait) (linux_nat_kill, linux_nat_mourn_inferior) (linux_nat_xfer_partial, linux_nat_thread_alive) (linux_nat_update_thread_list, linux_nat_pid_to_str) (linux_nat_thread_name, linux_child_pid_to_exec_file) (linux_child_static_tracepoint_markers_by_strid) (linux_nat_is_async_p, linux_nat_can_async_p) (linux_nat_supports_non_stop, linux_nat_always_non_stop_p) (linux_nat_supports_multi_process) (linux_nat_supports_disable_randomization, linux_nat_async) (linux_nat_stop, linux_nat_close, linux_nat_thread_address_space) (linux_nat_core_of_thread, linux_nat_filesystem_is_local) (linux_nat_fileio_open, linux_nat_fileio_readlink) (linux_nat_fileio_unlink, linux_nat_thread_events): Refactor as methods of linux_nat_target. (linux_nat_wait_1, linux_xfer_siginfo, linux_proc_xfer_partial) (linux_proc_xfer_spu, linux_nat_xfer_osdata): Remove target_ops parameter. (check_stopped_by_watchpoint): Adjust. (linux_xfer_partial): Delete. (linux_target_install_ops, linux_target, linux_nat_add_target): Delete. (linux_nat_target::linux_nat_target): New. * linux-nat.h: Include "inf-ptrace.h". (linux_nat_target): New. (linux_target, linux_target_install_ops, linux_nat_add_target): Delete function declarations. (linux_target): Declare global. * linux-thread-db.c (thread_db_target): New. (thread_db_target::thread_db_target): New. (thread_db_ops): Delete. (the_thread_db_target): New. (thread_db_detach, thread_db_wait, thread_db_mourn_inferior) (thread_db_update_thread_list, thread_db_pid_to_str) (thread_db_extra_thread_info) (thread_db_thread_handle_to_thread_info) (thread_db_get_thread_local_address, thread_db_get_ada_task_ptid) (thread_db_resume): Refactor as methods of thread_db_target. (init_thread_db_ops): Delete. (_initialize_thread_db): Remove reference to init_thread_db_ops. * x86-linux-nat.c: Don't include "linux-nat.h". (super_post_startup_inferior): Delete. (x86_linux_nat_target::~x86_linux_nat_target): New. (x86_linux_child_post_startup_inferior) (x86_linux_read_description, x86_linux_enable_btrace) (x86_linux_disable_btrace, x86_linux_teardown_btrace) (x86_linux_read_btrace, x86_linux_btrace_conf): Refactor as methods of x86_linux_nat_target. (x86_linux_create_target): Delete. Bits folded ... (x86_linux_add_target): ... here. Now takes a linux_nat_target pointer. * x86-linux-nat.h: Include "linux-nat.h" and "x86-nat.h". (x86_linux_nat_target): New class. (x86_linux_create_target): Delete. (x86_linux_add_target): Now takes a linux_nat_target pointer. * x86-nat.c (x86_insert_watchpoint, x86_remove_watchpoint) (x86_region_ok_for_watchpoint, x86_stopped_data_address) (x86_stopped_by_watchpoint, x86_insert_hw_breakpoint) (x86_remove_hw_breakpoint, x86_can_use_hw_breakpoint) (x86_stopped_by_hw_breakpoint): Remove target_ops parameter and make extern. (x86_use_watchpoints): Delete. * x86-nat.h: Include "breakpoint.h" and "target.h". (x86_use_watchpoints): Delete. (x86_can_use_hw_breakpoint, x86_region_ok_for_hw_watchpoint) (x86_stopped_by_watchpoint, x86_stopped_data_address) (x86_insert_watchpoint, x86_remove_watchpoint) (x86_insert_hw_breakpoint, x86_remove_hw_breakpoint) (x86_stopped_by_hw_breakpoint): New declarations. (x86_nat_target): New template class. * ppc-linux-nat.c (ppc_linux_nat_target): New class. (the_ppc_linux_nat_target): New. (ppc_linux_fetch_inferior_registers) (ppc_linux_can_use_hw_breakpoint) (ppc_linux_region_ok_for_hw_watchpoint) (ppc_linux_ranged_break_num_registers) (ppc_linux_insert_hw_breakpoint, ppc_linux_remove_hw_breakpoint) (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_can_accel_watchpoint_condition) (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint) (ppc_linux_stopped_data_address, ppc_linux_stopped_by_watchpoint) (ppc_linux_watchpoint_addr_within_range) (ppc_linux_masked_watch_num_registers) (ppc_linux_store_inferior_registers, ppc_linux_auxv_parse) (ppc_linux_read_description): Refactor as methods of ppc_linux_nat_target. (_initialize_ppc_linux_nat): Adjust. Set linux_target. * procfs.c (procfs_xfer_partial): Delete forward declaration. (procfs_target): New class. (the_procfs_target): New. (procfs_target): Delete function. (procfs_auxv_parse, procfs_attach, procfs_detach) (procfs_fetch_registers, procfs_store_registers, procfs_wait) (procfs_xfer_partial, procfs_resume, procfs_pass_signals) (procfs_files_info, procfs_kill_inferior, procfs_mourn_inferior) (procfs_create_inferior, procfs_update_thread_list) (procfs_thread_alive, procfs_pid_to_str) (procfs_can_use_hw_breakpoint, procfs_stopped_by_watchpoint) (procfs_stopped_data_address, procfs_insert_watchpoint) (procfs_remove_watchpoint, procfs_region_ok_for_hw_watchpoint) (proc_find_memory_regions, procfs_info_proc) (procfs_make_note_section): Refactor as methods of procfs_target. (_initialize_procfs): Adjust. * sol-thread.c (sol_thread_target): New class. (sol_thread_ops): Now a sol_thread_target. (sol_thread_detach, sol_thread_resume, sol_thread_wait) (sol_thread_fetch_registers, sol_thread_store_registers) (sol_thread_xfer_partial, sol_thread_mourn_inferior) (sol_thread_alive, solaris_pid_to_str, sol_update_thread_list) (sol_get_ada_task_ptid): Refactor as methods of sol_thread_target. (init_sol_thread_ops): Delete. (_initialize_sol_thread): Adjust. Remove references to init_sol_thread_ops and complete_target_initialization. * windows-nat.c (windows_nat_target): New class. (windows_fetch_inferior_registers) (windows_store_inferior_registers, windows_resume, windows_wait) (windows_attach, windows_detach, windows_pid_to_exec_file) (windows_files_info, windows_create_inferior) (windows_mourn_inferior, windows_interrupt, windows_kill_inferior) (windows_close, windows_pid_to_str, windows_xfer_partial) (windows_get_tib_address, windows_get_ada_task_ptid) (windows_thread_name, windows_thread_alive): Refactor as windows_nat_target methods. (do_initial_windows_stuff): Adjust. (windows_target): Delete function. (_initialize_windows_nat): Adjust. * darwin-nat.c (darwin_resume, darwin_wait_to, darwin_interrupt) (darwin_mourn_inferior, darwin_kill_inferior) (darwin_create_inferior, darwin_attach, darwin_detach) (darwin_pid_to_str, darwin_thread_alive, darwin_xfer_partial) (darwin_pid_to_exec_file, darwin_get_ada_task_ptid) (darwin_supports_multi_process): Refactor as darwin_nat_target methods. (darwin_resume_to, darwin_files_info): Delete. (_initialize_darwin_inferior): Rename to ... (_initialize_darwin_nat): ... this. Adjust to C++ification. * darwin-nat.h: Include "inf-child.h". (darwin_nat_target): New class. (darwin_complete_target): Delete. * i386-darwin-nat.c (i386_darwin_nat_target): New class. (darwin_target): New. (i386_darwin_fetch_inferior_registers) (i386_darwin_store_inferior_registers): Refactor as methods of darwin_nat_target. (darwin_complete_target): Delete, with ... (_initialize_i386_darwin_nat): ... bits factored out here. * alpha-linux-nat.c (alpha_linux_nat_target): New class. (the_alpha_linux_nat_target): New. (alpha_linux_register_u_offset): Refactor as alpha_linux_nat_target method. (_initialize_alpha_linux_nat): Adjust. * linux-nat-trad.c (inf_ptrace_register_u_offset): Delete. (inf_ptrace_fetch_register, inf_ptrace_fetch_registers) (inf_ptrace_store_register, inf_ptrace_store_registers): Refact as methods of linux_nat_trad_target. (linux_trad_target): Delete. * linux-nat-trad.h (linux_trad_target): Delete function. (linux_nat_trad_target): New class. * mips-linux-nat.c (mips_linux_nat_target): New class. (super_fetch_registers, super_store_registers, super_close): Delete. (the_mips_linux_nat_target): New. (mips64_linux_regsets_fetch_registers) (mips64_linux_regsets_store_registers) (mips64_linux_fetch_registers, mips64_linux_store_registers) (mips_linux_register_u_offset, mips_linux_read_description) (mips_linux_can_use_hw_breakpoint) (mips_linux_stopped_by_watchpoint) (mips_linux_stopped_data_address) (mips_linux_region_ok_for_hw_watchpoint) (mips_linux_insert_watchpoint, mips_linux_remove_watchpoint) (mips_linux_close): Refactor as methods of mips_linux_nat. (_initialize_mips_linux_nat): Adjust to C++ification. * aix-thread.c (aix_thread_target): New class. (aix_thread_ops): Now an aix_thread_target. (aix_thread_detach, aix_thread_resume, aix_thread_wait) (aix_thread_fetch_registers, aix_thread_store_registers) (aix_thread_xfer_partial, aix_thread_mourn_inferior) (aix_thread_thread_alive, aix_thread_pid_to_str) (aix_thread_extra_thread_info, aix_thread_get_ada_task_ptid): Refactor as methods of aix_thread_target. (init_aix_thread_ops): Delete. (_initialize_aix_thread): Remove references to init_aix_thread_ops and complete_target_initialization. * rs6000-nat.c (rs6000_xfer_shared_libraries): Delete. (rs6000_nat_target): New class. (the_rs6000_nat_target): New. (rs6000_fetch_inferior_registers, rs6000_store_inferior_registers) (rs6000_xfer_partial, rs6000_wait, rs6000_create_inferior) (rs6000_xfer_shared_libraries): Refactor as rs6000_nat_target methods. (super_create_inferior): Delete. (_initialize_rs6000_nat): Adjust to C++ification. * arm-linux-nat.c (arm_linux_nat_target): New class. (the_arm_linux_nat_target): New. (arm_linux_fetch_inferior_registers) (arm_linux_store_inferior_registers, arm_linux_read_description) (arm_linux_can_use_hw_breakpoint, arm_linux_insert_hw_breakpoint) (arm_linux_remove_hw_breakpoint) (arm_linux_region_ok_for_hw_watchpoint) (arm_linux_insert_watchpoint, arm_linux_remove_watchpoint) (arm_linux_stopped_data_address, arm_linux_stopped_by_watchpoint) (arm_linux_watchpoint_addr_within_range): Refactor as methods of arm_linux_nat_target. (_initialize_arm_linux_nat): Adjust to C++ification. * aarch64-linux-nat.c (aarch64_linux_nat_target): New class. (the_aarch64_linux_nat_target): New. (aarch64_linux_fetch_inferior_registers) (aarch64_linux_store_inferior_registers) (aarch64_linux_child_post_startup_inferior) (aarch64_linux_read_description) (aarch64_linux_can_use_hw_breakpoint) (aarch64_linux_insert_hw_breakpoint) (aarch64_linux_remove_hw_breakpoint) (aarch64_linux_insert_watchpoint, aarch64_linux_remove_watchpoint) (aarch64_linux_region_ok_for_hw_watchpoint) (aarch64_linux_stopped_data_address) (aarch64_linux_stopped_by_watchpoint) (aarch64_linux_watchpoint_addr_within_range) (aarch64_linux_can_do_single_step): Refactor as methods of aarch64_linux_nat_target. (super_post_startup_inferior): Delete. (_initialize_aarch64_linux_nat): Adjust to C++ification. * hppa-linux-nat.c (hppa_linux_nat_target): New class. (the_hppa_linux_nat_target): New. (hppa_linux_fetch_inferior_registers) (hppa_linux_store_inferior_registers): Refactor as methods of hppa_linux_nat_target. (_initialize_hppa_linux_nat): Adjust to C++ification. * ia64-linux-nat.c (ia64_linux_nat_target): New class. (the_ia64_linux_nat_target): New. (ia64_linux_insert_watchpoint, ia64_linux_remove_watchpoint) (ia64_linux_stopped_data_address) (ia64_linux_stopped_by_watchpoint, ia64_linux_fetch_registers) (ia64_linux_store_registers, ia64_linux_xfer_partial): Refactor as ia64_linux_nat_target methods. (super_xfer_partial): Delete. (_initialize_ia64_linux_nat): Adjust to C++ification. * m32r-linux-nat.c (m32r_linux_nat_target): New class. (the_m32r_linux_nat_target): New. (m32r_linux_fetch_inferior_registers) (m32r_linux_store_inferior_registers): Refactor as m32r_linux_nat_target methods. (_initialize_m32r_linux_nat): Adjust to C++ification. * m68k-linux-nat.c (m68k_linux_nat_target): New class. (the_m68k_linux_nat_target): New. (m68k_linux_fetch_inferior_registers) (m68k_linux_store_inferior_registers): Refactor as m68k_linux_nat_target methods. (_initialize_m68k_linux_nat): Adjust to C++ification. * s390-linux-nat.c (s390_linux_nat_target): New class. (the_s390_linux_nat_target): New. (s390_linux_fetch_inferior_registers) (s390_linux_store_inferior_registers, s390_stopped_by_watchpoint) (s390_insert_watchpoint, s390_remove_watchpoint) (s390_can_use_hw_breakpoint, s390_insert_hw_breakpoint) (s390_remove_hw_breakpoint, s390_region_ok_for_hw_watchpoint) (s390_auxv_parse, s390_read_description): Refactor as methods of s390_linux_nat_target. (_initialize_s390_nat): Adjust to C++ification. * sparc-linux-nat.c (sparc_linux_nat_target): New class. (the_sparc_linux_nat_target): New. (_initialize_sparc_linux_nat): Adjust to C++ification. * sparc-nat.c (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc64-linux-nat.c (sparc64_linux_nat_target): New class. (the_sparc64_linux_nat_target): New. (_initialize_sparc64_linux_nat): Adjust to C++ification. * spu-linux-nat.c (spu_linux_nat_target): New class. (the_spu_linux_nat_target): New. (spu_child_post_startup_inferior, spu_child_post_attach) (spu_child_wait, spu_fetch_inferior_registers) (spu_store_inferior_registers, spu_xfer_partial) (spu_can_use_hw_breakpoint): Refactor as spu_linux_nat_target methods. (_initialize_spu_nat): Adjust to C++ification. * tilegx-linux-nat.c (tilegx_linux_nat_target): New class. (the_tilegx_linux_nat_target): New. (fetch_inferior_registers, store_inferior_registers): Refactor as methods. (_initialize_tile_linux_nat): Adjust to C++ification. * xtensa-linux-nat.c (xtensa_linux_nat_target): New class. (the_xtensa_linux_nat_target): New. (xtensa_linux_fetch_inferior_registers) (xtensa_linux_store_inferior_registers): Refactor as xtensa_linux_nat_target methods. (_initialize_xtensa_linux_nat): Adjust to C++ification. * fbsd-nat.c (USE_SIGTRAP_SIGINFO): Delete. (fbsd_pid_to_exec_file, fbsd_find_memory_regions) (fbsd_find_memory_regions, fbsd_info_proc, fbsd_xfer_partial) (fbsd_thread_alive, fbsd_pid_to_str, fbsd_thread_name) (fbsd_update_thread_list, fbsd_resume, fbsd_wait) (fbsd_stopped_by_sw_breakpoint) (fbsd_supports_stopped_by_sw_breakpoint, fbsd_follow_fork) (fbsd_insert_fork_catchpoint, fbsd_remove_fork_catchpoint) (fbsd_insert_vfork_catchpoint, fbsd_remove_vfork_catchpoint) (fbsd_post_startup_inferior, fbsd_post_attach) (fbsd_insert_exec_catchpoint, fbsd_remove_exec_catchpoint) (fbsd_set_syscall_catchpoint) (super_xfer_partial, super_resume, super_wait) (fbsd_supports_stopped_by_hw_breakpoint): Delete. (fbsd_handle_debug_trap): Remove target_ops parameter. (fbsd_nat_add_target): Delete. * fbsd-nat.h: Include "inf-ptrace.h". (fbsd_nat_add_target): Delete. (USE_SIGTRAP_SIGINFO): Define. (fbsd_nat_target): New class. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers) (amd64bsd_store_inferior_registers): Remove target_ops parameter. (amd64bsd_target): Delete. * amd64-bsd-nat.h: New file. * amd64-fbsd-nat.c: Include "amd64-bsd-nat.h" instead of "x86-bsd-nat.h". (amd64_fbsd_nat_target): New class. (the_amd64_fbsd_nat_target): New. (amd64fbsd_read_description): Refactor as method of amd64_fbsd_nat_target. (amd64_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_amd64fbsd_nat): Adjust to C++ification. * amd64-nat.h (amd64bsd_target): Delete function declaration. * i386-bsd-nat.c (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Remove target_ops parameter. (i386bsd_target): Delete. * i386-bsd-nat.h (i386bsd_target): Delete function declaration. (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Declare. (i386_bsd_nat_target): New class. * i386-fbsd-nat.c (i386_fbsd_nat_target): New class. (the_i386_fbsd_nat_target): New. (i386fbsd_resume, i386fbsd_read_description): Refactor as i386_fbsd_nat_target methods. (i386_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_i386fbsd_nat): Adjust to C++ification. * x86-bsd-nat.c (super_mourn_inferior): Delete. (x86bsd_mourn_inferior, x86bsd_target): Delete. (_initialize_x86_bsd_nat): Adjust to C++ification. * x86-bsd-nat.h: Include "x86-nat.h". (x86bsd_target): Delete declaration. (x86bsd_nat_target): New class. * aarch64-fbsd-nat.c (aarch64_fbsd_nat_target): New class. (the_aarch64_fbsd_nat_target): New. (aarch64_fbsd_fetch_inferior_registers) (aarch64_fbsd_store_inferior_registers): Refactor as methods of aarch64_fbsd_nat_target. (_initialize_aarch64_fbsd_nat): Adjust to C++ification. * alpha-bsd-nat.c (alpha_bsd_nat_target): New class. (the_alpha_bsd_nat_target): New. (alphabsd_fetch_inferior_registers) (alphabsd_store_inferior_registers): Refactor as alpha_bsd_nat_target methods. (_initialize_alphabsd_nat): Refactor as methods of alpha_bsd_nat_target. * amd64-nbsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_nbsd_nat_target): New. (_initialize_amd64nbsd_nat): Adjust to C++ification. * amd64-obsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_obsd_nat_target): New. (_initialize_amd64obsd_nat): Adjust to C++ification. * arm-fbsd-nat.c (arm_fbsd_nat_target): New. (the_arm_fbsd_nat_target): New. (arm_fbsd_fetch_inferior_registers) (arm_fbsd_store_inferior_registers, arm_fbsd_read_description): (_initialize_arm_fbsd_nat): Refactor as methods of arm_fbsd_nat_target. (_initialize_arm_fbsd_nat): Adjust to C++ification. * arm-nbsd-nat.c (arm_netbsd_nat_target): New class. (the_arm_netbsd_nat_target): New. (armnbsd_fetch_registers, armnbsd_store_registers): Refactor as arm_netbsd_nat_target. (_initialize_arm_netbsd_nat): Adjust to C++ification. * hppa-nbsd-nat.c (hppa_nbsd_nat_target): New class. (the_hppa_nbsd_nat_target): New. (hppanbsd_fetch_registers, hppanbsd_store_registers): Refactor as hppa_nbsd_nat_target methods. (_initialize_hppanbsd_nat): Adjust to C++ification. * hppa-obsd-nat.c (hppa_obsd_nat_target): New class. (the_hppa_obsd_nat_target): New. (hppaobsd_fetch_registers, hppaobsd_store_registers): Refactor as methods of hppa_obsd_nat_target. (_initialize_hppaobsd_nat): Adjust to C++ification. Use add_target. * i386-nbsd-nat.c (the_i386_nbsd_nat_target): New. (_initialize_i386nbsd_nat): Adjust to C++ification. Use add_target. * i386-obsd-nat.c (the_i386_obsd_nat_target): New. (_initialize_i386obsd_nat): Use add_target. * m68k-bsd-nat.c (m68k_bsd_nat_target): New class. (the_m68k_bsd_nat_target): New. (m68kbsd_fetch_inferior_registers) (m68kbsd_store_inferior_registers): Refactor as methods of m68k_bsd_nat_target. (_initialize_m68kbsd_nat): Adjust to C++ification. * mips-fbsd-nat.c (mips_fbsd_nat_target): New class. (the_mips_fbsd_nat_target): New. (mips_fbsd_fetch_inferior_registers) (mips_fbsd_store_inferior_registers): Refactor as methods of mips_fbsd_nat_target. (_initialize_mips_fbsd_nat): Adjust to C++ification. Use add_target. * mips-nbsd-nat.c (mips_nbsd_nat_target): New class. (the_mips_nbsd_nat_target): New. (mipsnbsd_fetch_inferior_registers) (mipsnbsd_store_inferior_registers): Refactor as methods of mips_nbsd_nat_target. (_initialize_mipsnbsd_nat): Adjust to C++ification. * mips64-obsd-nat.c (mips64_obsd_nat_target): New class. (the_mips64_obsd_nat_target): New. (mips64obsd_fetch_inferior_registers) (mips64obsd_store_inferior_registers): Refactor as methods of mips64_obsd_nat_target. (_initialize_mips64obsd_nat): Adjust to C++ification. Use add_target. * nbsd-nat.c (nbsd_pid_to_exec_file): Refactor as method of nbsd_nat_target. * nbsd-nat.h: Include "inf-ptrace.h". (nbsd_nat_target): New class. * obsd-nat.c (obsd_pid_to_str, obsd_update_thread_list) (obsd_wait): Refactor as methods of obsd_nat_target. (obsd_add_target): Delete. * obsd-nat.h: Include "inf-ptrace.h". (obsd_nat_target): New class. * ppc-fbsd-nat.c (ppc_fbsd_nat_target): New class. (the_ppc_fbsd_nat_target): New. (ppcfbsd_fetch_inferior_registers) (ppcfbsd_store_inferior_registers): Refactor as methods of ppc_fbsd_nat_target. (_initialize_ppcfbsd_nat): Adjust to C++ification. Use add_target. * ppc-nbsd-nat.c (ppc_nbsd_nat_target): New class. (the_ppc_nbsd_nat_target): New. (ppcnbsd_fetch_inferior_registers) (ppcnbsd_store_inferior_registers): Refactor as methods of ppc_nbsd_nat_target. (_initialize_ppcnbsd_nat): Adjust to C++ification. * ppc-obsd-nat.c (ppc_obsd_nat_target): New class. (the_ppc_obsd_nat_target): New. (ppcobsd_fetch_registers, ppcobsd_store_registers): Refactor as methods of ppc_obsd_nat_target. (_initialize_ppcobsd_nat): Adjust to C++ification. Use add_target. * sh-nbsd-nat.c (sh_nbsd_nat_target): New class. (the_sh_nbsd_nat_target): New. (shnbsd_fetch_inferior_registers) (shnbsd_store_inferior_registers): Refactor as methods of sh_nbsd_nat_target. (_initialize_shnbsd_nat): Adjust to C++ification. * sparc-nat.c (sparc_xfer_wcookie): Make extern. (inf_ptrace_xfer_partial): Delete. (sparc_xfer_partial, sparc_target): Delete. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers, sparc_xfer_wcookie): Declare. (sparc_target): Delete function declaration. (sparc_target): New template class. * sparc-nbsd-nat.c (the_sparc_nbsd_nat_target): New. (_initialize_sparcnbsd_nat): Adjust to C++ification. * sparc64-fbsd-nat.c (the_sparc64_fbsd_nat_target): New. (_initialize_sparc64fbsd_nat): Adjust to C++ification. Use add_target. * sparc64-nbsd-nat.c (the_sparc64_nbsd_nat_target): New. (_initialize_sparc64nbsd_nat): Adjust to C++ification. * sparc64-obsd-nat.c (the_sparc64_obsd_nat_target): New. (_initialize_sparc64obsd_nat): Adjust to C++ification. Use add_target. * vax-bsd-nat.c (vax_bsd_nat_target): New class. (the_vax_bsd_nat_target): New. (vaxbsd_fetch_inferior_registers) (vaxbsd_store_inferior_registers): Refactor as vax_bsd_nat_target methods. (_initialize_vaxbsd_nat): Adjust to C++ification. * bsd-kvm.c (bsd_kvm_target): New class. (bsd_kvm_ops): Now a bsd_kvm_target. (bsd_kvm_open, bsd_kvm_close, bsd_kvm_xfer_partial) (bsd_kvm_files_info, bsd_kvm_fetch_registers) (bsd_kvm_thread_alive, bsd_kvm_pid_to_str): Refactor as methods of bsd_kvm_target. (bsd_kvm_return_one): Delete. (bsd_kvm_add_target): Adjust to C++ification. * nto-procfs.c (nto_procfs_target, nto_procfs_target_native) (nto_procfs_target_procfs): New classes. (procfs_open_1, procfs_thread_alive, procfs_update_thread_list) (procfs_files_info, procfs_pid_to_exec_file, procfs_attach) (procfs_post_attach, procfs_wait, procfs_fetch_registers) (procfs_xfer_partial, procfs_detach, procfs_insert_breakpoint) (procfs_remove_breakpoint, procfs_insert_hw_breakpoint) (procfs_remove_hw_breakpoint, procfs_resume) (procfs_mourn_inferior, procfs_create_inferior, procfs_interrupt) (procfs_kill_inferior, procfs_store_registers) (procfs_pass_signals, procfs_pid_to_str, procfs_can_run): Refactor as methods of nto_procfs_target. (nto_procfs_ops): Now an nto_procfs_target_procfs. (nto_native_ops): Delete. (procfs_open, procfs_native_open): Delete. (nto_native_ops): Now an nto_procfs_target_native. (init_procfs_targets): Adjust to C++ification. (procfs_can_use_hw_breakpoint, procfs_remove_hw_watchpoint) (procfs_insert_hw_watchpoint, procfs_stopped_by_watchpoint): Refactor as methods of nto_procfs_target. * go32-nat.c (go32_nat_target): New class. (the_go32_nat_target): New. (go32_attach, go32_resume, go32_wait, go32_fetch_registers) (go32_store_registers, go32_xfer_partial, go32_files_info) (go32_kill_inferior, go32_create_inferior, go32_mourn_inferior) (go32_terminal_init, go32_terminal_info, go32_terminal_inferior) (go32_terminal_ours, go32_pass_ctrlc, go32_thread_alive) (go32_pid_to_str): Refactor as methods of go32_nat_target. (go32_target): Delete. (_initialize_go32_nat): Adjust to C++ification. * gnu-nat.c (gnu_wait, gnu_resume, gnu_kill_inferior) (gnu_mourn_inferior, gnu_create_inferior, gnu_attach, gnu_detach) (gnu_stop, gnu_thread_alive, gnu_xfer_partial) (gnu_find_memory_regions, gnu_pid_to_str): Refactor as methods of gnu_nat_target. (gnu_target): Delete. * gnu-nat.h (gnu_target): Delete. (gnu_nat_target): New class. * i386-gnu-nat.c (gnu_base_target): New. (i386_gnu_nat_target): New class. (the_i386_gnu_nat_target): New. (_initialize_i386gnu_nat): Adjust to C++ification. gdb/testsuite/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * gdb.base/breakpoint-in-ro-region.exp: Adjust to to_resume and to_log_command renames. * gdb.base/sss-bp-on-user-bp-2.exp: Likewise.
2018-05-03 07:37:22 +08:00
int
ppc_linux_nat_target::insert_watchpoint (CORE_ADDR addr, int len,
enum target_hw_bp_type type,
struct expression *cond)
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
{
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
m_dreg_interface.detect (inferior_ptid);
if (m_dreg_interface.unavailable_p ())
return -1;
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
if (m_dreg_interface.hwdebug_p ())
{
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
struct ppc_hw_breakpoint p;
create_watchpoint_request (&p, addr, len, type, cond, 1);
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
register_hw_breakpoint (inferior_ptid.pid (), p);
}
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
else
{
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
gdb_assert (m_dreg_interface.debugreg_p ());
long wp_value;
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
long read_mode, write_mode;
if (linux_get_hwcap (current_top_target ()) & PPC_FEATURE_BOOKE)
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
{
/* PowerPC 440 requires only the read/write flags to be passed
to the kernel. */
read_mode = 1;
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
write_mode = 2;
}
else
{
/* PowerPC 970 and other DABR-based processors are required to pass
the Breakpoint Translation bit together with the flags. */
read_mode = 5;
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
write_mode = 6;
}
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
wp_value = addr & ~(read_mode | write_mode);
switch (type)
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
{
case hw_read:
/* Set read and translate bits. */
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
wp_value |= read_mode;
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
break;
case hw_write:
/* Set write and translate bits. */
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
wp_value |= write_mode;
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
break;
case hw_access:
/* Set read, write and translate bits. */
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
wp_value |= read_mode | write_mode;
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
break;
}
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
register_wp (inferior_ptid.pid (), wp_value);
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
}
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
return 0;
}
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
/* Clear a registration for a hardware watchpoint. It will be removed
from the threads of the group of inferior_ptid when they are next
resumed. */
Convert struct target_ops to C++ I.e., use C++ virtual methods and inheritance instead of tables of function pointers. Unfortunately, there's no way to do a smooth transition. ALL native targets in the tree must be converted at the same time. I've tested all I could with cross compilers and with help from GCC compile farm, but naturally I haven't been able to test many of the ports. Still, I made a best effort to port everything over, and while I expect some build problems due to typos and such, which should be trivial to fix, I don't expect any design problems. * Implementation notes: - The flattened current_target is gone. References to current_target or current_target.beneath are replaced with references to target_stack (the top of the stack) directly. - To keep "set debug target" working, this adds a new debug_stratum layer that sits on top of the stack, prints the debug, and delegates to the target beneath. In addition, this makes the shortname and longname properties of target_ops be virtual methods instead of data fields, and makes the debug target defer those to the target beneath. This is so that debug code sprinkled around that does "if (debugtarget) ..." can transparently print the name of the target beneath. A patch later in the series actually splits out the shortname/longname methods to a separate structure, but I preferred to keep that chance separate as it is associated with changing a bit the design of how targets are registered and open. - Since you can't check whether a C++ virtual method is overridden, the old method of checking whether a target_ops implements a method by comparing the function pointer must be replaced with something else. Some cases are fixed by adding a parallel "can_do_foo" target_ops methods. E.g.,: + for (t = target_stack; t != NULL; t = t->beneath) { - if (t->to_create_inferior != NULL) + if (t->can_create_inferior ()) break; } Others are fixed by changing void return type to bool or int return type, and have the default implementation return false or -1, to indicate lack of support. - make-target-delegates was adjusted to generate C++ classes and methods. It needed tweaks to grok "virtual" in front of the target method name, and for the fact that methods are no longer function pointers. (In particular, the current code parsing the return type was simple because it could simply parse up until the '(' in '(*to_foo)'. It now generates a couple C++ classes that inherit target_ops: dummy_target and debug_target. Since we need to generate the class declarations as well, i.e., we need to emit methods twice, we now generate the code in two passes. - The core_target global is renamed to avoid conflict with the "core_target" class. - ctf/tfile targets init_tracefile_ops is replaced by a base class that is inherited by both ctf and tfile. - bsd-uthread The bsd_uthread_ops_hack hack is gone. It's not needed because nothing was extending a target created by bsd_uthread_target. - remote/extended-remote targets This is a first pass, just enough to C++ify target_ops. A later pass will convert more free functions to methods, and make remote_state be truly per remote instance, allowing multiple simultaneous instances of remote targets. - inf-child/"native" is converted to an actual base class (inf_child_target), that is inherited by all native targets. - GNU/Linux The old weird double-target linux_ops mechanism in linux-nat.c, is gone, replaced by adding a few virtual methods to linux-nat.h's target_ops, called low_XXX, that the concrete linux-nat implementations override. Sort of like gdbserver's linux_target_ops, but simpler, for requiring only one target_ops-like hierarchy, which spares implementing the same method twice when we need to forward the method to a low implementation. The low target simply reimplements the target_ops method directly in that case. There are a few remaining linux-nat.c hooks that would be better converted to low_ methods like above too. E.g.: linux_nat_set_new_thread (t, x86_linux_new_thread); linux_nat_set_new_fork (t, x86_linux_new_fork); linux_nat_set_forget_process That'll be done in a follow up patch. - We can no longer use functions like x86_use_watchpoints to install custom methods on an arbitrary base target. The patch replaces instances of such a pattern with template mixins. For example memory_breakpoint_target defined in target.h, or x86_nat_target in x86-nat.h. - linux_trad_target, MIPS and Alpha GNU/Linux The code in the new linux-nat-trad.h/c files which was split off of inf-ptrace.h/c recently, is converted to a C++ base class, and used by the MIPS and Alpha GNU/Linux ports. - BSD targets The $architecture x NetBSD/OpenBSD/FreeBSD support matrix complicates things a bit. There's common BSD target code, and there's common architecture-specific code shared between the different BSDs. Currently, all that is stiched together to form a final target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target functions etc. This introduces new fbsd_nat_target, obsd_nat_target and nbsd_nat_target classes that serve as base/prototype target for the corresponding BSD variant. And introduces generic i386/AMD64 BSD targets, to be used as template mixin to build a final target. Similarly, a generic SPARC target is added, used by both BSD and Linux ports. - bsd_kvm_add_target, BSD libkvm target I considered making bsd_kvm_supply_pcb a virtual method, and then have each port inherit bsd_kvm_target and override that method, but that was resulting in lots of unjustified churn, so I left the function pointer mechanism alone. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> John Baldwin <jhb@freebsd.org> * target.h (enum strata) <debug_stratum>: New. (struct target_ops) <all delegation methods>: Replace by C++ virtual methods, and drop "to_" prefix. All references updated throughout. <to_shortname, to_longname, to_doc, to_data, to_have_steppable_watchpoint, to_have_continuable_watchpoint, to_has_thread_control, to_attach_no_wait>: Delete, replaced by virtual methods. All references updated throughout. <can_attach, supports_terminal_ours, can_create_inferior, get_thread_control_capabilities, attach_no_wait>: New virtual methods. <insert_breakpoint, remove_breakpoint>: Now TARGET_DEFAULT_NORETURN methods. <info_proc>: Now returns bool. <to_magic>: Delete. (OPS_MAGIC): Delete. (current_target): Delete. All references replaced by references to ... (target_stack): ... this. New. (target_shortname, target_longname): Adjust. (target_can_run): Now a function declaration. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (memory_breakpoint_target): New template class. (test_target_ops): Refactor as a C++ class with virtual methods. * make-target-delegates (NAME_PART): Tighten. (POINTER_PART, CP_SYMBOL): New. (SIMPLE_RETURN_PART): Reimplement. (VEC_RETURN_PART): Expect less. (RETURN_PART, VIRTUAL_PART): New. (METHOD): Adjust to C++ virtual methods. (scan_target_h): Remove reference to C99. (dname): Output "target_ops::" prefix. (write_function_header): Adjust to output a C++ class method. (write_declaration): New. (write_delegator): Adjust to output a C++ class method. (tdname): Output "dummy_target::" prefix. (write_tdefault, write_debugmethod): Adjust to output a C++ class method. (tdefault_names, debug_names): Delete. (return_types, tdefaults, styles, argtypes_array): New. (top level): All methods are delegators. (print_class): New. (top level): Print dummy_target and debug_target classes. * target-delegates.c: Regenerate. * target-debug.h (target_debug_print_enum_info_proc_what) (target_debug_print_thread_control_capabilities) (target_debug_print_thread_info_p): New. * target.c (dummy_target): Delete. (the_dummy_target, the_debug_target): New. (target_stack): Now extern. (set_targetdebug): Push/unpush debug target. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (add_target_with_completer): No longer call complete_target_initialization. (target_supports_terminal_ours): Use regular delegation. (update_current_target): Delete. (push_target): No longer check magic number. Don't call update_current_target. (unpush_target): Don't call update_current_target. (target_is_pushed): No longer check magic number. (target_require_runnable): Skip for all stratums over process_stratum. (target_ops::info_proc): New. (target_info_proc): Use find_target_at and find_default_run_target. (target_supports_disable_randomization): Use regular delegation. (target_get_osdata): Use find_target_at. (target_ops::open, target_ops::close, target_ops::can_attach) (target_ops::attach, target_ops::can_create_inferior) (target_ops::create_inferior, target_ops::can_run) (target_can_run): New. (default_fileio_target): Use regular delegation. (target_ops::fileio_open, target_ops::fileio_pwrite) (target_ops::fileio_pread, target_ops::fileio_fstat) (target_ops::fileio_close, target_ops::fileio_unlink) (target_ops::fileio_readlink): New. (target_fileio_open_1, target_fileio_unlink) (target_fileio_readlink): Always call the target method. Handle FILEIO_ENOSYS. (return_zero, return_zero_has_execution): Delete. (init_dummy_target): Delete. (dummy_target::dummy_target, dummy_target::shortname) (dummy_target::longname, dummy_target::doc) (debug_target::debug_target, debug_target::shortname) (debug_target::longname, debug_target::doc): New. (target_supports_delete_record): Use regular delegation. (setup_target_debug): Delete. (maintenance_print_target_stack): Skip debug_stratum. (initialize_targets): Instantiate the_dummy_target and the_debug_target. * auxv.c (target_auxv_parse): Remove 'ops' parameter. Adjust to use target_stack. (target_auxv_search, fprint_target_auxv): Adjust. (info_auxv_command): Adjust to use target_stack. * auxv.h (target_auxv_parse): Remove 'ops' parameter. * exceptions.c (print_flush): Handle a NULL target_stack. * regcache.c (target_ops_no_register): Refactor as class with virtual methods. * exec.c (exec_target): New class. (exec_ops): Now an exec_target. (exec_open, exec_close_1, exec_get_section_table) (exec_xfer_partial, exec_files_info, exec_has_memory) (exec_make_note_section): Refactor as exec_target methods. (exec_file_clear, ignore, exec_remove_breakpoint, init_exec_ops): Delete. (exec_target::find_memory_regions): New. (_initialize_exec): Don't call init_exec_ops. * gdbcore.h (exec_file_clear): Delete. * corefile.c (core_target): Delete. (core_file_command): Adjust. * corelow.c (core_target): New class. (the_core_target): New. (core_close): Remove target_ops parameter. (core_close_cleanup): Adjust. (core_target::close): New. (core_open, core_detach, get_core_registers, core_files_info) (core_xfer_partial, core_thread_alive, core_read_description) (core_pid_to_str, core_thread_name, core_has_memory) (core_has_stack, core_has_registers, core_info_proc): Rework as core_target methods. (ignore, core_remove_breakpoint, init_core_ops): Delete. (_initialize_corelow): Initialize the_core_target. * gdbcore.h (core_target): Delete. (the_core_target): New. * ctf.c: (ctf_target): New class. (ctf_ops): Now a ctf_target. (ctf_open, ctf_close, ctf_files_info, ctf_fetch_registers) (ctf_xfer_partial, ctf_get_trace_state_variable_value) (ctf_trace_find, ctf_traceframe_info): Refactor as ctf_target methods. (init_ctf_ops): Delete. (_initialize_ctf): Don't call it. * tracefile-tfile.c (tfile_target): New class. (tfile_ops): Now a tfile_target. (tfile_open, tfile_close, tfile_files_info) (tfile_get_tracepoint_status, tfile_trace_find) (tfile_fetch_registers, tfile_xfer_partial) (tfile_get_trace_state_variable_value, tfile_traceframe_info): Refactor as tfile_target methods. (tfile_xfer_partial_features): Remove target_ops parameter. (init_tfile_ops): Delete. (_initialize_tracefile_tfile): Don't call it. * tracefile.c (tracefile_has_all_memory, tracefile_has_memory) (tracefile_has_stack, tracefile_has_registers) (tracefile_thread_alive, tracefile_get_trace_status): Refactor as tracefile_target methods. (init_tracefile_ops): Delete. (tracefile_target::tracefile_target): New. * tracefile.h: Include "target.h". (tracefile_target): New class. (init_tracefile_ops): Delete. * spu-multiarch.c (spu_multiarch_target): New class. (spu_ops): Now a spu_multiarch_target. (spu_thread_architecture, spu_region_ok_for_hw_watchpoint) (spu_fetch_registers, spu_store_registers, spu_xfer_partial) (spu_search_memory, spu_mourn_inferior): Refactor as spu_multiarch_target methods. (init_spu_ops): Delete. (_initialize_spu_multiarch): Remove references to init_spu_ops, complete_target_initialization. * ravenscar-thread.c (ravenscar_thread_target): New class. (ravenscar_ops): Now a ravenscar_thread_target. (ravenscar_resume, ravenscar_wait, ravenscar_update_thread_list) (ravenscar_thread_alive, ravenscar_pid_to_str) (ravenscar_fetch_registers, ravenscar_store_registers) (ravenscar_prepare_to_store, ravenscar_stopped_by_sw_breakpoint) (ravenscar_stopped_by_hw_breakpoint) (ravenscar_stopped_by_watchpoint, ravenscar_stopped_data_address) (ravenscar_mourn_inferior, ravenscar_core_of_thread) (ravenscar_get_ada_task_ptid): Refactor as ravenscar_thread_target methods. (init_ravenscar_thread_ops): Delete. (_initialize_ravenscar): Remove references to init_ravenscar_thread_ops and complete_target_initialization. * bsd-uthread.c (bsd_uthread_ops_hack): Delete. (bsd_uthread_target): New class. (bsd_uthread_ops): Now a bsd_uthread_target. (bsd_uthread_activate): Adjust to refer to bsd_uthread_ops. (bsd_uthread_close, bsd_uthread_mourn_inferior) (bsd_uthread_fetch_registers, bsd_uthread_store_registers) (bsd_uthread_wait, bsd_uthread_resume, bsd_uthread_thread_alive) (bsd_uthread_update_thread_list, bsd_uthread_extra_thread_info) (bsd_uthread_pid_to_str): Refactor as bsd_uthread_target methods. (bsd_uthread_target): Delete function. (_initialize_bsd_uthread): Remove reference to complete_target_initialization. * bfd-target.c (target_bfd_data): Delete. Fields folded into ... (target_bfd): ... this new class. (target_bfd_xfer_partial, target_bfd_get_section_table) (target_bfd_close): Refactor as target_bfd methods. (target_bfd::~target_bfd): New. (target_bfd_reopen): Adjust. (target_bfd::close): New. * record-btrace.c (record_btrace_target): New class. (record_btrace_ops): Now a record_btrace_target. (record_btrace_open, record_btrace_stop_recording) (record_btrace_disconnect, record_btrace_close) (record_btrace_async, record_btrace_info) (record_btrace_insn_history, record_btrace_insn_history_range) (record_btrace_insn_history_from, record_btrace_call_history) (record_btrace_call_history_range) (record_btrace_call_history_from, record_btrace_record_method) (record_btrace_is_replaying, record_btrace_will_replay) (record_btrace_xfer_partial, record_btrace_insert_breakpoint) (record_btrace_remove_breakpoint, record_btrace_fetch_registers) (record_btrace_store_registers, record_btrace_prepare_to_store) (record_btrace_to_get_unwinder) (record_btrace_to_get_tailcall_unwinder, record_btrace_resume) (record_btrace_commit_resume, record_btrace_wait) (record_btrace_stop, record_btrace_can_execute_reverse) (record_btrace_stopped_by_sw_breakpoint) (record_btrace_supports_stopped_by_sw_breakpoint) (record_btrace_stopped_by_hw_breakpoint) (record_btrace_supports_stopped_by_hw_breakpoint) (record_btrace_update_thread_list, record_btrace_thread_alive) (record_btrace_goto_begin, record_btrace_goto_end) (record_btrace_goto, record_btrace_stop_replaying_all) (record_btrace_execution_direction) (record_btrace_prepare_to_generate_core) (record_btrace_done_generating_core): Refactor as record_btrace_target methods. (init_record_btrace_ops): Delete. (_initialize_record_btrace): Remove reference to init_record_btrace_ops. * record-full.c (RECORD_FULL_IS_REPLAY): Adjust to always refer to the execution_direction global. (record_full_base_target, record_full_target) (record_full_core_target): New classes. (record_full_ops): Now a record_full_target. (record_full_core_ops): Now a record_full_core_target. (record_full_target::detach, record_full_target::disconnect) (record_full_core_target::disconnect) (record_full_target::mourn_inferior, record_full_target::kill): New. (record_full_open, record_full_close, record_full_async): Refactor as methods of the record_full_base_target class. (record_full_resume, record_full_commit_resume): Refactor as methods of the record_full_target class. (record_full_wait, record_full_stopped_by_watchpoint) (record_full_stopped_data_address) (record_full_stopped_by_sw_breakpoint) (record_full_supports_stopped_by_sw_breakpoint) (record_full_stopped_by_hw_breakpoint) (record_full_supports_stopped_by_hw_breakpoint): Refactor as methods of the record_full_base_target class. (record_full_store_registers, record_full_xfer_partial) (record_full_insert_breakpoint, record_full_remove_breakpoint): Refactor as methods of the record_full_target class. (record_full_can_execute_reverse, record_full_get_bookmark) (record_full_goto_bookmark, record_full_execution_direction) (record_full_record_method, record_full_info, record_full_delete) (record_full_is_replaying, record_full_will_replay) (record_full_goto_begin, record_full_goto_end, record_full_goto) (record_full_stop_replaying): Refactor as methods of the record_full_base_target class. (record_full_core_resume, record_full_core_kill) (record_full_core_fetch_registers) (record_full_core_prepare_to_store) (record_full_core_store_registers, record_full_core_xfer_partial) (record_full_core_insert_breakpoint) (record_full_core_remove_breakpoint) (record_full_core_has_execution): Refactor as methods of the record_full_core_target class. (record_full_base_target::supports_delete_record): New. (init_record_full_ops): Delete. (init_record_full_core_ops): Delete. (record_full_save): Refactor as method of the record_full_base_target class. (_initialize_record_full): Remove references to init_record_full_ops and init_record_full_core_ops. * remote.c (remote_target, extended_remote_target): New classes. (remote_ops): Now a remote_target. (extended_remote_ops): Now an extended_remote_target. (remote_insert_fork_catchpoint, remote_remove_fork_catchpoint) (remote_insert_vfork_catchpoint, remote_remove_vfork_catchpoint) (remote_insert_exec_catchpoint, remote_remove_exec_catchpoint) (remote_pass_signals, remote_set_syscall_catchpoint) (remote_program_signals, ) (remote_thread_always_alive): Remove target_ops parameter. (remote_thread_alive, remote_thread_name) (remote_update_thread_list, remote_threads_extra_info) (remote_static_tracepoint_marker_at) (remote_static_tracepoint_markers_by_strid) (remote_get_ada_task_ptid, remote_close, remote_start_remote) (remote_open): Refactor as methods of remote_target. (extended_remote_open, extended_remote_detach) (extended_remote_attach, extended_remote_post_attach): (extended_remote_supports_disable_randomization) (extended_remote_create_inferior): : Refactor as method of extended_remote_target. (remote_set_permissions, remote_open_1, remote_detach) (remote_follow_fork, remote_follow_exec, remote_disconnect) (remote_resume, remote_commit_resume, remote_stop) (remote_interrupt, remote_pass_ctrlc, remote_terminal_inferior) (remote_terminal_ours, remote_wait, remote_fetch_registers) (remote_prepare_to_store, remote_store_registers) (remote_flash_erase, remote_flash_done, remote_files_info) (remote_kill, remote_mourn, remote_insert_breakpoint) (remote_remove_breakpoint, remote_insert_watchpoint) (remote_watchpoint_addr_within_range) (remote_remove_watchpoint, remote_region_ok_for_hw_watchpoint) (remote_check_watch_resources, remote_stopped_by_sw_breakpoint) (remote_supports_stopped_by_sw_breakpoint) (remote_stopped_by_hw_breakpoint) (remote_supports_stopped_by_hw_breakpoint) (remote_stopped_by_watchpoint, remote_stopped_data_address) (remote_insert_hw_breakpoint, remote_remove_hw_breakpoint) (remote_verify_memory): Refactor as methods of remote_target. (remote_write_qxfer, remote_read_qxfer): Remove target_ops parameter. (remote_xfer_partial, remote_get_memory_xfer_limit) (remote_search_memory, remote_rcmd, remote_memory_map) (remote_pid_to_str, remote_get_thread_local_address) (remote_get_tib_address, remote_read_description): Refactor as methods of remote_target. (remote_target::fileio_open, remote_target::fileio_pwrite) (remote_target::fileio_pread, remote_target::fileio_close): New. (remote_hostio_readlink, remote_hostio_fstat) (remote_filesystem_is_local, remote_can_execute_reverse) (remote_supports_non_stop, remote_supports_disable_randomization) (remote_supports_multi_process, remote_supports_cond_breakpoints) (remote_supports_enable_disable_tracepoint) (remote_supports_string_tracing) (remote_can_run_breakpoint_commands, remote_trace_init) (remote_download_tracepoint, remote_can_download_tracepoint) (remote_download_trace_state_variable, remote_enable_tracepoint) (remote_disable_tracepoint, remote_trace_set_readonly_regions) (remote_trace_start, remote_get_trace_status) (remote_get_tracepoint_status, remote_trace_stop) (remote_trace_find, remote_get_trace_state_variable_value) (remote_save_trace_data, remote_get_raw_trace_data) (remote_set_disconnected_tracing, remote_core_of_thread) (remote_set_circular_trace_buffer, remote_traceframe_info) (remote_get_min_fast_tracepoint_insn_len) (remote_set_trace_buffer_size, remote_set_trace_notes) (remote_use_agent, remote_can_use_agent, remote_enable_btrace) (remote_disable_btrace, remote_teardown_btrace) (remote_read_btrace, remote_btrace_conf) (remote_augmented_libraries_svr4_read, remote_load) (remote_pid_to_exec_file, remote_can_do_single_step) (remote_execution_direction, remote_thread_handle_to_thread_info): Refactor as methods of remote_target. (init_remote_ops, init_extended_remote_ops): Delete. (remote_can_async_p, remote_is_async_p, remote_async) (remote_thread_events, remote_upload_tracepoints) (remote_upload_trace_state_variables): Refactor as methods of remote_target. (_initialize_remote): Remove references to init_remote_ops and init_extended_remote_ops. * remote-sim.c (gdbsim_target): New class. (gdbsim_fetch_register, gdbsim_store_register, gdbsim_kill) (gdbsim_load, gdbsim_create_inferior, gdbsim_open, gdbsim_close) (gdbsim_detach, gdbsim_resume, gdbsim_interrupt) (gdbsim_wait, gdbsim_prepare_to_store, gdbsim_xfer_partial) (gdbsim_files_info, gdbsim_mourn_inferior, gdbsim_thread_alive) (gdbsim_pid_to_str, gdbsim_has_all_memory, gdbsim_has_memory): Refactor as methods of gdbsim_target. (gdbsim_ops): Now a gdbsim_target. (init_gdbsim_ops): Delete. (gdbsim_cntrl_c): Adjust. (_initialize_remote_sim): Remove reference to init_gdbsim_ops. * amd64-linux-nat.c (amd64_linux_nat_target): New class. (the_amd64_linux_nat_target): New. (amd64_linux_fetch_inferior_registers) (amd64_linux_store_inferior_registers): Refactor as methods of amd64_linux_nat_target. (_initialize_amd64_linux_nat): Adjust. Set linux_target. * i386-linux-nat.c: Don't include "linux-nat.h". (i386_linux_nat_target): New class. (the_i386_linux_nat_target): New. (i386_linux_fetch_inferior_registers) (i386_linux_store_inferior_registers, i386_linux_resume): Refactor as methods of i386_linux_nat_target. (_initialize_i386_linux_nat): Adjust. Set linux_target. * inf-child.c (inf_child_ops): Delete. (inf_child_fetch_inferior_registers) (inf_child_store_inferior_registers): Delete. (inf_child_post_attach, inf_child_prepare_to_store): Refactor as methods of inf_child_target. (inf_child_target::supports_terminal_ours) (inf_child_target::terminal_init) (inf_child_target::terminal_inferior) (inf_child_target::terminal_ours_for_output) (inf_child_target::terminal_ours, inf_child_target::interrupt) (inf_child_target::pass_ctrlc, inf_child_target::terminal_info): New. (inf_child_open, inf_child_disconnect, inf_child_close) (inf_child_mourn_inferior, inf_child_maybe_unpush_target) (inf_child_post_startup_inferior, inf_child_can_run) (inf_child_pid_to_exec_file): Refactor as methods of inf_child_target. (inf_child_follow_fork): Delete. (inf_child_target::can_create_inferior) (inf_child_target::can_attach): New. (inf_child_target::has_all_memory, inf_child_target::has_memory) (inf_child_target::has_stack, inf_child_target::has_registers) (inf_child_target::has_execution): New. (inf_child_fileio_open, inf_child_fileio_pwrite) (inf_child_fileio_pread, inf_child_fileio_fstat) (inf_child_fileio_close, inf_child_fileio_unlink) (inf_child_fileio_readlink, inf_child_use_agent) (inf_child_can_use_agent): Refactor as methods of inf_child_target. (return_zero, inf_child_target): Delete. (inf_child_target::inf_child_target): New. * inf-child.h: Include "target.h". (inf_child_target): Delete function prototype. (inf_child_target): New class. (inf_child_open_target, inf_child_mourn_inferior) (inf_child_maybe_unpush_target): Delete. * inf-ptrace.c (inf_ptrace_target::~inf_ptrace_target): New. (inf_ptrace_follow_fork, inf_ptrace_insert_fork_catchpoint) (inf_ptrace_remove_fork_catchpoint, inf_ptrace_create_inferior) (inf_ptrace_post_startup_inferior, inf_ptrace_mourn_inferior) (inf_ptrace_attach, inf_ptrace_post_attach, inf_ptrace_detach) (inf_ptrace_detach_success, inf_ptrace_kill, inf_ptrace_resume) (inf_ptrace_wait, inf_ptrace_xfer_partial) (inf_ptrace_thread_alive, inf_ptrace_files_info) (inf_ptrace_pid_to_str, inf_ptrace_auxv_parse): Refactor as methods of inf_ptrace_target. (inf_ptrace_target): Delete function. * inf-ptrace.h: Include "inf-child.h". (inf_ptrace_target): Delete function declaration. (inf_ptrace_target): New class. (inf_ptrace_trad_target, inf_ptrace_detach_success): Delete. * linux-nat.c (linux_target): New. (linux_ops, linux_ops_saved, super_xfer_partial): Delete. (linux_nat_target::~linux_nat_target): New. (linux_child_post_attach, linux_child_post_startup_inferior) (linux_child_follow_fork, linux_child_insert_fork_catchpoint) (linux_child_remove_fork_catchpoint) (linux_child_insert_vfork_catchpoint) (linux_child_remove_vfork_catchpoint) (linux_child_insert_exec_catchpoint) (linux_child_remove_exec_catchpoint) (linux_child_set_syscall_catchpoint, linux_nat_pass_signals) (linux_nat_create_inferior, linux_nat_attach, linux_nat_detach) (linux_nat_resume, linux_nat_stopped_by_watchpoint) (linux_nat_stopped_data_address) (linux_nat_stopped_by_sw_breakpoint) (linux_nat_supports_stopped_by_sw_breakpoint) (linux_nat_stopped_by_hw_breakpoint) (linux_nat_supports_stopped_by_hw_breakpoint, linux_nat_wait) (linux_nat_kill, linux_nat_mourn_inferior) (linux_nat_xfer_partial, linux_nat_thread_alive) (linux_nat_update_thread_list, linux_nat_pid_to_str) (linux_nat_thread_name, linux_child_pid_to_exec_file) (linux_child_static_tracepoint_markers_by_strid) (linux_nat_is_async_p, linux_nat_can_async_p) (linux_nat_supports_non_stop, linux_nat_always_non_stop_p) (linux_nat_supports_multi_process) (linux_nat_supports_disable_randomization, linux_nat_async) (linux_nat_stop, linux_nat_close, linux_nat_thread_address_space) (linux_nat_core_of_thread, linux_nat_filesystem_is_local) (linux_nat_fileio_open, linux_nat_fileio_readlink) (linux_nat_fileio_unlink, linux_nat_thread_events): Refactor as methods of linux_nat_target. (linux_nat_wait_1, linux_xfer_siginfo, linux_proc_xfer_partial) (linux_proc_xfer_spu, linux_nat_xfer_osdata): Remove target_ops parameter. (check_stopped_by_watchpoint): Adjust. (linux_xfer_partial): Delete. (linux_target_install_ops, linux_target, linux_nat_add_target): Delete. (linux_nat_target::linux_nat_target): New. * linux-nat.h: Include "inf-ptrace.h". (linux_nat_target): New. (linux_target, linux_target_install_ops, linux_nat_add_target): Delete function declarations. (linux_target): Declare global. * linux-thread-db.c (thread_db_target): New. (thread_db_target::thread_db_target): New. (thread_db_ops): Delete. (the_thread_db_target): New. (thread_db_detach, thread_db_wait, thread_db_mourn_inferior) (thread_db_update_thread_list, thread_db_pid_to_str) (thread_db_extra_thread_info) (thread_db_thread_handle_to_thread_info) (thread_db_get_thread_local_address, thread_db_get_ada_task_ptid) (thread_db_resume): Refactor as methods of thread_db_target. (init_thread_db_ops): Delete. (_initialize_thread_db): Remove reference to init_thread_db_ops. * x86-linux-nat.c: Don't include "linux-nat.h". (super_post_startup_inferior): Delete. (x86_linux_nat_target::~x86_linux_nat_target): New. (x86_linux_child_post_startup_inferior) (x86_linux_read_description, x86_linux_enable_btrace) (x86_linux_disable_btrace, x86_linux_teardown_btrace) (x86_linux_read_btrace, x86_linux_btrace_conf): Refactor as methods of x86_linux_nat_target. (x86_linux_create_target): Delete. Bits folded ... (x86_linux_add_target): ... here. Now takes a linux_nat_target pointer. * x86-linux-nat.h: Include "linux-nat.h" and "x86-nat.h". (x86_linux_nat_target): New class. (x86_linux_create_target): Delete. (x86_linux_add_target): Now takes a linux_nat_target pointer. * x86-nat.c (x86_insert_watchpoint, x86_remove_watchpoint) (x86_region_ok_for_watchpoint, x86_stopped_data_address) (x86_stopped_by_watchpoint, x86_insert_hw_breakpoint) (x86_remove_hw_breakpoint, x86_can_use_hw_breakpoint) (x86_stopped_by_hw_breakpoint): Remove target_ops parameter and make extern. (x86_use_watchpoints): Delete. * x86-nat.h: Include "breakpoint.h" and "target.h". (x86_use_watchpoints): Delete. (x86_can_use_hw_breakpoint, x86_region_ok_for_hw_watchpoint) (x86_stopped_by_watchpoint, x86_stopped_data_address) (x86_insert_watchpoint, x86_remove_watchpoint) (x86_insert_hw_breakpoint, x86_remove_hw_breakpoint) (x86_stopped_by_hw_breakpoint): New declarations. (x86_nat_target): New template class. * ppc-linux-nat.c (ppc_linux_nat_target): New class. (the_ppc_linux_nat_target): New. (ppc_linux_fetch_inferior_registers) (ppc_linux_can_use_hw_breakpoint) (ppc_linux_region_ok_for_hw_watchpoint) (ppc_linux_ranged_break_num_registers) (ppc_linux_insert_hw_breakpoint, ppc_linux_remove_hw_breakpoint) (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_can_accel_watchpoint_condition) (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint) (ppc_linux_stopped_data_address, ppc_linux_stopped_by_watchpoint) (ppc_linux_watchpoint_addr_within_range) (ppc_linux_masked_watch_num_registers) (ppc_linux_store_inferior_registers, ppc_linux_auxv_parse) (ppc_linux_read_description): Refactor as methods of ppc_linux_nat_target. (_initialize_ppc_linux_nat): Adjust. Set linux_target. * procfs.c (procfs_xfer_partial): Delete forward declaration. (procfs_target): New class. (the_procfs_target): New. (procfs_target): Delete function. (procfs_auxv_parse, procfs_attach, procfs_detach) (procfs_fetch_registers, procfs_store_registers, procfs_wait) (procfs_xfer_partial, procfs_resume, procfs_pass_signals) (procfs_files_info, procfs_kill_inferior, procfs_mourn_inferior) (procfs_create_inferior, procfs_update_thread_list) (procfs_thread_alive, procfs_pid_to_str) (procfs_can_use_hw_breakpoint, procfs_stopped_by_watchpoint) (procfs_stopped_data_address, procfs_insert_watchpoint) (procfs_remove_watchpoint, procfs_region_ok_for_hw_watchpoint) (proc_find_memory_regions, procfs_info_proc) (procfs_make_note_section): Refactor as methods of procfs_target. (_initialize_procfs): Adjust. * sol-thread.c (sol_thread_target): New class. (sol_thread_ops): Now a sol_thread_target. (sol_thread_detach, sol_thread_resume, sol_thread_wait) (sol_thread_fetch_registers, sol_thread_store_registers) (sol_thread_xfer_partial, sol_thread_mourn_inferior) (sol_thread_alive, solaris_pid_to_str, sol_update_thread_list) (sol_get_ada_task_ptid): Refactor as methods of sol_thread_target. (init_sol_thread_ops): Delete. (_initialize_sol_thread): Adjust. Remove references to init_sol_thread_ops and complete_target_initialization. * windows-nat.c (windows_nat_target): New class. (windows_fetch_inferior_registers) (windows_store_inferior_registers, windows_resume, windows_wait) (windows_attach, windows_detach, windows_pid_to_exec_file) (windows_files_info, windows_create_inferior) (windows_mourn_inferior, windows_interrupt, windows_kill_inferior) (windows_close, windows_pid_to_str, windows_xfer_partial) (windows_get_tib_address, windows_get_ada_task_ptid) (windows_thread_name, windows_thread_alive): Refactor as windows_nat_target methods. (do_initial_windows_stuff): Adjust. (windows_target): Delete function. (_initialize_windows_nat): Adjust. * darwin-nat.c (darwin_resume, darwin_wait_to, darwin_interrupt) (darwin_mourn_inferior, darwin_kill_inferior) (darwin_create_inferior, darwin_attach, darwin_detach) (darwin_pid_to_str, darwin_thread_alive, darwin_xfer_partial) (darwin_pid_to_exec_file, darwin_get_ada_task_ptid) (darwin_supports_multi_process): Refactor as darwin_nat_target methods. (darwin_resume_to, darwin_files_info): Delete. (_initialize_darwin_inferior): Rename to ... (_initialize_darwin_nat): ... this. Adjust to C++ification. * darwin-nat.h: Include "inf-child.h". (darwin_nat_target): New class. (darwin_complete_target): Delete. * i386-darwin-nat.c (i386_darwin_nat_target): New class. (darwin_target): New. (i386_darwin_fetch_inferior_registers) (i386_darwin_store_inferior_registers): Refactor as methods of darwin_nat_target. (darwin_complete_target): Delete, with ... (_initialize_i386_darwin_nat): ... bits factored out here. * alpha-linux-nat.c (alpha_linux_nat_target): New class. (the_alpha_linux_nat_target): New. (alpha_linux_register_u_offset): Refactor as alpha_linux_nat_target method. (_initialize_alpha_linux_nat): Adjust. * linux-nat-trad.c (inf_ptrace_register_u_offset): Delete. (inf_ptrace_fetch_register, inf_ptrace_fetch_registers) (inf_ptrace_store_register, inf_ptrace_store_registers): Refact as methods of linux_nat_trad_target. (linux_trad_target): Delete. * linux-nat-trad.h (linux_trad_target): Delete function. (linux_nat_trad_target): New class. * mips-linux-nat.c (mips_linux_nat_target): New class. (super_fetch_registers, super_store_registers, super_close): Delete. (the_mips_linux_nat_target): New. (mips64_linux_regsets_fetch_registers) (mips64_linux_regsets_store_registers) (mips64_linux_fetch_registers, mips64_linux_store_registers) (mips_linux_register_u_offset, mips_linux_read_description) (mips_linux_can_use_hw_breakpoint) (mips_linux_stopped_by_watchpoint) (mips_linux_stopped_data_address) (mips_linux_region_ok_for_hw_watchpoint) (mips_linux_insert_watchpoint, mips_linux_remove_watchpoint) (mips_linux_close): Refactor as methods of mips_linux_nat. (_initialize_mips_linux_nat): Adjust to C++ification. * aix-thread.c (aix_thread_target): New class. (aix_thread_ops): Now an aix_thread_target. (aix_thread_detach, aix_thread_resume, aix_thread_wait) (aix_thread_fetch_registers, aix_thread_store_registers) (aix_thread_xfer_partial, aix_thread_mourn_inferior) (aix_thread_thread_alive, aix_thread_pid_to_str) (aix_thread_extra_thread_info, aix_thread_get_ada_task_ptid): Refactor as methods of aix_thread_target. (init_aix_thread_ops): Delete. (_initialize_aix_thread): Remove references to init_aix_thread_ops and complete_target_initialization. * rs6000-nat.c (rs6000_xfer_shared_libraries): Delete. (rs6000_nat_target): New class. (the_rs6000_nat_target): New. (rs6000_fetch_inferior_registers, rs6000_store_inferior_registers) (rs6000_xfer_partial, rs6000_wait, rs6000_create_inferior) (rs6000_xfer_shared_libraries): Refactor as rs6000_nat_target methods. (super_create_inferior): Delete. (_initialize_rs6000_nat): Adjust to C++ification. * arm-linux-nat.c (arm_linux_nat_target): New class. (the_arm_linux_nat_target): New. (arm_linux_fetch_inferior_registers) (arm_linux_store_inferior_registers, arm_linux_read_description) (arm_linux_can_use_hw_breakpoint, arm_linux_insert_hw_breakpoint) (arm_linux_remove_hw_breakpoint) (arm_linux_region_ok_for_hw_watchpoint) (arm_linux_insert_watchpoint, arm_linux_remove_watchpoint) (arm_linux_stopped_data_address, arm_linux_stopped_by_watchpoint) (arm_linux_watchpoint_addr_within_range): Refactor as methods of arm_linux_nat_target. (_initialize_arm_linux_nat): Adjust to C++ification. * aarch64-linux-nat.c (aarch64_linux_nat_target): New class. (the_aarch64_linux_nat_target): New. (aarch64_linux_fetch_inferior_registers) (aarch64_linux_store_inferior_registers) (aarch64_linux_child_post_startup_inferior) (aarch64_linux_read_description) (aarch64_linux_can_use_hw_breakpoint) (aarch64_linux_insert_hw_breakpoint) (aarch64_linux_remove_hw_breakpoint) (aarch64_linux_insert_watchpoint, aarch64_linux_remove_watchpoint) (aarch64_linux_region_ok_for_hw_watchpoint) (aarch64_linux_stopped_data_address) (aarch64_linux_stopped_by_watchpoint) (aarch64_linux_watchpoint_addr_within_range) (aarch64_linux_can_do_single_step): Refactor as methods of aarch64_linux_nat_target. (super_post_startup_inferior): Delete. (_initialize_aarch64_linux_nat): Adjust to C++ification. * hppa-linux-nat.c (hppa_linux_nat_target): New class. (the_hppa_linux_nat_target): New. (hppa_linux_fetch_inferior_registers) (hppa_linux_store_inferior_registers): Refactor as methods of hppa_linux_nat_target. (_initialize_hppa_linux_nat): Adjust to C++ification. * ia64-linux-nat.c (ia64_linux_nat_target): New class. (the_ia64_linux_nat_target): New. (ia64_linux_insert_watchpoint, ia64_linux_remove_watchpoint) (ia64_linux_stopped_data_address) (ia64_linux_stopped_by_watchpoint, ia64_linux_fetch_registers) (ia64_linux_store_registers, ia64_linux_xfer_partial): Refactor as ia64_linux_nat_target methods. (super_xfer_partial): Delete. (_initialize_ia64_linux_nat): Adjust to C++ification. * m32r-linux-nat.c (m32r_linux_nat_target): New class. (the_m32r_linux_nat_target): New. (m32r_linux_fetch_inferior_registers) (m32r_linux_store_inferior_registers): Refactor as m32r_linux_nat_target methods. (_initialize_m32r_linux_nat): Adjust to C++ification. * m68k-linux-nat.c (m68k_linux_nat_target): New class. (the_m68k_linux_nat_target): New. (m68k_linux_fetch_inferior_registers) (m68k_linux_store_inferior_registers): Refactor as m68k_linux_nat_target methods. (_initialize_m68k_linux_nat): Adjust to C++ification. * s390-linux-nat.c (s390_linux_nat_target): New class. (the_s390_linux_nat_target): New. (s390_linux_fetch_inferior_registers) (s390_linux_store_inferior_registers, s390_stopped_by_watchpoint) (s390_insert_watchpoint, s390_remove_watchpoint) (s390_can_use_hw_breakpoint, s390_insert_hw_breakpoint) (s390_remove_hw_breakpoint, s390_region_ok_for_hw_watchpoint) (s390_auxv_parse, s390_read_description): Refactor as methods of s390_linux_nat_target. (_initialize_s390_nat): Adjust to C++ification. * sparc-linux-nat.c (sparc_linux_nat_target): New class. (the_sparc_linux_nat_target): New. (_initialize_sparc_linux_nat): Adjust to C++ification. * sparc-nat.c (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc64-linux-nat.c (sparc64_linux_nat_target): New class. (the_sparc64_linux_nat_target): New. (_initialize_sparc64_linux_nat): Adjust to C++ification. * spu-linux-nat.c (spu_linux_nat_target): New class. (the_spu_linux_nat_target): New. (spu_child_post_startup_inferior, spu_child_post_attach) (spu_child_wait, spu_fetch_inferior_registers) (spu_store_inferior_registers, spu_xfer_partial) (spu_can_use_hw_breakpoint): Refactor as spu_linux_nat_target methods. (_initialize_spu_nat): Adjust to C++ification. * tilegx-linux-nat.c (tilegx_linux_nat_target): New class. (the_tilegx_linux_nat_target): New. (fetch_inferior_registers, store_inferior_registers): Refactor as methods. (_initialize_tile_linux_nat): Adjust to C++ification. * xtensa-linux-nat.c (xtensa_linux_nat_target): New class. (the_xtensa_linux_nat_target): New. (xtensa_linux_fetch_inferior_registers) (xtensa_linux_store_inferior_registers): Refactor as xtensa_linux_nat_target methods. (_initialize_xtensa_linux_nat): Adjust to C++ification. * fbsd-nat.c (USE_SIGTRAP_SIGINFO): Delete. (fbsd_pid_to_exec_file, fbsd_find_memory_regions) (fbsd_find_memory_regions, fbsd_info_proc, fbsd_xfer_partial) (fbsd_thread_alive, fbsd_pid_to_str, fbsd_thread_name) (fbsd_update_thread_list, fbsd_resume, fbsd_wait) (fbsd_stopped_by_sw_breakpoint) (fbsd_supports_stopped_by_sw_breakpoint, fbsd_follow_fork) (fbsd_insert_fork_catchpoint, fbsd_remove_fork_catchpoint) (fbsd_insert_vfork_catchpoint, fbsd_remove_vfork_catchpoint) (fbsd_post_startup_inferior, fbsd_post_attach) (fbsd_insert_exec_catchpoint, fbsd_remove_exec_catchpoint) (fbsd_set_syscall_catchpoint) (super_xfer_partial, super_resume, super_wait) (fbsd_supports_stopped_by_hw_breakpoint): Delete. (fbsd_handle_debug_trap): Remove target_ops parameter. (fbsd_nat_add_target): Delete. * fbsd-nat.h: Include "inf-ptrace.h". (fbsd_nat_add_target): Delete. (USE_SIGTRAP_SIGINFO): Define. (fbsd_nat_target): New class. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers) (amd64bsd_store_inferior_registers): Remove target_ops parameter. (amd64bsd_target): Delete. * amd64-bsd-nat.h: New file. * amd64-fbsd-nat.c: Include "amd64-bsd-nat.h" instead of "x86-bsd-nat.h". (amd64_fbsd_nat_target): New class. (the_amd64_fbsd_nat_target): New. (amd64fbsd_read_description): Refactor as method of amd64_fbsd_nat_target. (amd64_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_amd64fbsd_nat): Adjust to C++ification. * amd64-nat.h (amd64bsd_target): Delete function declaration. * i386-bsd-nat.c (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Remove target_ops parameter. (i386bsd_target): Delete. * i386-bsd-nat.h (i386bsd_target): Delete function declaration. (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Declare. (i386_bsd_nat_target): New class. * i386-fbsd-nat.c (i386_fbsd_nat_target): New class. (the_i386_fbsd_nat_target): New. (i386fbsd_resume, i386fbsd_read_description): Refactor as i386_fbsd_nat_target methods. (i386_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_i386fbsd_nat): Adjust to C++ification. * x86-bsd-nat.c (super_mourn_inferior): Delete. (x86bsd_mourn_inferior, x86bsd_target): Delete. (_initialize_x86_bsd_nat): Adjust to C++ification. * x86-bsd-nat.h: Include "x86-nat.h". (x86bsd_target): Delete declaration. (x86bsd_nat_target): New class. * aarch64-fbsd-nat.c (aarch64_fbsd_nat_target): New class. (the_aarch64_fbsd_nat_target): New. (aarch64_fbsd_fetch_inferior_registers) (aarch64_fbsd_store_inferior_registers): Refactor as methods of aarch64_fbsd_nat_target. (_initialize_aarch64_fbsd_nat): Adjust to C++ification. * alpha-bsd-nat.c (alpha_bsd_nat_target): New class. (the_alpha_bsd_nat_target): New. (alphabsd_fetch_inferior_registers) (alphabsd_store_inferior_registers): Refactor as alpha_bsd_nat_target methods. (_initialize_alphabsd_nat): Refactor as methods of alpha_bsd_nat_target. * amd64-nbsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_nbsd_nat_target): New. (_initialize_amd64nbsd_nat): Adjust to C++ification. * amd64-obsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_obsd_nat_target): New. (_initialize_amd64obsd_nat): Adjust to C++ification. * arm-fbsd-nat.c (arm_fbsd_nat_target): New. (the_arm_fbsd_nat_target): New. (arm_fbsd_fetch_inferior_registers) (arm_fbsd_store_inferior_registers, arm_fbsd_read_description): (_initialize_arm_fbsd_nat): Refactor as methods of arm_fbsd_nat_target. (_initialize_arm_fbsd_nat): Adjust to C++ification. * arm-nbsd-nat.c (arm_netbsd_nat_target): New class. (the_arm_netbsd_nat_target): New. (armnbsd_fetch_registers, armnbsd_store_registers): Refactor as arm_netbsd_nat_target. (_initialize_arm_netbsd_nat): Adjust to C++ification. * hppa-nbsd-nat.c (hppa_nbsd_nat_target): New class. (the_hppa_nbsd_nat_target): New. (hppanbsd_fetch_registers, hppanbsd_store_registers): Refactor as hppa_nbsd_nat_target methods. (_initialize_hppanbsd_nat): Adjust to C++ification. * hppa-obsd-nat.c (hppa_obsd_nat_target): New class. (the_hppa_obsd_nat_target): New. (hppaobsd_fetch_registers, hppaobsd_store_registers): Refactor as methods of hppa_obsd_nat_target. (_initialize_hppaobsd_nat): Adjust to C++ification. Use add_target. * i386-nbsd-nat.c (the_i386_nbsd_nat_target): New. (_initialize_i386nbsd_nat): Adjust to C++ification. Use add_target. * i386-obsd-nat.c (the_i386_obsd_nat_target): New. (_initialize_i386obsd_nat): Use add_target. * m68k-bsd-nat.c (m68k_bsd_nat_target): New class. (the_m68k_bsd_nat_target): New. (m68kbsd_fetch_inferior_registers) (m68kbsd_store_inferior_registers): Refactor as methods of m68k_bsd_nat_target. (_initialize_m68kbsd_nat): Adjust to C++ification. * mips-fbsd-nat.c (mips_fbsd_nat_target): New class. (the_mips_fbsd_nat_target): New. (mips_fbsd_fetch_inferior_registers) (mips_fbsd_store_inferior_registers): Refactor as methods of mips_fbsd_nat_target. (_initialize_mips_fbsd_nat): Adjust to C++ification. Use add_target. * mips-nbsd-nat.c (mips_nbsd_nat_target): New class. (the_mips_nbsd_nat_target): New. (mipsnbsd_fetch_inferior_registers) (mipsnbsd_store_inferior_registers): Refactor as methods of mips_nbsd_nat_target. (_initialize_mipsnbsd_nat): Adjust to C++ification. * mips64-obsd-nat.c (mips64_obsd_nat_target): New class. (the_mips64_obsd_nat_target): New. (mips64obsd_fetch_inferior_registers) (mips64obsd_store_inferior_registers): Refactor as methods of mips64_obsd_nat_target. (_initialize_mips64obsd_nat): Adjust to C++ification. Use add_target. * nbsd-nat.c (nbsd_pid_to_exec_file): Refactor as method of nbsd_nat_target. * nbsd-nat.h: Include "inf-ptrace.h". (nbsd_nat_target): New class. * obsd-nat.c (obsd_pid_to_str, obsd_update_thread_list) (obsd_wait): Refactor as methods of obsd_nat_target. (obsd_add_target): Delete. * obsd-nat.h: Include "inf-ptrace.h". (obsd_nat_target): New class. * ppc-fbsd-nat.c (ppc_fbsd_nat_target): New class. (the_ppc_fbsd_nat_target): New. (ppcfbsd_fetch_inferior_registers) (ppcfbsd_store_inferior_registers): Refactor as methods of ppc_fbsd_nat_target. (_initialize_ppcfbsd_nat): Adjust to C++ification. Use add_target. * ppc-nbsd-nat.c (ppc_nbsd_nat_target): New class. (the_ppc_nbsd_nat_target): New. (ppcnbsd_fetch_inferior_registers) (ppcnbsd_store_inferior_registers): Refactor as methods of ppc_nbsd_nat_target. (_initialize_ppcnbsd_nat): Adjust to C++ification. * ppc-obsd-nat.c (ppc_obsd_nat_target): New class. (the_ppc_obsd_nat_target): New. (ppcobsd_fetch_registers, ppcobsd_store_registers): Refactor as methods of ppc_obsd_nat_target. (_initialize_ppcobsd_nat): Adjust to C++ification. Use add_target. * sh-nbsd-nat.c (sh_nbsd_nat_target): New class. (the_sh_nbsd_nat_target): New. (shnbsd_fetch_inferior_registers) (shnbsd_store_inferior_registers): Refactor as methods of sh_nbsd_nat_target. (_initialize_shnbsd_nat): Adjust to C++ification. * sparc-nat.c (sparc_xfer_wcookie): Make extern. (inf_ptrace_xfer_partial): Delete. (sparc_xfer_partial, sparc_target): Delete. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers, sparc_xfer_wcookie): Declare. (sparc_target): Delete function declaration. (sparc_target): New template class. * sparc-nbsd-nat.c (the_sparc_nbsd_nat_target): New. (_initialize_sparcnbsd_nat): Adjust to C++ification. * sparc64-fbsd-nat.c (the_sparc64_fbsd_nat_target): New. (_initialize_sparc64fbsd_nat): Adjust to C++ification. Use add_target. * sparc64-nbsd-nat.c (the_sparc64_nbsd_nat_target): New. (_initialize_sparc64nbsd_nat): Adjust to C++ification. * sparc64-obsd-nat.c (the_sparc64_obsd_nat_target): New. (_initialize_sparc64obsd_nat): Adjust to C++ification. Use add_target. * vax-bsd-nat.c (vax_bsd_nat_target): New class. (the_vax_bsd_nat_target): New. (vaxbsd_fetch_inferior_registers) (vaxbsd_store_inferior_registers): Refactor as vax_bsd_nat_target methods. (_initialize_vaxbsd_nat): Adjust to C++ification. * bsd-kvm.c (bsd_kvm_target): New class. (bsd_kvm_ops): Now a bsd_kvm_target. (bsd_kvm_open, bsd_kvm_close, bsd_kvm_xfer_partial) (bsd_kvm_files_info, bsd_kvm_fetch_registers) (bsd_kvm_thread_alive, bsd_kvm_pid_to_str): Refactor as methods of bsd_kvm_target. (bsd_kvm_return_one): Delete. (bsd_kvm_add_target): Adjust to C++ification. * nto-procfs.c (nto_procfs_target, nto_procfs_target_native) (nto_procfs_target_procfs): New classes. (procfs_open_1, procfs_thread_alive, procfs_update_thread_list) (procfs_files_info, procfs_pid_to_exec_file, procfs_attach) (procfs_post_attach, procfs_wait, procfs_fetch_registers) (procfs_xfer_partial, procfs_detach, procfs_insert_breakpoint) (procfs_remove_breakpoint, procfs_insert_hw_breakpoint) (procfs_remove_hw_breakpoint, procfs_resume) (procfs_mourn_inferior, procfs_create_inferior, procfs_interrupt) (procfs_kill_inferior, procfs_store_registers) (procfs_pass_signals, procfs_pid_to_str, procfs_can_run): Refactor as methods of nto_procfs_target. (nto_procfs_ops): Now an nto_procfs_target_procfs. (nto_native_ops): Delete. (procfs_open, procfs_native_open): Delete. (nto_native_ops): Now an nto_procfs_target_native. (init_procfs_targets): Adjust to C++ification. (procfs_can_use_hw_breakpoint, procfs_remove_hw_watchpoint) (procfs_insert_hw_watchpoint, procfs_stopped_by_watchpoint): Refactor as methods of nto_procfs_target. * go32-nat.c (go32_nat_target): New class. (the_go32_nat_target): New. (go32_attach, go32_resume, go32_wait, go32_fetch_registers) (go32_store_registers, go32_xfer_partial, go32_files_info) (go32_kill_inferior, go32_create_inferior, go32_mourn_inferior) (go32_terminal_init, go32_terminal_info, go32_terminal_inferior) (go32_terminal_ours, go32_pass_ctrlc, go32_thread_alive) (go32_pid_to_str): Refactor as methods of go32_nat_target. (go32_target): Delete. (_initialize_go32_nat): Adjust to C++ification. * gnu-nat.c (gnu_wait, gnu_resume, gnu_kill_inferior) (gnu_mourn_inferior, gnu_create_inferior, gnu_attach, gnu_detach) (gnu_stop, gnu_thread_alive, gnu_xfer_partial) (gnu_find_memory_regions, gnu_pid_to_str): Refactor as methods of gnu_nat_target. (gnu_target): Delete. * gnu-nat.h (gnu_target): Delete. (gnu_nat_target): New class. * i386-gnu-nat.c (gnu_base_target): New. (i386_gnu_nat_target): New class. (the_i386_gnu_nat_target): New. (_initialize_i386gnu_nat): Adjust to C++ification. gdb/testsuite/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * gdb.base/breakpoint-in-ro-region.exp: Adjust to to_resume and to_log_command renames. * gdb.base/sss-bp-on-user-bp-2.exp: Likewise.
2018-05-03 07:37:22 +08:00
int
ppc_linux_nat_target::remove_watchpoint (CORE_ADDR addr, int len,
enum target_hw_bp_type type,
struct expression *cond)
{
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
gdb_assert (!m_dreg_interface.unavailable_p ());
* linux-nat.c (linux_nat_new_thread): New variable. (linux_child_follow_fork): Set inferior_ptid to include LWP ID. Use linux_nat_switch_fork. (lwp_list): Make public. (add_lwp): Call linux_nat_new_thread. (lin_lwp_attach_lwp, linux_nat_attach): Call add_lwp after stopping the new thread. (resume_callback): Clear lp->siginfo. Remove unused variable. (linux_nat_resume): Assert that the LWP list is already initialized. Clear lp->siginfo. (save_siginfo): New. (stop_wait_callback, linux_nat_wait): Call it. (linux_nat_set_new_thread, linux_nat_get_siginfo): New. * linux-nat.h (struct lwp_info): Add siginfo. (lwp_list, linux_nat_set_new_thread, linux_nat_get_siginfo): Declare. (ALL_LWPS): Define. * amd64-linux-nat.c (amd64_linux_dr): New. (amd64_linux_dr_get): Take a PTID argument. Correct typo. (amd64_linux_dr_set): Take a PTID argument. (amd64_linux_dr_set_control, amd64_linux_dr_set_addr): Use ALL_LWPS. (amd64_linux_dr_reset_addr): Use amd64_linux_dr_set_addr. (amd64_linux_dr_get_status): Pass inferior_ptid to amd64_linux_dr_get. (amd64_linux_new_thread): New. (_initialize_amd64_linux_nat): Call linux_nat_set_new_thread. * i386-linux-nat.c (i386_linux_dr): New. (i386_linux_dr_get, i386_linux_dr_set): Take a PTID argument. (i386_linux_dr_set_control, i386_linux_dr_set_addr): Use ALL_LWPS. (i386_linux_dr_reset_addr): Use i386_linux_dr_set_addr. (i386_linux_dr_get_status): Pass inferior_ptid to i386_linux_dr_get. (i386_linux_new_thread): New. (i386_linux_resume): Remove unnecessary PID check. (_initialize_i386_linux_nat): Call linux_nat_set_new_thread. * ia64-linux-nat.c (enable_watchpoints_in_psr): Take PTID argument. (fetch_debug_register, fetch_debug_register_pair): Delete. (debug_registers): New. (ia64_linux_insert_watchpoint, ia64_linux_remove_watchpoint): Use ALL_LWPS and debug_registers. (ia64_linux_new_thread): New. (ia64_linux_stopped_data_address): Use linux_nat_get_siginfo. (_initialize_ia64_linux_nat): Call linux_nat_set_new_thread. * ppc-linux-nat.c (last_stopped_data_address): Delete. (saved_dabr_value): New. (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint): Use ALL_LWPS. (ppc_linux_new_thread): New. (ppc_linux_stopped_data_address): Use linux_nat_get_siginfo. (ppc_linux_stopped_by_watchpoint): Call ppc_linux_stopped_data_address. (_initialize_ppc_linux_nat): Call linux_nat_set_new_thread. * s390-nat.c (s390_stopped_by_watchpoint): Clear the watchpoint status after reading it. (s390_fix_watch_points): Take a PTID argument. (s390_insert_watchpoint, s390_remove_watchpoint): Use ALL_LWPS. (_initialize_s390_nat): Call linux_nat_set_new_thread.
2007-10-01 08:22:50 +08:00
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
if (m_dreg_interface.hwdebug_p ())
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
{
struct ppc_hw_breakpoint p;
create_watchpoint_request (&p, addr, len, type, cond, 0);
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
clear_hw_breakpoint (inferior_ptid.pid (), p);
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
}
else
{
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
gdb_assert (m_dreg_interface.debugreg_p ());
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
clear_wp (inferior_ptid.pid ());
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
}
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
return 0;
}
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
/* Clean up the per-process info associated with PID. When using the
HWDEBUG interface, we also erase the per-thread state of installed
debug registers for all the threads that belong to the group of PID.
Usually the thread state is cleaned up by low_delete_thread. We also
do it here because low_new_thread is not called for the initial LWP,
so low_delete_thread won't be able to clean up this state. */
linux_nat_target: More low methods This converts the remaining linux-nat.c hooks low_ methods like had been started in a previous patch. The linux_nat_set_foo routines are all gone with this. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * linux-nat.h (linux_nat_target) <low_new_thread, low_delete_thread, low_new_fork, low_forget_process, low_prepare_to_resume, low_siginfo_fixup, low_status_is_event>: New virtual methods. (linux_nat_set_new_thread, linux_nat_set_delete_thread) (linux_nat_new_fork_ftype, linux_nat_set_new_fork) (linux_nat_forget_process_ftype, linux_nat_set_forget_process) (linux_nat_forget_process, linux_nat_set_siginfo_fixup) (linux_nat_set_prepare_to_resume, linux_nat_set_status_is_event): Delete. * linux-fork.c (delete_fork): Adjust to call low method. * linux-nat.c (linux_nat_new_thread, linux_nat_delete_thread) (linux_nat_new_fork, linux_nat_forget_process_hook) (linux_nat_prepare_to_resume, linux_nat_siginfo_fixup) (linux_nat_status_is_event): (linux_nat_target::follow_fork, lwp_free, add_lwp, detach_one_lwp) (linux_resume_one_lwp_throw, linux_handle_extended_wait): Adjust to call low method. (sigtrap_is_event): Rename to ... (linux_nat_target::low_status_is_event): ... this. (linux_nat_set_status_is_event): Delete. (save_stop_reason, linux_nat_wait_1) (linux_nat_target::mourn_inferior, siginfo_fixup): Adjust to call low methods. (linux_nat_set_new_thread, linux_nat_set_delete_thread) (linux_nat_set_new_fork, linux_nat_set_forget_process) (linux_nat_forget_process, linux_nat_set_siginfo_fixup) (linux_nat_set_prepare_to_resume): Delete. * aarch64-linux-nat.c: All linux_nat_set_* callbacks converted to low virtual methods. * amd64-linux-nat.c: Likewise. * arm-linux-nat.c: Likewise. * i386-linux-nat.c: Likewise. * ia64-linux-nat.c: Likewise. * mips-linux-nat.c: Likewise. * ppc-linux-nat.c: Likewise. * s390-linux-nat.c: Likewise. * sparc64-linux-nat.c: Likewise. * x86-linux-nat.c: Likewise. * x86-linux-nat.h: Include "nat/x86-linux.h". (x86_linux_nat_target) <low_new_fork, low_forget_process, low_prepare_to_resume, low_new_thread, low_delete_thread>: Override methods.
2018-05-03 07:37:27 +08:00
void
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
ppc_linux_nat_target::low_forget_process (pid_t pid)
{
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
if ((!m_dreg_interface.detected_p ())
|| (m_dreg_interface.unavailable_p ()))
return;
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
ptid_t pid_ptid (pid, 0, 0);
m_process_info.erase (pid);
if (m_dreg_interface.hwdebug_p ())
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
{
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
for (auto it = m_installed_hw_bps.begin ();
it != m_installed_hw_bps.end ();)
{
if (it->first.matches (pid_ptid))
it = m_installed_hw_bps.erase (it);
else
it++;
}
}
}
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
/* Copy the per-process state associated with the pid of PARENT to the
sate of CHILD_PID. GDB expects that a forked process will have the
same hardware breakpoints and watchpoints as the parent.
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
If we're using the HWDEBUG interface, also copy the thread debug
register state for the ptid of PARENT to the state for CHILD_PID.
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
Like for clone events, we assume the kernel will copy the debug
registers from the parent thread to the child. The
low_prepare_to_resume function is made to work even if it doesn't.
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
We copy the thread state here and not in low_new_thread since we don't
have the pid of the parent in low_new_thread. Even if we did,
low_new_thread might not be called immediately after the fork event is
detected. For instance, with the checkpointing system (see
linux-fork.c), the thread won't be added until GDB decides to switch
to a new checkpointed process. At that point, the debug register
state of the parent thread is unlikely to correspond to the state it
had at the point when it forked. */
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
void
ppc_linux_nat_target::low_new_fork (struct lwp_info *parent,
pid_t child_pid)
{
if ((!m_dreg_interface.detected_p ())
|| (m_dreg_interface.unavailable_p ()))
return;
auto process_it = m_process_info.find (parent->ptid.pid ());
if (process_it != m_process_info.end ())
m_process_info[child_pid] = m_process_info[parent->ptid.pid ()];
if (m_dreg_interface.hwdebug_p ())
{
ptid_t child_ptid (child_pid, child_pid, 0);
copy_thread_dreg_state (parent->ptid, child_ptid);
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
}
}
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
/* Copy the thread debug register state from the PARENT thread to the the
state for CHILD_LWP, if we're using the HWDEBUG interface. We assume
the kernel copies the debug registers from one thread to another after
a clone event. The low_prepare_to_resume function is made to work
even if it doesn't. */
void
ppc_linux_nat_target::low_new_clone (struct lwp_info *parent,
pid_t child_lwp)
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
{
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
if ((!m_dreg_interface.detected_p ())
|| (m_dreg_interface.unavailable_p ()))
return;
if (m_dreg_interface.hwdebug_p ())
{
ptid_t child_ptid (parent->ptid.pid (), child_lwp, 0);
copy_thread_dreg_state (parent->ptid, child_ptid);
}
}
/* Initialize the arch-specific thread state for LP so that it contains
the ptid for lp, so that we can use it in low_delete_thread. Mark the
new thread LP as stale so that we update its debug registers before
resuming it. This is not called for the initial thread. */
void
ppc_linux_nat_target::low_new_thread (struct lwp_info *lp)
{
init_arch_lwp_info (lp);
mark_thread_stale (lp);
}
/* Delete the per-thread debug register stale flag. */
void
ppc_linux_nat_target::low_delete_thread (struct arch_lwp_info
*lp_arch_info)
{
if (lp_arch_info != NULL)
{
if (m_dreg_interface.detected_p ()
&& m_dreg_interface.hwdebug_p ())
m_installed_hw_bps.erase (lp_arch_info->lwp_ptid);
xfree (lp_arch_info);
}
}
/* Install or delete debug registers in thread LP so that it matches what
GDB requested before it is resumed. */
void
ppc_linux_nat_target::low_prepare_to_resume (struct lwp_info *lp)
{
if ((!m_dreg_interface.detected_p ())
|| (m_dreg_interface.unavailable_p ()))
return;
/* We have to re-install or clear the debug registers if we set the
stale flag.
In addition, some kernels configurations can disable a hardware
watchpoint after it is hit. Usually, GDB will remove and re-install
a hardware watchpoint when the thread stops if "breakpoint
always-inserted" is off, or to single-step a watchpoint. But so
that we don't rely on this behavior, if we stop due to a hardware
breakpoint or watchpoint, we also refresh our debug registers. */
arch_lwp_info *lp_arch_info = get_arch_lwp_info (lp);
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
bool stale_dregs = (lp->stop_reason == TARGET_STOPPED_BY_WATCHPOINT
|| lp->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT
|| lp_arch_info->debug_regs_stale);
if (!stale_dregs)
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
return;
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
gdb_assert (lp->ptid.lwp_p ());
auto process_it = m_process_info.find (lp->ptid.pid ());
if (m_dreg_interface.hwdebug_p ())
{
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
/* First, delete any hardware watchpoint or breakpoint installed in
the inferior and update the thread state. */
auto installed_it = m_installed_hw_bps.find (lp->ptid);
if (installed_it != m_installed_hw_bps.end ())
{
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
auto &bp_list = installed_it->second;
for (auto bp_it = bp_list.begin (); bp_it != bp_list.end ();)
{
/* We ignore ENOENT to account for various possible kernel
behaviors, e.g. the kernel might or might not copy debug
registers across forks and clones, and we always copy
the debug register state when fork and clone events are
detected. */
if (ptrace (PPC_PTRACE_DELHWDEBUG, lp->ptid.lwp (), 0,
bp_it->first) == -1)
if (errno != ENOENT)
perror_with_name (_("Error deleting hardware "
"breakpoint or watchpoint"));
/* We erase the entries one at a time after successfuly
removing the corresponding slot form the thread so that
if we throw an exception above in a future iteration the
map remains consistent. */
bp_it = bp_list.erase (bp_it);
}
gdb_assert (bp_list.empty ());
}
/* Now we install all the requested hardware breakpoints and
watchpoints and update the thread state. */
if (process_it != m_process_info.end ())
{
auto &bp_list = m_installed_hw_bps[lp->ptid];
for (ppc_hw_breakpoint bp
: process_it->second.requested_hw_bps)
{
long slot = ptrace (PPC_PTRACE_SETHWDEBUG, lp->ptid.lwp (),
0, &bp);
if (slot < 0)
perror_with_name (_("Error setting hardware "
"breakpoint or watchpoint"));
/* Keep track of which slots we installed in this
thread. */
bp_list.emplace (bp_list.begin (), slot, bp);
}
}
}
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
else
{
gdb_assert (m_dreg_interface.debugreg_p ());
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
/* Passing 0 to PTRACE_SET_DEBUGREG will clear the
watchpoint. */
long wp = 0;
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
/* GDB requested a watchpoint to be installed. */
if (process_it != m_process_info.end ()
&& process_it->second.requested_wp_val.has_value ())
wp = *(process_it->second.requested_wp_val);
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
long ret = ptrace (PTRACE_SET_DEBUGREG, lp->ptid.lwp (),
0, wp);
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
if (ret == -1)
perror_with_name (_("Error setting hardware watchpoint"));
}
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
lp_arch_info->debug_regs_stale = false;
}
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
/* Return true if INFERIOR_PTID is known to have been stopped by a
hardware watchpoint, false otherwise. If true is returned, write the
address that the kernel reported as causing the SIGTRAP in ADDR_P. */
target_ops: Use bool throughout After the previous target_ops/C++ patches are all squashed and merged, this one can go in separately. This patch adjusts all the target methods to return bool instead of int when they're returning a boolean. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * target.h (target_ops) <stopped_by_sw_breakpoint, supports_stopped_by_sw_breakpoint, stopped_by_hw_breakpoint, supports_stopped_by_hw_breakpoint, stopped_by_watchpoint, have_continuable_watchpoint, stopped_data_address, watchpoint_addr_within_range, can_accel_watchpoint_condition, can_run, thread_alive, has_all_memory, has_memory, has_stack, has_registers, has_execution, can_async_p, is_async_p, supports_non_stop, always_non_stop_p, can_execute_reverse, supports_multi_process, supports_enable_disable_tracepoint, supports_disable_randomization, supports_string_tracing, supports_evaluation_of_breakpoint_conditions, can_run_breakpoint_commands, filesystem_is_local, can_download_tracepoint, get_trace_state_variable_value, set_trace_notes, get_tib_address, use_agent, can_use_agent, record_is_replaying, record_will_replay, augmented_libraries_svr4_read>: Adjust to return bool. * aarch64-linux-nat.c: All implementations adjusted. * aix-thread.c: All implementations adjusted. * arm-linux-nat.c: All implementations adjusted. * breakpoint.c: All implementations adjusted. * bsd-kvm.c: All implementations adjusted. * bsd-uthread.c: All implementations adjusted. * corelow.c: All implementations adjusted. * ctf.c: All implementations adjusted. * darwin-nat.c: All implementations adjusted. * darwin-nat.h: All implementations adjusted. * exec.c: All implementations adjusted. * fbsd-nat.c: All implementations adjusted. * fbsd-nat.h: All implementations adjusted. * gnu-nat.c: All implementations adjusted. * gnu-nat.h: All implementations adjusted. * go32-nat.c: All implementations adjusted. * ia64-linux-nat.c: All implementations adjusted. * inf-child.c: All implementations adjusted. * inf-child.h: All implementations adjusted. * inf-ptrace.c: All implementations adjusted. * inf-ptrace.h: All implementations adjusted. * linux-nat.c: All implementations adjusted. * linux-nat.h: All implementations adjusted. * mips-linux-nat.c: All implementations adjusted. * nto-procfs.c: All implementations adjusted. * ppc-linux-nat.c: All implementations adjusted. * procfs.c: All implementations adjusted. * ravenscar-thread.c: All implementations adjusted. * record-btrace.c: All implementations adjusted. * record-full.c: All implementations adjusted. * remote-sim.c: All implementations adjusted. * remote.c: All implementations adjusted. * s390-linux-nat.c: All implementations adjusted. * sol-thread.c: All implementations adjusted. * spu-multiarch.c: All implementations adjusted. * target-delegates.c: All implementations adjusted. * target.c: All implementations adjusted. * target.h: All implementations adjusted. * tracefile-tfile.c: All implementations adjusted. * tracefile.c: All implementations adjusted. * tracefile.h: All implementations adjusted. * windows-nat.c: All implementations adjusted. * x86-linux-nat.h: All implementations adjusted. * x86-nat.h: All implementations adjusted.
2018-05-03 07:37:26 +08:00
bool
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
ppc_linux_nat_target::low_stopped_data_address (CORE_ADDR *addr_p)
{
siginfo_t siginfo;
if (!linux_nat_get_siginfo (inferior_ptid, &siginfo))
target_ops: Use bool throughout After the previous target_ops/C++ patches are all squashed and merged, this one can go in separately. This patch adjusts all the target methods to return bool instead of int when they're returning a boolean. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * target.h (target_ops) <stopped_by_sw_breakpoint, supports_stopped_by_sw_breakpoint, stopped_by_hw_breakpoint, supports_stopped_by_hw_breakpoint, stopped_by_watchpoint, have_continuable_watchpoint, stopped_data_address, watchpoint_addr_within_range, can_accel_watchpoint_condition, can_run, thread_alive, has_all_memory, has_memory, has_stack, has_registers, has_execution, can_async_p, is_async_p, supports_non_stop, always_non_stop_p, can_execute_reverse, supports_multi_process, supports_enable_disable_tracepoint, supports_disable_randomization, supports_string_tracing, supports_evaluation_of_breakpoint_conditions, can_run_breakpoint_commands, filesystem_is_local, can_download_tracepoint, get_trace_state_variable_value, set_trace_notes, get_tib_address, use_agent, can_use_agent, record_is_replaying, record_will_replay, augmented_libraries_svr4_read>: Adjust to return bool. * aarch64-linux-nat.c: All implementations adjusted. * aix-thread.c: All implementations adjusted. * arm-linux-nat.c: All implementations adjusted. * breakpoint.c: All implementations adjusted. * bsd-kvm.c: All implementations adjusted. * bsd-uthread.c: All implementations adjusted. * corelow.c: All implementations adjusted. * ctf.c: All implementations adjusted. * darwin-nat.c: All implementations adjusted. * darwin-nat.h: All implementations adjusted. * exec.c: All implementations adjusted. * fbsd-nat.c: All implementations adjusted. * fbsd-nat.h: All implementations adjusted. * gnu-nat.c: All implementations adjusted. * gnu-nat.h: All implementations adjusted. * go32-nat.c: All implementations adjusted. * ia64-linux-nat.c: All implementations adjusted. * inf-child.c: All implementations adjusted. * inf-child.h: All implementations adjusted. * inf-ptrace.c: All implementations adjusted. * inf-ptrace.h: All implementations adjusted. * linux-nat.c: All implementations adjusted. * linux-nat.h: All implementations adjusted. * mips-linux-nat.c: All implementations adjusted. * nto-procfs.c: All implementations adjusted. * ppc-linux-nat.c: All implementations adjusted. * procfs.c: All implementations adjusted. * ravenscar-thread.c: All implementations adjusted. * record-btrace.c: All implementations adjusted. * record-full.c: All implementations adjusted. * remote-sim.c: All implementations adjusted. * remote.c: All implementations adjusted. * s390-linux-nat.c: All implementations adjusted. * sol-thread.c: All implementations adjusted. * spu-multiarch.c: All implementations adjusted. * target-delegates.c: All implementations adjusted. * target.c: All implementations adjusted. * target.h: All implementations adjusted. * tracefile-tfile.c: All implementations adjusted. * tracefile.c: All implementations adjusted. * tracefile.h: All implementations adjusted. * windows-nat.c: All implementations adjusted. * x86-linux-nat.h: All implementations adjusted. * x86-nat.h: All implementations adjusted.
2018-05-03 07:37:26 +08:00
return false;
if (siginfo.si_signo != SIGTRAP
|| (siginfo.si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */)
target_ops: Use bool throughout After the previous target_ops/C++ patches are all squashed and merged, this one can go in separately. This patch adjusts all the target methods to return bool instead of int when they're returning a boolean. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * target.h (target_ops) <stopped_by_sw_breakpoint, supports_stopped_by_sw_breakpoint, stopped_by_hw_breakpoint, supports_stopped_by_hw_breakpoint, stopped_by_watchpoint, have_continuable_watchpoint, stopped_data_address, watchpoint_addr_within_range, can_accel_watchpoint_condition, can_run, thread_alive, has_all_memory, has_memory, has_stack, has_registers, has_execution, can_async_p, is_async_p, supports_non_stop, always_non_stop_p, can_execute_reverse, supports_multi_process, supports_enable_disable_tracepoint, supports_disable_randomization, supports_string_tracing, supports_evaluation_of_breakpoint_conditions, can_run_breakpoint_commands, filesystem_is_local, can_download_tracepoint, get_trace_state_variable_value, set_trace_notes, get_tib_address, use_agent, can_use_agent, record_is_replaying, record_will_replay, augmented_libraries_svr4_read>: Adjust to return bool. * aarch64-linux-nat.c: All implementations adjusted. * aix-thread.c: All implementations adjusted. * arm-linux-nat.c: All implementations adjusted. * breakpoint.c: All implementations adjusted. * bsd-kvm.c: All implementations adjusted. * bsd-uthread.c: All implementations adjusted. * corelow.c: All implementations adjusted. * ctf.c: All implementations adjusted. * darwin-nat.c: All implementations adjusted. * darwin-nat.h: All implementations adjusted. * exec.c: All implementations adjusted. * fbsd-nat.c: All implementations adjusted. * fbsd-nat.h: All implementations adjusted. * gnu-nat.c: All implementations adjusted. * gnu-nat.h: All implementations adjusted. * go32-nat.c: All implementations adjusted. * ia64-linux-nat.c: All implementations adjusted. * inf-child.c: All implementations adjusted. * inf-child.h: All implementations adjusted. * inf-ptrace.c: All implementations adjusted. * inf-ptrace.h: All implementations adjusted. * linux-nat.c: All implementations adjusted. * linux-nat.h: All implementations adjusted. * mips-linux-nat.c: All implementations adjusted. * nto-procfs.c: All implementations adjusted. * ppc-linux-nat.c: All implementations adjusted. * procfs.c: All implementations adjusted. * ravenscar-thread.c: All implementations adjusted. * record-btrace.c: All implementations adjusted. * record-full.c: All implementations adjusted. * remote-sim.c: All implementations adjusted. * remote.c: All implementations adjusted. * s390-linux-nat.c: All implementations adjusted. * sol-thread.c: All implementations adjusted. * spu-multiarch.c: All implementations adjusted. * target-delegates.c: All implementations adjusted. * target.c: All implementations adjusted. * target.h: All implementations adjusted. * tracefile-tfile.c: All implementations adjusted. * tracefile.c: All implementations adjusted. * tracefile.h: All implementations adjusted. * windows-nat.c: All implementations adjusted. * x86-linux-nat.h: All implementations adjusted. * x86-nat.h: All implementations adjusted.
2018-05-03 07:37:26 +08:00
return false;
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
gdb_assert (!m_dreg_interface.unavailable_p ());
/* Check if this signal corresponds to a hardware breakpoint. We only
need to check this if we're using the HWDEBUG interface, since the
DEBUGREG interface only allows setting one hardware watchpoint. */
if (m_dreg_interface.hwdebug_p ())
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
{
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
/* The index (or slot) of the *point is passed in the si_errno
field. Currently, this is only the case if the kernel was
configured with CONFIG_PPC_ADV_DEBUG_REGS. If not, we assume
the kernel will set si_errno to a value that doesn't correspond
to any real slot. */
int slot = siginfo.si_errno;
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
auto installed_it = m_installed_hw_bps.find (inferior_ptid);
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
/* We must have installed slots for the thread if it got a
TRAP_HWBKPT signal. */
gdb_assert (installed_it != m_installed_hw_bps.end ());
for (const auto & slot_bp_pair : installed_it->second)
if (slot_bp_pair.first == slot
&& (slot_bp_pair.second.trigger_type
== PPC_BREAKPOINT_TRIGGER_EXECUTE))
return false;
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
}
*addr_p = (CORE_ADDR) (uintptr_t) siginfo.si_addr;
target_ops: Use bool throughout After the previous target_ops/C++ patches are all squashed and merged, this one can go in separately. This patch adjusts all the target methods to return bool instead of int when they're returning a boolean. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * target.h (target_ops) <stopped_by_sw_breakpoint, supports_stopped_by_sw_breakpoint, stopped_by_hw_breakpoint, supports_stopped_by_hw_breakpoint, stopped_by_watchpoint, have_continuable_watchpoint, stopped_data_address, watchpoint_addr_within_range, can_accel_watchpoint_condition, can_run, thread_alive, has_all_memory, has_memory, has_stack, has_registers, has_execution, can_async_p, is_async_p, supports_non_stop, always_non_stop_p, can_execute_reverse, supports_multi_process, supports_enable_disable_tracepoint, supports_disable_randomization, supports_string_tracing, supports_evaluation_of_breakpoint_conditions, can_run_breakpoint_commands, filesystem_is_local, can_download_tracepoint, get_trace_state_variable_value, set_trace_notes, get_tib_address, use_agent, can_use_agent, record_is_replaying, record_will_replay, augmented_libraries_svr4_read>: Adjust to return bool. * aarch64-linux-nat.c: All implementations adjusted. * aix-thread.c: All implementations adjusted. * arm-linux-nat.c: All implementations adjusted. * breakpoint.c: All implementations adjusted. * bsd-kvm.c: All implementations adjusted. * bsd-uthread.c: All implementations adjusted. * corelow.c: All implementations adjusted. * ctf.c: All implementations adjusted. * darwin-nat.c: All implementations adjusted. * darwin-nat.h: All implementations adjusted. * exec.c: All implementations adjusted. * fbsd-nat.c: All implementations adjusted. * fbsd-nat.h: All implementations adjusted. * gnu-nat.c: All implementations adjusted. * gnu-nat.h: All implementations adjusted. * go32-nat.c: All implementations adjusted. * ia64-linux-nat.c: All implementations adjusted. * inf-child.c: All implementations adjusted. * inf-child.h: All implementations adjusted. * inf-ptrace.c: All implementations adjusted. * inf-ptrace.h: All implementations adjusted. * linux-nat.c: All implementations adjusted. * linux-nat.h: All implementations adjusted. * mips-linux-nat.c: All implementations adjusted. * nto-procfs.c: All implementations adjusted. * ppc-linux-nat.c: All implementations adjusted. * procfs.c: All implementations adjusted. * ravenscar-thread.c: All implementations adjusted. * record-btrace.c: All implementations adjusted. * record-full.c: All implementations adjusted. * remote-sim.c: All implementations adjusted. * remote.c: All implementations adjusted. * s390-linux-nat.c: All implementations adjusted. * sol-thread.c: All implementations adjusted. * spu-multiarch.c: All implementations adjusted. * target-delegates.c: All implementations adjusted. * target.c: All implementations adjusted. * target.h: All implementations adjusted. * tracefile-tfile.c: All implementations adjusted. * tracefile.c: All implementations adjusted. * tracefile.h: All implementations adjusted. * windows-nat.c: All implementations adjusted. * x86-linux-nat.h: All implementations adjusted. * x86-nat.h: All implementations adjusted.
2018-05-03 07:37:26 +08:00
return true;
}
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
/* Return true if INFERIOR_PTID is known to have been stopped by a
hardware watchpoint, false otherwise. */
target_ops: Use bool throughout After the previous target_ops/C++ patches are all squashed and merged, this one can go in separately. This patch adjusts all the target methods to return bool instead of int when they're returning a boolean. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * target.h (target_ops) <stopped_by_sw_breakpoint, supports_stopped_by_sw_breakpoint, stopped_by_hw_breakpoint, supports_stopped_by_hw_breakpoint, stopped_by_watchpoint, have_continuable_watchpoint, stopped_data_address, watchpoint_addr_within_range, can_accel_watchpoint_condition, can_run, thread_alive, has_all_memory, has_memory, has_stack, has_registers, has_execution, can_async_p, is_async_p, supports_non_stop, always_non_stop_p, can_execute_reverse, supports_multi_process, supports_enable_disable_tracepoint, supports_disable_randomization, supports_string_tracing, supports_evaluation_of_breakpoint_conditions, can_run_breakpoint_commands, filesystem_is_local, can_download_tracepoint, get_trace_state_variable_value, set_trace_notes, get_tib_address, use_agent, can_use_agent, record_is_replaying, record_will_replay, augmented_libraries_svr4_read>: Adjust to return bool. * aarch64-linux-nat.c: All implementations adjusted. * aix-thread.c: All implementations adjusted. * arm-linux-nat.c: All implementations adjusted. * breakpoint.c: All implementations adjusted. * bsd-kvm.c: All implementations adjusted. * bsd-uthread.c: All implementations adjusted. * corelow.c: All implementations adjusted. * ctf.c: All implementations adjusted. * darwin-nat.c: All implementations adjusted. * darwin-nat.h: All implementations adjusted. * exec.c: All implementations adjusted. * fbsd-nat.c: All implementations adjusted. * fbsd-nat.h: All implementations adjusted. * gnu-nat.c: All implementations adjusted. * gnu-nat.h: All implementations adjusted. * go32-nat.c: All implementations adjusted. * ia64-linux-nat.c: All implementations adjusted. * inf-child.c: All implementations adjusted. * inf-child.h: All implementations adjusted. * inf-ptrace.c: All implementations adjusted. * inf-ptrace.h: All implementations adjusted. * linux-nat.c: All implementations adjusted. * linux-nat.h: All implementations adjusted. * mips-linux-nat.c: All implementations adjusted. * nto-procfs.c: All implementations adjusted. * ppc-linux-nat.c: All implementations adjusted. * procfs.c: All implementations adjusted. * ravenscar-thread.c: All implementations adjusted. * record-btrace.c: All implementations adjusted. * record-full.c: All implementations adjusted. * remote-sim.c: All implementations adjusted. * remote.c: All implementations adjusted. * s390-linux-nat.c: All implementations adjusted. * sol-thread.c: All implementations adjusted. * spu-multiarch.c: All implementations adjusted. * target-delegates.c: All implementations adjusted. * target.c: All implementations adjusted. * target.h: All implementations adjusted. * tracefile-tfile.c: All implementations adjusted. * tracefile.c: All implementations adjusted. * tracefile.h: All implementations adjusted. * windows-nat.c: All implementations adjusted. * x86-linux-nat.h: All implementations adjusted. * x86-nat.h: All implementations adjusted.
2018-05-03 07:37:26 +08:00
bool
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
ppc_linux_nat_target::low_stopped_by_watchpoint ()
* linux-nat.c (linux_nat_new_thread): New variable. (linux_child_follow_fork): Set inferior_ptid to include LWP ID. Use linux_nat_switch_fork. (lwp_list): Make public. (add_lwp): Call linux_nat_new_thread. (lin_lwp_attach_lwp, linux_nat_attach): Call add_lwp after stopping the new thread. (resume_callback): Clear lp->siginfo. Remove unused variable. (linux_nat_resume): Assert that the LWP list is already initialized. Clear lp->siginfo. (save_siginfo): New. (stop_wait_callback, linux_nat_wait): Call it. (linux_nat_set_new_thread, linux_nat_get_siginfo): New. * linux-nat.h (struct lwp_info): Add siginfo. (lwp_list, linux_nat_set_new_thread, linux_nat_get_siginfo): Declare. (ALL_LWPS): Define. * amd64-linux-nat.c (amd64_linux_dr): New. (amd64_linux_dr_get): Take a PTID argument. Correct typo. (amd64_linux_dr_set): Take a PTID argument. (amd64_linux_dr_set_control, amd64_linux_dr_set_addr): Use ALL_LWPS. (amd64_linux_dr_reset_addr): Use amd64_linux_dr_set_addr. (amd64_linux_dr_get_status): Pass inferior_ptid to amd64_linux_dr_get. (amd64_linux_new_thread): New. (_initialize_amd64_linux_nat): Call linux_nat_set_new_thread. * i386-linux-nat.c (i386_linux_dr): New. (i386_linux_dr_get, i386_linux_dr_set): Take a PTID argument. (i386_linux_dr_set_control, i386_linux_dr_set_addr): Use ALL_LWPS. (i386_linux_dr_reset_addr): Use i386_linux_dr_set_addr. (i386_linux_dr_get_status): Pass inferior_ptid to i386_linux_dr_get. (i386_linux_new_thread): New. (i386_linux_resume): Remove unnecessary PID check. (_initialize_i386_linux_nat): Call linux_nat_set_new_thread. * ia64-linux-nat.c (enable_watchpoints_in_psr): Take PTID argument. (fetch_debug_register, fetch_debug_register_pair): Delete. (debug_registers): New. (ia64_linux_insert_watchpoint, ia64_linux_remove_watchpoint): Use ALL_LWPS and debug_registers. (ia64_linux_new_thread): New. (ia64_linux_stopped_data_address): Use linux_nat_get_siginfo. (_initialize_ia64_linux_nat): Call linux_nat_set_new_thread. * ppc-linux-nat.c (last_stopped_data_address): Delete. (saved_dabr_value): New. (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint): Use ALL_LWPS. (ppc_linux_new_thread): New. (ppc_linux_stopped_data_address): Use linux_nat_get_siginfo. (ppc_linux_stopped_by_watchpoint): Call ppc_linux_stopped_data_address. (_initialize_ppc_linux_nat): Call linux_nat_set_new_thread. * s390-nat.c (s390_stopped_by_watchpoint): Clear the watchpoint status after reading it. (s390_fix_watch_points): Take a PTID argument. (s390_insert_watchpoint, s390_remove_watchpoint): Use ALL_LWPS. (_initialize_s390_nat): Call linux_nat_set_new_thread.
2007-10-01 08:22:50 +08:00
{
CORE_ADDR addr;
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
return low_stopped_data_address (&addr);
* linux-nat.c (linux_nat_new_thread): New variable. (linux_child_follow_fork): Set inferior_ptid to include LWP ID. Use linux_nat_switch_fork. (lwp_list): Make public. (add_lwp): Call linux_nat_new_thread. (lin_lwp_attach_lwp, linux_nat_attach): Call add_lwp after stopping the new thread. (resume_callback): Clear lp->siginfo. Remove unused variable. (linux_nat_resume): Assert that the LWP list is already initialized. Clear lp->siginfo. (save_siginfo): New. (stop_wait_callback, linux_nat_wait): Call it. (linux_nat_set_new_thread, linux_nat_get_siginfo): New. * linux-nat.h (struct lwp_info): Add siginfo. (lwp_list, linux_nat_set_new_thread, linux_nat_get_siginfo): Declare. (ALL_LWPS): Define. * amd64-linux-nat.c (amd64_linux_dr): New. (amd64_linux_dr_get): Take a PTID argument. Correct typo. (amd64_linux_dr_set): Take a PTID argument. (amd64_linux_dr_set_control, amd64_linux_dr_set_addr): Use ALL_LWPS. (amd64_linux_dr_reset_addr): Use amd64_linux_dr_set_addr. (amd64_linux_dr_get_status): Pass inferior_ptid to amd64_linux_dr_get. (amd64_linux_new_thread): New. (_initialize_amd64_linux_nat): Call linux_nat_set_new_thread. * i386-linux-nat.c (i386_linux_dr): New. (i386_linux_dr_get, i386_linux_dr_set): Take a PTID argument. (i386_linux_dr_set_control, i386_linux_dr_set_addr): Use ALL_LWPS. (i386_linux_dr_reset_addr): Use i386_linux_dr_set_addr. (i386_linux_dr_get_status): Pass inferior_ptid to i386_linux_dr_get. (i386_linux_new_thread): New. (i386_linux_resume): Remove unnecessary PID check. (_initialize_i386_linux_nat): Call linux_nat_set_new_thread. * ia64-linux-nat.c (enable_watchpoints_in_psr): Take PTID argument. (fetch_debug_register, fetch_debug_register_pair): Delete. (debug_registers): New. (ia64_linux_insert_watchpoint, ia64_linux_remove_watchpoint): Use ALL_LWPS and debug_registers. (ia64_linux_new_thread): New. (ia64_linux_stopped_data_address): Use linux_nat_get_siginfo. (_initialize_ia64_linux_nat): Call linux_nat_set_new_thread. * ppc-linux-nat.c (last_stopped_data_address): Delete. (saved_dabr_value): New. (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint): Use ALL_LWPS. (ppc_linux_new_thread): New. (ppc_linux_stopped_data_address): Use linux_nat_get_siginfo. (ppc_linux_stopped_by_watchpoint): Call ppc_linux_stopped_data_address. (_initialize_ppc_linux_nat): Call linux_nat_set_new_thread. * s390-nat.c (s390_stopped_by_watchpoint): Clear the watchpoint status after reading it. (s390_fix_watch_points): Take a PTID argument. (s390_insert_watchpoint, s390_remove_watchpoint): Use ALL_LWPS. (_initialize_s390_nat): Call linux_nat_set_new_thread.
2007-10-01 08:22:50 +08:00
}
target_ops: Use bool throughout After the previous target_ops/C++ patches are all squashed and merged, this one can go in separately. This patch adjusts all the target methods to return bool instead of int when they're returning a boolean. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * target.h (target_ops) <stopped_by_sw_breakpoint, supports_stopped_by_sw_breakpoint, stopped_by_hw_breakpoint, supports_stopped_by_hw_breakpoint, stopped_by_watchpoint, have_continuable_watchpoint, stopped_data_address, watchpoint_addr_within_range, can_accel_watchpoint_condition, can_run, thread_alive, has_all_memory, has_memory, has_stack, has_registers, has_execution, can_async_p, is_async_p, supports_non_stop, always_non_stop_p, can_execute_reverse, supports_multi_process, supports_enable_disable_tracepoint, supports_disable_randomization, supports_string_tracing, supports_evaluation_of_breakpoint_conditions, can_run_breakpoint_commands, filesystem_is_local, can_download_tracepoint, get_trace_state_variable_value, set_trace_notes, get_tib_address, use_agent, can_use_agent, record_is_replaying, record_will_replay, augmented_libraries_svr4_read>: Adjust to return bool. * aarch64-linux-nat.c: All implementations adjusted. * aix-thread.c: All implementations adjusted. * arm-linux-nat.c: All implementations adjusted. * breakpoint.c: All implementations adjusted. * bsd-kvm.c: All implementations adjusted. * bsd-uthread.c: All implementations adjusted. * corelow.c: All implementations adjusted. * ctf.c: All implementations adjusted. * darwin-nat.c: All implementations adjusted. * darwin-nat.h: All implementations adjusted. * exec.c: All implementations adjusted. * fbsd-nat.c: All implementations adjusted. * fbsd-nat.h: All implementations adjusted. * gnu-nat.c: All implementations adjusted. * gnu-nat.h: All implementations adjusted. * go32-nat.c: All implementations adjusted. * ia64-linux-nat.c: All implementations adjusted. * inf-child.c: All implementations adjusted. * inf-child.h: All implementations adjusted. * inf-ptrace.c: All implementations adjusted. * inf-ptrace.h: All implementations adjusted. * linux-nat.c: All implementations adjusted. * linux-nat.h: All implementations adjusted. * mips-linux-nat.c: All implementations adjusted. * nto-procfs.c: All implementations adjusted. * ppc-linux-nat.c: All implementations adjusted. * procfs.c: All implementations adjusted. * ravenscar-thread.c: All implementations adjusted. * record-btrace.c: All implementations adjusted. * record-full.c: All implementations adjusted. * remote-sim.c: All implementations adjusted. * remote.c: All implementations adjusted. * s390-linux-nat.c: All implementations adjusted. * sol-thread.c: All implementations adjusted. * spu-multiarch.c: All implementations adjusted. * target-delegates.c: All implementations adjusted. * target.c: All implementations adjusted. * target.h: All implementations adjusted. * tracefile-tfile.c: All implementations adjusted. * tracefile.c: All implementations adjusted. * tracefile.h: All implementations adjusted. * windows-nat.c: All implementations adjusted. * x86-linux-nat.h: All implementations adjusted. * x86-nat.h: All implementations adjusted.
2018-05-03 07:37:26 +08:00
bool
Convert struct target_ops to C++ I.e., use C++ virtual methods and inheritance instead of tables of function pointers. Unfortunately, there's no way to do a smooth transition. ALL native targets in the tree must be converted at the same time. I've tested all I could with cross compilers and with help from GCC compile farm, but naturally I haven't been able to test many of the ports. Still, I made a best effort to port everything over, and while I expect some build problems due to typos and such, which should be trivial to fix, I don't expect any design problems. * Implementation notes: - The flattened current_target is gone. References to current_target or current_target.beneath are replaced with references to target_stack (the top of the stack) directly. - To keep "set debug target" working, this adds a new debug_stratum layer that sits on top of the stack, prints the debug, and delegates to the target beneath. In addition, this makes the shortname and longname properties of target_ops be virtual methods instead of data fields, and makes the debug target defer those to the target beneath. This is so that debug code sprinkled around that does "if (debugtarget) ..." can transparently print the name of the target beneath. A patch later in the series actually splits out the shortname/longname methods to a separate structure, but I preferred to keep that chance separate as it is associated with changing a bit the design of how targets are registered and open. - Since you can't check whether a C++ virtual method is overridden, the old method of checking whether a target_ops implements a method by comparing the function pointer must be replaced with something else. Some cases are fixed by adding a parallel "can_do_foo" target_ops methods. E.g.,: + for (t = target_stack; t != NULL; t = t->beneath) { - if (t->to_create_inferior != NULL) + if (t->can_create_inferior ()) break; } Others are fixed by changing void return type to bool or int return type, and have the default implementation return false or -1, to indicate lack of support. - make-target-delegates was adjusted to generate C++ classes and methods. It needed tweaks to grok "virtual" in front of the target method name, and for the fact that methods are no longer function pointers. (In particular, the current code parsing the return type was simple because it could simply parse up until the '(' in '(*to_foo)'. It now generates a couple C++ classes that inherit target_ops: dummy_target and debug_target. Since we need to generate the class declarations as well, i.e., we need to emit methods twice, we now generate the code in two passes. - The core_target global is renamed to avoid conflict with the "core_target" class. - ctf/tfile targets init_tracefile_ops is replaced by a base class that is inherited by both ctf and tfile. - bsd-uthread The bsd_uthread_ops_hack hack is gone. It's not needed because nothing was extending a target created by bsd_uthread_target. - remote/extended-remote targets This is a first pass, just enough to C++ify target_ops. A later pass will convert more free functions to methods, and make remote_state be truly per remote instance, allowing multiple simultaneous instances of remote targets. - inf-child/"native" is converted to an actual base class (inf_child_target), that is inherited by all native targets. - GNU/Linux The old weird double-target linux_ops mechanism in linux-nat.c, is gone, replaced by adding a few virtual methods to linux-nat.h's target_ops, called low_XXX, that the concrete linux-nat implementations override. Sort of like gdbserver's linux_target_ops, but simpler, for requiring only one target_ops-like hierarchy, which spares implementing the same method twice when we need to forward the method to a low implementation. The low target simply reimplements the target_ops method directly in that case. There are a few remaining linux-nat.c hooks that would be better converted to low_ methods like above too. E.g.: linux_nat_set_new_thread (t, x86_linux_new_thread); linux_nat_set_new_fork (t, x86_linux_new_fork); linux_nat_set_forget_process That'll be done in a follow up patch. - We can no longer use functions like x86_use_watchpoints to install custom methods on an arbitrary base target. The patch replaces instances of such a pattern with template mixins. For example memory_breakpoint_target defined in target.h, or x86_nat_target in x86-nat.h. - linux_trad_target, MIPS and Alpha GNU/Linux The code in the new linux-nat-trad.h/c files which was split off of inf-ptrace.h/c recently, is converted to a C++ base class, and used by the MIPS and Alpha GNU/Linux ports. - BSD targets The $architecture x NetBSD/OpenBSD/FreeBSD support matrix complicates things a bit. There's common BSD target code, and there's common architecture-specific code shared between the different BSDs. Currently, all that is stiched together to form a final target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target functions etc. This introduces new fbsd_nat_target, obsd_nat_target and nbsd_nat_target classes that serve as base/prototype target for the corresponding BSD variant. And introduces generic i386/AMD64 BSD targets, to be used as template mixin to build a final target. Similarly, a generic SPARC target is added, used by both BSD and Linux ports. - bsd_kvm_add_target, BSD libkvm target I considered making bsd_kvm_supply_pcb a virtual method, and then have each port inherit bsd_kvm_target and override that method, but that was resulting in lots of unjustified churn, so I left the function pointer mechanism alone. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> John Baldwin <jhb@freebsd.org> * target.h (enum strata) <debug_stratum>: New. (struct target_ops) <all delegation methods>: Replace by C++ virtual methods, and drop "to_" prefix. All references updated throughout. <to_shortname, to_longname, to_doc, to_data, to_have_steppable_watchpoint, to_have_continuable_watchpoint, to_has_thread_control, to_attach_no_wait>: Delete, replaced by virtual methods. All references updated throughout. <can_attach, supports_terminal_ours, can_create_inferior, get_thread_control_capabilities, attach_no_wait>: New virtual methods. <insert_breakpoint, remove_breakpoint>: Now TARGET_DEFAULT_NORETURN methods. <info_proc>: Now returns bool. <to_magic>: Delete. (OPS_MAGIC): Delete. (current_target): Delete. All references replaced by references to ... (target_stack): ... this. New. (target_shortname, target_longname): Adjust. (target_can_run): Now a function declaration. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (memory_breakpoint_target): New template class. (test_target_ops): Refactor as a C++ class with virtual methods. * make-target-delegates (NAME_PART): Tighten. (POINTER_PART, CP_SYMBOL): New. (SIMPLE_RETURN_PART): Reimplement. (VEC_RETURN_PART): Expect less. (RETURN_PART, VIRTUAL_PART): New. (METHOD): Adjust to C++ virtual methods. (scan_target_h): Remove reference to C99. (dname): Output "target_ops::" prefix. (write_function_header): Adjust to output a C++ class method. (write_declaration): New. (write_delegator): Adjust to output a C++ class method. (tdname): Output "dummy_target::" prefix. (write_tdefault, write_debugmethod): Adjust to output a C++ class method. (tdefault_names, debug_names): Delete. (return_types, tdefaults, styles, argtypes_array): New. (top level): All methods are delegators. (print_class): New. (top level): Print dummy_target and debug_target classes. * target-delegates.c: Regenerate. * target-debug.h (target_debug_print_enum_info_proc_what) (target_debug_print_thread_control_capabilities) (target_debug_print_thread_info_p): New. * target.c (dummy_target): Delete. (the_dummy_target, the_debug_target): New. (target_stack): Now extern. (set_targetdebug): Push/unpush debug target. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (add_target_with_completer): No longer call complete_target_initialization. (target_supports_terminal_ours): Use regular delegation. (update_current_target): Delete. (push_target): No longer check magic number. Don't call update_current_target. (unpush_target): Don't call update_current_target. (target_is_pushed): No longer check magic number. (target_require_runnable): Skip for all stratums over process_stratum. (target_ops::info_proc): New. (target_info_proc): Use find_target_at and find_default_run_target. (target_supports_disable_randomization): Use regular delegation. (target_get_osdata): Use find_target_at. (target_ops::open, target_ops::close, target_ops::can_attach) (target_ops::attach, target_ops::can_create_inferior) (target_ops::create_inferior, target_ops::can_run) (target_can_run): New. (default_fileio_target): Use regular delegation. (target_ops::fileio_open, target_ops::fileio_pwrite) (target_ops::fileio_pread, target_ops::fileio_fstat) (target_ops::fileio_close, target_ops::fileio_unlink) (target_ops::fileio_readlink): New. (target_fileio_open_1, target_fileio_unlink) (target_fileio_readlink): Always call the target method. Handle FILEIO_ENOSYS. (return_zero, return_zero_has_execution): Delete. (init_dummy_target): Delete. (dummy_target::dummy_target, dummy_target::shortname) (dummy_target::longname, dummy_target::doc) (debug_target::debug_target, debug_target::shortname) (debug_target::longname, debug_target::doc): New. (target_supports_delete_record): Use regular delegation. (setup_target_debug): Delete. (maintenance_print_target_stack): Skip debug_stratum. (initialize_targets): Instantiate the_dummy_target and the_debug_target. * auxv.c (target_auxv_parse): Remove 'ops' parameter. Adjust to use target_stack. (target_auxv_search, fprint_target_auxv): Adjust. (info_auxv_command): Adjust to use target_stack. * auxv.h (target_auxv_parse): Remove 'ops' parameter. * exceptions.c (print_flush): Handle a NULL target_stack. * regcache.c (target_ops_no_register): Refactor as class with virtual methods. * exec.c (exec_target): New class. (exec_ops): Now an exec_target. (exec_open, exec_close_1, exec_get_section_table) (exec_xfer_partial, exec_files_info, exec_has_memory) (exec_make_note_section): Refactor as exec_target methods. (exec_file_clear, ignore, exec_remove_breakpoint, init_exec_ops): Delete. (exec_target::find_memory_regions): New. (_initialize_exec): Don't call init_exec_ops. * gdbcore.h (exec_file_clear): Delete. * corefile.c (core_target): Delete. (core_file_command): Adjust. * corelow.c (core_target): New class. (the_core_target): New. (core_close): Remove target_ops parameter. (core_close_cleanup): Adjust. (core_target::close): New. (core_open, core_detach, get_core_registers, core_files_info) (core_xfer_partial, core_thread_alive, core_read_description) (core_pid_to_str, core_thread_name, core_has_memory) (core_has_stack, core_has_registers, core_info_proc): Rework as core_target methods. (ignore, core_remove_breakpoint, init_core_ops): Delete. (_initialize_corelow): Initialize the_core_target. * gdbcore.h (core_target): Delete. (the_core_target): New. * ctf.c: (ctf_target): New class. (ctf_ops): Now a ctf_target. (ctf_open, ctf_close, ctf_files_info, ctf_fetch_registers) (ctf_xfer_partial, ctf_get_trace_state_variable_value) (ctf_trace_find, ctf_traceframe_info): Refactor as ctf_target methods. (init_ctf_ops): Delete. (_initialize_ctf): Don't call it. * tracefile-tfile.c (tfile_target): New class. (tfile_ops): Now a tfile_target. (tfile_open, tfile_close, tfile_files_info) (tfile_get_tracepoint_status, tfile_trace_find) (tfile_fetch_registers, tfile_xfer_partial) (tfile_get_trace_state_variable_value, tfile_traceframe_info): Refactor as tfile_target methods. (tfile_xfer_partial_features): Remove target_ops parameter. (init_tfile_ops): Delete. (_initialize_tracefile_tfile): Don't call it. * tracefile.c (tracefile_has_all_memory, tracefile_has_memory) (tracefile_has_stack, tracefile_has_registers) (tracefile_thread_alive, tracefile_get_trace_status): Refactor as tracefile_target methods. (init_tracefile_ops): Delete. (tracefile_target::tracefile_target): New. * tracefile.h: Include "target.h". (tracefile_target): New class. (init_tracefile_ops): Delete. * spu-multiarch.c (spu_multiarch_target): New class. (spu_ops): Now a spu_multiarch_target. (spu_thread_architecture, spu_region_ok_for_hw_watchpoint) (spu_fetch_registers, spu_store_registers, spu_xfer_partial) (spu_search_memory, spu_mourn_inferior): Refactor as spu_multiarch_target methods. (init_spu_ops): Delete. (_initialize_spu_multiarch): Remove references to init_spu_ops, complete_target_initialization. * ravenscar-thread.c (ravenscar_thread_target): New class. (ravenscar_ops): Now a ravenscar_thread_target. (ravenscar_resume, ravenscar_wait, ravenscar_update_thread_list) (ravenscar_thread_alive, ravenscar_pid_to_str) (ravenscar_fetch_registers, ravenscar_store_registers) (ravenscar_prepare_to_store, ravenscar_stopped_by_sw_breakpoint) (ravenscar_stopped_by_hw_breakpoint) (ravenscar_stopped_by_watchpoint, ravenscar_stopped_data_address) (ravenscar_mourn_inferior, ravenscar_core_of_thread) (ravenscar_get_ada_task_ptid): Refactor as ravenscar_thread_target methods. (init_ravenscar_thread_ops): Delete. (_initialize_ravenscar): Remove references to init_ravenscar_thread_ops and complete_target_initialization. * bsd-uthread.c (bsd_uthread_ops_hack): Delete. (bsd_uthread_target): New class. (bsd_uthread_ops): Now a bsd_uthread_target. (bsd_uthread_activate): Adjust to refer to bsd_uthread_ops. (bsd_uthread_close, bsd_uthread_mourn_inferior) (bsd_uthread_fetch_registers, bsd_uthread_store_registers) (bsd_uthread_wait, bsd_uthread_resume, bsd_uthread_thread_alive) (bsd_uthread_update_thread_list, bsd_uthread_extra_thread_info) (bsd_uthread_pid_to_str): Refactor as bsd_uthread_target methods. (bsd_uthread_target): Delete function. (_initialize_bsd_uthread): Remove reference to complete_target_initialization. * bfd-target.c (target_bfd_data): Delete. Fields folded into ... (target_bfd): ... this new class. (target_bfd_xfer_partial, target_bfd_get_section_table) (target_bfd_close): Refactor as target_bfd methods. (target_bfd::~target_bfd): New. (target_bfd_reopen): Adjust. (target_bfd::close): New. * record-btrace.c (record_btrace_target): New class. (record_btrace_ops): Now a record_btrace_target. (record_btrace_open, record_btrace_stop_recording) (record_btrace_disconnect, record_btrace_close) (record_btrace_async, record_btrace_info) (record_btrace_insn_history, record_btrace_insn_history_range) (record_btrace_insn_history_from, record_btrace_call_history) (record_btrace_call_history_range) (record_btrace_call_history_from, record_btrace_record_method) (record_btrace_is_replaying, record_btrace_will_replay) (record_btrace_xfer_partial, record_btrace_insert_breakpoint) (record_btrace_remove_breakpoint, record_btrace_fetch_registers) (record_btrace_store_registers, record_btrace_prepare_to_store) (record_btrace_to_get_unwinder) (record_btrace_to_get_tailcall_unwinder, record_btrace_resume) (record_btrace_commit_resume, record_btrace_wait) (record_btrace_stop, record_btrace_can_execute_reverse) (record_btrace_stopped_by_sw_breakpoint) (record_btrace_supports_stopped_by_sw_breakpoint) (record_btrace_stopped_by_hw_breakpoint) (record_btrace_supports_stopped_by_hw_breakpoint) (record_btrace_update_thread_list, record_btrace_thread_alive) (record_btrace_goto_begin, record_btrace_goto_end) (record_btrace_goto, record_btrace_stop_replaying_all) (record_btrace_execution_direction) (record_btrace_prepare_to_generate_core) (record_btrace_done_generating_core): Refactor as record_btrace_target methods. (init_record_btrace_ops): Delete. (_initialize_record_btrace): Remove reference to init_record_btrace_ops. * record-full.c (RECORD_FULL_IS_REPLAY): Adjust to always refer to the execution_direction global. (record_full_base_target, record_full_target) (record_full_core_target): New classes. (record_full_ops): Now a record_full_target. (record_full_core_ops): Now a record_full_core_target. (record_full_target::detach, record_full_target::disconnect) (record_full_core_target::disconnect) (record_full_target::mourn_inferior, record_full_target::kill): New. (record_full_open, record_full_close, record_full_async): Refactor as methods of the record_full_base_target class. (record_full_resume, record_full_commit_resume): Refactor as methods of the record_full_target class. (record_full_wait, record_full_stopped_by_watchpoint) (record_full_stopped_data_address) (record_full_stopped_by_sw_breakpoint) (record_full_supports_stopped_by_sw_breakpoint) (record_full_stopped_by_hw_breakpoint) (record_full_supports_stopped_by_hw_breakpoint): Refactor as methods of the record_full_base_target class. (record_full_store_registers, record_full_xfer_partial) (record_full_insert_breakpoint, record_full_remove_breakpoint): Refactor as methods of the record_full_target class. (record_full_can_execute_reverse, record_full_get_bookmark) (record_full_goto_bookmark, record_full_execution_direction) (record_full_record_method, record_full_info, record_full_delete) (record_full_is_replaying, record_full_will_replay) (record_full_goto_begin, record_full_goto_end, record_full_goto) (record_full_stop_replaying): Refactor as methods of the record_full_base_target class. (record_full_core_resume, record_full_core_kill) (record_full_core_fetch_registers) (record_full_core_prepare_to_store) (record_full_core_store_registers, record_full_core_xfer_partial) (record_full_core_insert_breakpoint) (record_full_core_remove_breakpoint) (record_full_core_has_execution): Refactor as methods of the record_full_core_target class. (record_full_base_target::supports_delete_record): New. (init_record_full_ops): Delete. (init_record_full_core_ops): Delete. (record_full_save): Refactor as method of the record_full_base_target class. (_initialize_record_full): Remove references to init_record_full_ops and init_record_full_core_ops. * remote.c (remote_target, extended_remote_target): New classes. (remote_ops): Now a remote_target. (extended_remote_ops): Now an extended_remote_target. (remote_insert_fork_catchpoint, remote_remove_fork_catchpoint) (remote_insert_vfork_catchpoint, remote_remove_vfork_catchpoint) (remote_insert_exec_catchpoint, remote_remove_exec_catchpoint) (remote_pass_signals, remote_set_syscall_catchpoint) (remote_program_signals, ) (remote_thread_always_alive): Remove target_ops parameter. (remote_thread_alive, remote_thread_name) (remote_update_thread_list, remote_threads_extra_info) (remote_static_tracepoint_marker_at) (remote_static_tracepoint_markers_by_strid) (remote_get_ada_task_ptid, remote_close, remote_start_remote) (remote_open): Refactor as methods of remote_target. (extended_remote_open, extended_remote_detach) (extended_remote_attach, extended_remote_post_attach): (extended_remote_supports_disable_randomization) (extended_remote_create_inferior): : Refactor as method of extended_remote_target. (remote_set_permissions, remote_open_1, remote_detach) (remote_follow_fork, remote_follow_exec, remote_disconnect) (remote_resume, remote_commit_resume, remote_stop) (remote_interrupt, remote_pass_ctrlc, remote_terminal_inferior) (remote_terminal_ours, remote_wait, remote_fetch_registers) (remote_prepare_to_store, remote_store_registers) (remote_flash_erase, remote_flash_done, remote_files_info) (remote_kill, remote_mourn, remote_insert_breakpoint) (remote_remove_breakpoint, remote_insert_watchpoint) (remote_watchpoint_addr_within_range) (remote_remove_watchpoint, remote_region_ok_for_hw_watchpoint) (remote_check_watch_resources, remote_stopped_by_sw_breakpoint) (remote_supports_stopped_by_sw_breakpoint) (remote_stopped_by_hw_breakpoint) (remote_supports_stopped_by_hw_breakpoint) (remote_stopped_by_watchpoint, remote_stopped_data_address) (remote_insert_hw_breakpoint, remote_remove_hw_breakpoint) (remote_verify_memory): Refactor as methods of remote_target. (remote_write_qxfer, remote_read_qxfer): Remove target_ops parameter. (remote_xfer_partial, remote_get_memory_xfer_limit) (remote_search_memory, remote_rcmd, remote_memory_map) (remote_pid_to_str, remote_get_thread_local_address) (remote_get_tib_address, remote_read_description): Refactor as methods of remote_target. (remote_target::fileio_open, remote_target::fileio_pwrite) (remote_target::fileio_pread, remote_target::fileio_close): New. (remote_hostio_readlink, remote_hostio_fstat) (remote_filesystem_is_local, remote_can_execute_reverse) (remote_supports_non_stop, remote_supports_disable_randomization) (remote_supports_multi_process, remote_supports_cond_breakpoints) (remote_supports_enable_disable_tracepoint) (remote_supports_string_tracing) (remote_can_run_breakpoint_commands, remote_trace_init) (remote_download_tracepoint, remote_can_download_tracepoint) (remote_download_trace_state_variable, remote_enable_tracepoint) (remote_disable_tracepoint, remote_trace_set_readonly_regions) (remote_trace_start, remote_get_trace_status) (remote_get_tracepoint_status, remote_trace_stop) (remote_trace_find, remote_get_trace_state_variable_value) (remote_save_trace_data, remote_get_raw_trace_data) (remote_set_disconnected_tracing, remote_core_of_thread) (remote_set_circular_trace_buffer, remote_traceframe_info) (remote_get_min_fast_tracepoint_insn_len) (remote_set_trace_buffer_size, remote_set_trace_notes) (remote_use_agent, remote_can_use_agent, remote_enable_btrace) (remote_disable_btrace, remote_teardown_btrace) (remote_read_btrace, remote_btrace_conf) (remote_augmented_libraries_svr4_read, remote_load) (remote_pid_to_exec_file, remote_can_do_single_step) (remote_execution_direction, remote_thread_handle_to_thread_info): Refactor as methods of remote_target. (init_remote_ops, init_extended_remote_ops): Delete. (remote_can_async_p, remote_is_async_p, remote_async) (remote_thread_events, remote_upload_tracepoints) (remote_upload_trace_state_variables): Refactor as methods of remote_target. (_initialize_remote): Remove references to init_remote_ops and init_extended_remote_ops. * remote-sim.c (gdbsim_target): New class. (gdbsim_fetch_register, gdbsim_store_register, gdbsim_kill) (gdbsim_load, gdbsim_create_inferior, gdbsim_open, gdbsim_close) (gdbsim_detach, gdbsim_resume, gdbsim_interrupt) (gdbsim_wait, gdbsim_prepare_to_store, gdbsim_xfer_partial) (gdbsim_files_info, gdbsim_mourn_inferior, gdbsim_thread_alive) (gdbsim_pid_to_str, gdbsim_has_all_memory, gdbsim_has_memory): Refactor as methods of gdbsim_target. (gdbsim_ops): Now a gdbsim_target. (init_gdbsim_ops): Delete. (gdbsim_cntrl_c): Adjust. (_initialize_remote_sim): Remove reference to init_gdbsim_ops. * amd64-linux-nat.c (amd64_linux_nat_target): New class. (the_amd64_linux_nat_target): New. (amd64_linux_fetch_inferior_registers) (amd64_linux_store_inferior_registers): Refactor as methods of amd64_linux_nat_target. (_initialize_amd64_linux_nat): Adjust. Set linux_target. * i386-linux-nat.c: Don't include "linux-nat.h". (i386_linux_nat_target): New class. (the_i386_linux_nat_target): New. (i386_linux_fetch_inferior_registers) (i386_linux_store_inferior_registers, i386_linux_resume): Refactor as methods of i386_linux_nat_target. (_initialize_i386_linux_nat): Adjust. Set linux_target. * inf-child.c (inf_child_ops): Delete. (inf_child_fetch_inferior_registers) (inf_child_store_inferior_registers): Delete. (inf_child_post_attach, inf_child_prepare_to_store): Refactor as methods of inf_child_target. (inf_child_target::supports_terminal_ours) (inf_child_target::terminal_init) (inf_child_target::terminal_inferior) (inf_child_target::terminal_ours_for_output) (inf_child_target::terminal_ours, inf_child_target::interrupt) (inf_child_target::pass_ctrlc, inf_child_target::terminal_info): New. (inf_child_open, inf_child_disconnect, inf_child_close) (inf_child_mourn_inferior, inf_child_maybe_unpush_target) (inf_child_post_startup_inferior, inf_child_can_run) (inf_child_pid_to_exec_file): Refactor as methods of inf_child_target. (inf_child_follow_fork): Delete. (inf_child_target::can_create_inferior) (inf_child_target::can_attach): New. (inf_child_target::has_all_memory, inf_child_target::has_memory) (inf_child_target::has_stack, inf_child_target::has_registers) (inf_child_target::has_execution): New. (inf_child_fileio_open, inf_child_fileio_pwrite) (inf_child_fileio_pread, inf_child_fileio_fstat) (inf_child_fileio_close, inf_child_fileio_unlink) (inf_child_fileio_readlink, inf_child_use_agent) (inf_child_can_use_agent): Refactor as methods of inf_child_target. (return_zero, inf_child_target): Delete. (inf_child_target::inf_child_target): New. * inf-child.h: Include "target.h". (inf_child_target): Delete function prototype. (inf_child_target): New class. (inf_child_open_target, inf_child_mourn_inferior) (inf_child_maybe_unpush_target): Delete. * inf-ptrace.c (inf_ptrace_target::~inf_ptrace_target): New. (inf_ptrace_follow_fork, inf_ptrace_insert_fork_catchpoint) (inf_ptrace_remove_fork_catchpoint, inf_ptrace_create_inferior) (inf_ptrace_post_startup_inferior, inf_ptrace_mourn_inferior) (inf_ptrace_attach, inf_ptrace_post_attach, inf_ptrace_detach) (inf_ptrace_detach_success, inf_ptrace_kill, inf_ptrace_resume) (inf_ptrace_wait, inf_ptrace_xfer_partial) (inf_ptrace_thread_alive, inf_ptrace_files_info) (inf_ptrace_pid_to_str, inf_ptrace_auxv_parse): Refactor as methods of inf_ptrace_target. (inf_ptrace_target): Delete function. * inf-ptrace.h: Include "inf-child.h". (inf_ptrace_target): Delete function declaration. (inf_ptrace_target): New class. (inf_ptrace_trad_target, inf_ptrace_detach_success): Delete. * linux-nat.c (linux_target): New. (linux_ops, linux_ops_saved, super_xfer_partial): Delete. (linux_nat_target::~linux_nat_target): New. (linux_child_post_attach, linux_child_post_startup_inferior) (linux_child_follow_fork, linux_child_insert_fork_catchpoint) (linux_child_remove_fork_catchpoint) (linux_child_insert_vfork_catchpoint) (linux_child_remove_vfork_catchpoint) (linux_child_insert_exec_catchpoint) (linux_child_remove_exec_catchpoint) (linux_child_set_syscall_catchpoint, linux_nat_pass_signals) (linux_nat_create_inferior, linux_nat_attach, linux_nat_detach) (linux_nat_resume, linux_nat_stopped_by_watchpoint) (linux_nat_stopped_data_address) (linux_nat_stopped_by_sw_breakpoint) (linux_nat_supports_stopped_by_sw_breakpoint) (linux_nat_stopped_by_hw_breakpoint) (linux_nat_supports_stopped_by_hw_breakpoint, linux_nat_wait) (linux_nat_kill, linux_nat_mourn_inferior) (linux_nat_xfer_partial, linux_nat_thread_alive) (linux_nat_update_thread_list, linux_nat_pid_to_str) (linux_nat_thread_name, linux_child_pid_to_exec_file) (linux_child_static_tracepoint_markers_by_strid) (linux_nat_is_async_p, linux_nat_can_async_p) (linux_nat_supports_non_stop, linux_nat_always_non_stop_p) (linux_nat_supports_multi_process) (linux_nat_supports_disable_randomization, linux_nat_async) (linux_nat_stop, linux_nat_close, linux_nat_thread_address_space) (linux_nat_core_of_thread, linux_nat_filesystem_is_local) (linux_nat_fileio_open, linux_nat_fileio_readlink) (linux_nat_fileio_unlink, linux_nat_thread_events): Refactor as methods of linux_nat_target. (linux_nat_wait_1, linux_xfer_siginfo, linux_proc_xfer_partial) (linux_proc_xfer_spu, linux_nat_xfer_osdata): Remove target_ops parameter. (check_stopped_by_watchpoint): Adjust. (linux_xfer_partial): Delete. (linux_target_install_ops, linux_target, linux_nat_add_target): Delete. (linux_nat_target::linux_nat_target): New. * linux-nat.h: Include "inf-ptrace.h". (linux_nat_target): New. (linux_target, linux_target_install_ops, linux_nat_add_target): Delete function declarations. (linux_target): Declare global. * linux-thread-db.c (thread_db_target): New. (thread_db_target::thread_db_target): New. (thread_db_ops): Delete. (the_thread_db_target): New. (thread_db_detach, thread_db_wait, thread_db_mourn_inferior) (thread_db_update_thread_list, thread_db_pid_to_str) (thread_db_extra_thread_info) (thread_db_thread_handle_to_thread_info) (thread_db_get_thread_local_address, thread_db_get_ada_task_ptid) (thread_db_resume): Refactor as methods of thread_db_target. (init_thread_db_ops): Delete. (_initialize_thread_db): Remove reference to init_thread_db_ops. * x86-linux-nat.c: Don't include "linux-nat.h". (super_post_startup_inferior): Delete. (x86_linux_nat_target::~x86_linux_nat_target): New. (x86_linux_child_post_startup_inferior) (x86_linux_read_description, x86_linux_enable_btrace) (x86_linux_disable_btrace, x86_linux_teardown_btrace) (x86_linux_read_btrace, x86_linux_btrace_conf): Refactor as methods of x86_linux_nat_target. (x86_linux_create_target): Delete. Bits folded ... (x86_linux_add_target): ... here. Now takes a linux_nat_target pointer. * x86-linux-nat.h: Include "linux-nat.h" and "x86-nat.h". (x86_linux_nat_target): New class. (x86_linux_create_target): Delete. (x86_linux_add_target): Now takes a linux_nat_target pointer. * x86-nat.c (x86_insert_watchpoint, x86_remove_watchpoint) (x86_region_ok_for_watchpoint, x86_stopped_data_address) (x86_stopped_by_watchpoint, x86_insert_hw_breakpoint) (x86_remove_hw_breakpoint, x86_can_use_hw_breakpoint) (x86_stopped_by_hw_breakpoint): Remove target_ops parameter and make extern. (x86_use_watchpoints): Delete. * x86-nat.h: Include "breakpoint.h" and "target.h". (x86_use_watchpoints): Delete. (x86_can_use_hw_breakpoint, x86_region_ok_for_hw_watchpoint) (x86_stopped_by_watchpoint, x86_stopped_data_address) (x86_insert_watchpoint, x86_remove_watchpoint) (x86_insert_hw_breakpoint, x86_remove_hw_breakpoint) (x86_stopped_by_hw_breakpoint): New declarations. (x86_nat_target): New template class. * ppc-linux-nat.c (ppc_linux_nat_target): New class. (the_ppc_linux_nat_target): New. (ppc_linux_fetch_inferior_registers) (ppc_linux_can_use_hw_breakpoint) (ppc_linux_region_ok_for_hw_watchpoint) (ppc_linux_ranged_break_num_registers) (ppc_linux_insert_hw_breakpoint, ppc_linux_remove_hw_breakpoint) (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_can_accel_watchpoint_condition) (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint) (ppc_linux_stopped_data_address, ppc_linux_stopped_by_watchpoint) (ppc_linux_watchpoint_addr_within_range) (ppc_linux_masked_watch_num_registers) (ppc_linux_store_inferior_registers, ppc_linux_auxv_parse) (ppc_linux_read_description): Refactor as methods of ppc_linux_nat_target. (_initialize_ppc_linux_nat): Adjust. Set linux_target. * procfs.c (procfs_xfer_partial): Delete forward declaration. (procfs_target): New class. (the_procfs_target): New. (procfs_target): Delete function. (procfs_auxv_parse, procfs_attach, procfs_detach) (procfs_fetch_registers, procfs_store_registers, procfs_wait) (procfs_xfer_partial, procfs_resume, procfs_pass_signals) (procfs_files_info, procfs_kill_inferior, procfs_mourn_inferior) (procfs_create_inferior, procfs_update_thread_list) (procfs_thread_alive, procfs_pid_to_str) (procfs_can_use_hw_breakpoint, procfs_stopped_by_watchpoint) (procfs_stopped_data_address, procfs_insert_watchpoint) (procfs_remove_watchpoint, procfs_region_ok_for_hw_watchpoint) (proc_find_memory_regions, procfs_info_proc) (procfs_make_note_section): Refactor as methods of procfs_target. (_initialize_procfs): Adjust. * sol-thread.c (sol_thread_target): New class. (sol_thread_ops): Now a sol_thread_target. (sol_thread_detach, sol_thread_resume, sol_thread_wait) (sol_thread_fetch_registers, sol_thread_store_registers) (sol_thread_xfer_partial, sol_thread_mourn_inferior) (sol_thread_alive, solaris_pid_to_str, sol_update_thread_list) (sol_get_ada_task_ptid): Refactor as methods of sol_thread_target. (init_sol_thread_ops): Delete. (_initialize_sol_thread): Adjust. Remove references to init_sol_thread_ops and complete_target_initialization. * windows-nat.c (windows_nat_target): New class. (windows_fetch_inferior_registers) (windows_store_inferior_registers, windows_resume, windows_wait) (windows_attach, windows_detach, windows_pid_to_exec_file) (windows_files_info, windows_create_inferior) (windows_mourn_inferior, windows_interrupt, windows_kill_inferior) (windows_close, windows_pid_to_str, windows_xfer_partial) (windows_get_tib_address, windows_get_ada_task_ptid) (windows_thread_name, windows_thread_alive): Refactor as windows_nat_target methods. (do_initial_windows_stuff): Adjust. (windows_target): Delete function. (_initialize_windows_nat): Adjust. * darwin-nat.c (darwin_resume, darwin_wait_to, darwin_interrupt) (darwin_mourn_inferior, darwin_kill_inferior) (darwin_create_inferior, darwin_attach, darwin_detach) (darwin_pid_to_str, darwin_thread_alive, darwin_xfer_partial) (darwin_pid_to_exec_file, darwin_get_ada_task_ptid) (darwin_supports_multi_process): Refactor as darwin_nat_target methods. (darwin_resume_to, darwin_files_info): Delete. (_initialize_darwin_inferior): Rename to ... (_initialize_darwin_nat): ... this. Adjust to C++ification. * darwin-nat.h: Include "inf-child.h". (darwin_nat_target): New class. (darwin_complete_target): Delete. * i386-darwin-nat.c (i386_darwin_nat_target): New class. (darwin_target): New. (i386_darwin_fetch_inferior_registers) (i386_darwin_store_inferior_registers): Refactor as methods of darwin_nat_target. (darwin_complete_target): Delete, with ... (_initialize_i386_darwin_nat): ... bits factored out here. * alpha-linux-nat.c (alpha_linux_nat_target): New class. (the_alpha_linux_nat_target): New. (alpha_linux_register_u_offset): Refactor as alpha_linux_nat_target method. (_initialize_alpha_linux_nat): Adjust. * linux-nat-trad.c (inf_ptrace_register_u_offset): Delete. (inf_ptrace_fetch_register, inf_ptrace_fetch_registers) (inf_ptrace_store_register, inf_ptrace_store_registers): Refact as methods of linux_nat_trad_target. (linux_trad_target): Delete. * linux-nat-trad.h (linux_trad_target): Delete function. (linux_nat_trad_target): New class. * mips-linux-nat.c (mips_linux_nat_target): New class. (super_fetch_registers, super_store_registers, super_close): Delete. (the_mips_linux_nat_target): New. (mips64_linux_regsets_fetch_registers) (mips64_linux_regsets_store_registers) (mips64_linux_fetch_registers, mips64_linux_store_registers) (mips_linux_register_u_offset, mips_linux_read_description) (mips_linux_can_use_hw_breakpoint) (mips_linux_stopped_by_watchpoint) (mips_linux_stopped_data_address) (mips_linux_region_ok_for_hw_watchpoint) (mips_linux_insert_watchpoint, mips_linux_remove_watchpoint) (mips_linux_close): Refactor as methods of mips_linux_nat. (_initialize_mips_linux_nat): Adjust to C++ification. * aix-thread.c (aix_thread_target): New class. (aix_thread_ops): Now an aix_thread_target. (aix_thread_detach, aix_thread_resume, aix_thread_wait) (aix_thread_fetch_registers, aix_thread_store_registers) (aix_thread_xfer_partial, aix_thread_mourn_inferior) (aix_thread_thread_alive, aix_thread_pid_to_str) (aix_thread_extra_thread_info, aix_thread_get_ada_task_ptid): Refactor as methods of aix_thread_target. (init_aix_thread_ops): Delete. (_initialize_aix_thread): Remove references to init_aix_thread_ops and complete_target_initialization. * rs6000-nat.c (rs6000_xfer_shared_libraries): Delete. (rs6000_nat_target): New class. (the_rs6000_nat_target): New. (rs6000_fetch_inferior_registers, rs6000_store_inferior_registers) (rs6000_xfer_partial, rs6000_wait, rs6000_create_inferior) (rs6000_xfer_shared_libraries): Refactor as rs6000_nat_target methods. (super_create_inferior): Delete. (_initialize_rs6000_nat): Adjust to C++ification. * arm-linux-nat.c (arm_linux_nat_target): New class. (the_arm_linux_nat_target): New. (arm_linux_fetch_inferior_registers) (arm_linux_store_inferior_registers, arm_linux_read_description) (arm_linux_can_use_hw_breakpoint, arm_linux_insert_hw_breakpoint) (arm_linux_remove_hw_breakpoint) (arm_linux_region_ok_for_hw_watchpoint) (arm_linux_insert_watchpoint, arm_linux_remove_watchpoint) (arm_linux_stopped_data_address, arm_linux_stopped_by_watchpoint) (arm_linux_watchpoint_addr_within_range): Refactor as methods of arm_linux_nat_target. (_initialize_arm_linux_nat): Adjust to C++ification. * aarch64-linux-nat.c (aarch64_linux_nat_target): New class. (the_aarch64_linux_nat_target): New. (aarch64_linux_fetch_inferior_registers) (aarch64_linux_store_inferior_registers) (aarch64_linux_child_post_startup_inferior) (aarch64_linux_read_description) (aarch64_linux_can_use_hw_breakpoint) (aarch64_linux_insert_hw_breakpoint) (aarch64_linux_remove_hw_breakpoint) (aarch64_linux_insert_watchpoint, aarch64_linux_remove_watchpoint) (aarch64_linux_region_ok_for_hw_watchpoint) (aarch64_linux_stopped_data_address) (aarch64_linux_stopped_by_watchpoint) (aarch64_linux_watchpoint_addr_within_range) (aarch64_linux_can_do_single_step): Refactor as methods of aarch64_linux_nat_target. (super_post_startup_inferior): Delete. (_initialize_aarch64_linux_nat): Adjust to C++ification. * hppa-linux-nat.c (hppa_linux_nat_target): New class. (the_hppa_linux_nat_target): New. (hppa_linux_fetch_inferior_registers) (hppa_linux_store_inferior_registers): Refactor as methods of hppa_linux_nat_target. (_initialize_hppa_linux_nat): Adjust to C++ification. * ia64-linux-nat.c (ia64_linux_nat_target): New class. (the_ia64_linux_nat_target): New. (ia64_linux_insert_watchpoint, ia64_linux_remove_watchpoint) (ia64_linux_stopped_data_address) (ia64_linux_stopped_by_watchpoint, ia64_linux_fetch_registers) (ia64_linux_store_registers, ia64_linux_xfer_partial): Refactor as ia64_linux_nat_target methods. (super_xfer_partial): Delete. (_initialize_ia64_linux_nat): Adjust to C++ification. * m32r-linux-nat.c (m32r_linux_nat_target): New class. (the_m32r_linux_nat_target): New. (m32r_linux_fetch_inferior_registers) (m32r_linux_store_inferior_registers): Refactor as m32r_linux_nat_target methods. (_initialize_m32r_linux_nat): Adjust to C++ification. * m68k-linux-nat.c (m68k_linux_nat_target): New class. (the_m68k_linux_nat_target): New. (m68k_linux_fetch_inferior_registers) (m68k_linux_store_inferior_registers): Refactor as m68k_linux_nat_target methods. (_initialize_m68k_linux_nat): Adjust to C++ification. * s390-linux-nat.c (s390_linux_nat_target): New class. (the_s390_linux_nat_target): New. (s390_linux_fetch_inferior_registers) (s390_linux_store_inferior_registers, s390_stopped_by_watchpoint) (s390_insert_watchpoint, s390_remove_watchpoint) (s390_can_use_hw_breakpoint, s390_insert_hw_breakpoint) (s390_remove_hw_breakpoint, s390_region_ok_for_hw_watchpoint) (s390_auxv_parse, s390_read_description): Refactor as methods of s390_linux_nat_target. (_initialize_s390_nat): Adjust to C++ification. * sparc-linux-nat.c (sparc_linux_nat_target): New class. (the_sparc_linux_nat_target): New. (_initialize_sparc_linux_nat): Adjust to C++ification. * sparc-nat.c (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc64-linux-nat.c (sparc64_linux_nat_target): New class. (the_sparc64_linux_nat_target): New. (_initialize_sparc64_linux_nat): Adjust to C++ification. * spu-linux-nat.c (spu_linux_nat_target): New class. (the_spu_linux_nat_target): New. (spu_child_post_startup_inferior, spu_child_post_attach) (spu_child_wait, spu_fetch_inferior_registers) (spu_store_inferior_registers, spu_xfer_partial) (spu_can_use_hw_breakpoint): Refactor as spu_linux_nat_target methods. (_initialize_spu_nat): Adjust to C++ification. * tilegx-linux-nat.c (tilegx_linux_nat_target): New class. (the_tilegx_linux_nat_target): New. (fetch_inferior_registers, store_inferior_registers): Refactor as methods. (_initialize_tile_linux_nat): Adjust to C++ification. * xtensa-linux-nat.c (xtensa_linux_nat_target): New class. (the_xtensa_linux_nat_target): New. (xtensa_linux_fetch_inferior_registers) (xtensa_linux_store_inferior_registers): Refactor as xtensa_linux_nat_target methods. (_initialize_xtensa_linux_nat): Adjust to C++ification. * fbsd-nat.c (USE_SIGTRAP_SIGINFO): Delete. (fbsd_pid_to_exec_file, fbsd_find_memory_regions) (fbsd_find_memory_regions, fbsd_info_proc, fbsd_xfer_partial) (fbsd_thread_alive, fbsd_pid_to_str, fbsd_thread_name) (fbsd_update_thread_list, fbsd_resume, fbsd_wait) (fbsd_stopped_by_sw_breakpoint) (fbsd_supports_stopped_by_sw_breakpoint, fbsd_follow_fork) (fbsd_insert_fork_catchpoint, fbsd_remove_fork_catchpoint) (fbsd_insert_vfork_catchpoint, fbsd_remove_vfork_catchpoint) (fbsd_post_startup_inferior, fbsd_post_attach) (fbsd_insert_exec_catchpoint, fbsd_remove_exec_catchpoint) (fbsd_set_syscall_catchpoint) (super_xfer_partial, super_resume, super_wait) (fbsd_supports_stopped_by_hw_breakpoint): Delete. (fbsd_handle_debug_trap): Remove target_ops parameter. (fbsd_nat_add_target): Delete. * fbsd-nat.h: Include "inf-ptrace.h". (fbsd_nat_add_target): Delete. (USE_SIGTRAP_SIGINFO): Define. (fbsd_nat_target): New class. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers) (amd64bsd_store_inferior_registers): Remove target_ops parameter. (amd64bsd_target): Delete. * amd64-bsd-nat.h: New file. * amd64-fbsd-nat.c: Include "amd64-bsd-nat.h" instead of "x86-bsd-nat.h". (amd64_fbsd_nat_target): New class. (the_amd64_fbsd_nat_target): New. (amd64fbsd_read_description): Refactor as method of amd64_fbsd_nat_target. (amd64_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_amd64fbsd_nat): Adjust to C++ification. * amd64-nat.h (amd64bsd_target): Delete function declaration. * i386-bsd-nat.c (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Remove target_ops parameter. (i386bsd_target): Delete. * i386-bsd-nat.h (i386bsd_target): Delete function declaration. (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Declare. (i386_bsd_nat_target): New class. * i386-fbsd-nat.c (i386_fbsd_nat_target): New class. (the_i386_fbsd_nat_target): New. (i386fbsd_resume, i386fbsd_read_description): Refactor as i386_fbsd_nat_target methods. (i386_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_i386fbsd_nat): Adjust to C++ification. * x86-bsd-nat.c (super_mourn_inferior): Delete. (x86bsd_mourn_inferior, x86bsd_target): Delete. (_initialize_x86_bsd_nat): Adjust to C++ification. * x86-bsd-nat.h: Include "x86-nat.h". (x86bsd_target): Delete declaration. (x86bsd_nat_target): New class. * aarch64-fbsd-nat.c (aarch64_fbsd_nat_target): New class. (the_aarch64_fbsd_nat_target): New. (aarch64_fbsd_fetch_inferior_registers) (aarch64_fbsd_store_inferior_registers): Refactor as methods of aarch64_fbsd_nat_target. (_initialize_aarch64_fbsd_nat): Adjust to C++ification. * alpha-bsd-nat.c (alpha_bsd_nat_target): New class. (the_alpha_bsd_nat_target): New. (alphabsd_fetch_inferior_registers) (alphabsd_store_inferior_registers): Refactor as alpha_bsd_nat_target methods. (_initialize_alphabsd_nat): Refactor as methods of alpha_bsd_nat_target. * amd64-nbsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_nbsd_nat_target): New. (_initialize_amd64nbsd_nat): Adjust to C++ification. * amd64-obsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_obsd_nat_target): New. (_initialize_amd64obsd_nat): Adjust to C++ification. * arm-fbsd-nat.c (arm_fbsd_nat_target): New. (the_arm_fbsd_nat_target): New. (arm_fbsd_fetch_inferior_registers) (arm_fbsd_store_inferior_registers, arm_fbsd_read_description): (_initialize_arm_fbsd_nat): Refactor as methods of arm_fbsd_nat_target. (_initialize_arm_fbsd_nat): Adjust to C++ification. * arm-nbsd-nat.c (arm_netbsd_nat_target): New class. (the_arm_netbsd_nat_target): New. (armnbsd_fetch_registers, armnbsd_store_registers): Refactor as arm_netbsd_nat_target. (_initialize_arm_netbsd_nat): Adjust to C++ification. * hppa-nbsd-nat.c (hppa_nbsd_nat_target): New class. (the_hppa_nbsd_nat_target): New. (hppanbsd_fetch_registers, hppanbsd_store_registers): Refactor as hppa_nbsd_nat_target methods. (_initialize_hppanbsd_nat): Adjust to C++ification. * hppa-obsd-nat.c (hppa_obsd_nat_target): New class. (the_hppa_obsd_nat_target): New. (hppaobsd_fetch_registers, hppaobsd_store_registers): Refactor as methods of hppa_obsd_nat_target. (_initialize_hppaobsd_nat): Adjust to C++ification. Use add_target. * i386-nbsd-nat.c (the_i386_nbsd_nat_target): New. (_initialize_i386nbsd_nat): Adjust to C++ification. Use add_target. * i386-obsd-nat.c (the_i386_obsd_nat_target): New. (_initialize_i386obsd_nat): Use add_target. * m68k-bsd-nat.c (m68k_bsd_nat_target): New class. (the_m68k_bsd_nat_target): New. (m68kbsd_fetch_inferior_registers) (m68kbsd_store_inferior_registers): Refactor as methods of m68k_bsd_nat_target. (_initialize_m68kbsd_nat): Adjust to C++ification. * mips-fbsd-nat.c (mips_fbsd_nat_target): New class. (the_mips_fbsd_nat_target): New. (mips_fbsd_fetch_inferior_registers) (mips_fbsd_store_inferior_registers): Refactor as methods of mips_fbsd_nat_target. (_initialize_mips_fbsd_nat): Adjust to C++ification. Use add_target. * mips-nbsd-nat.c (mips_nbsd_nat_target): New class. (the_mips_nbsd_nat_target): New. (mipsnbsd_fetch_inferior_registers) (mipsnbsd_store_inferior_registers): Refactor as methods of mips_nbsd_nat_target. (_initialize_mipsnbsd_nat): Adjust to C++ification. * mips64-obsd-nat.c (mips64_obsd_nat_target): New class. (the_mips64_obsd_nat_target): New. (mips64obsd_fetch_inferior_registers) (mips64obsd_store_inferior_registers): Refactor as methods of mips64_obsd_nat_target. (_initialize_mips64obsd_nat): Adjust to C++ification. Use add_target. * nbsd-nat.c (nbsd_pid_to_exec_file): Refactor as method of nbsd_nat_target. * nbsd-nat.h: Include "inf-ptrace.h". (nbsd_nat_target): New class. * obsd-nat.c (obsd_pid_to_str, obsd_update_thread_list) (obsd_wait): Refactor as methods of obsd_nat_target. (obsd_add_target): Delete. * obsd-nat.h: Include "inf-ptrace.h". (obsd_nat_target): New class. * ppc-fbsd-nat.c (ppc_fbsd_nat_target): New class. (the_ppc_fbsd_nat_target): New. (ppcfbsd_fetch_inferior_registers) (ppcfbsd_store_inferior_registers): Refactor as methods of ppc_fbsd_nat_target. (_initialize_ppcfbsd_nat): Adjust to C++ification. Use add_target. * ppc-nbsd-nat.c (ppc_nbsd_nat_target): New class. (the_ppc_nbsd_nat_target): New. (ppcnbsd_fetch_inferior_registers) (ppcnbsd_store_inferior_registers): Refactor as methods of ppc_nbsd_nat_target. (_initialize_ppcnbsd_nat): Adjust to C++ification. * ppc-obsd-nat.c (ppc_obsd_nat_target): New class. (the_ppc_obsd_nat_target): New. (ppcobsd_fetch_registers, ppcobsd_store_registers): Refactor as methods of ppc_obsd_nat_target. (_initialize_ppcobsd_nat): Adjust to C++ification. Use add_target. * sh-nbsd-nat.c (sh_nbsd_nat_target): New class. (the_sh_nbsd_nat_target): New. (shnbsd_fetch_inferior_registers) (shnbsd_store_inferior_registers): Refactor as methods of sh_nbsd_nat_target. (_initialize_shnbsd_nat): Adjust to C++ification. * sparc-nat.c (sparc_xfer_wcookie): Make extern. (inf_ptrace_xfer_partial): Delete. (sparc_xfer_partial, sparc_target): Delete. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers, sparc_xfer_wcookie): Declare. (sparc_target): Delete function declaration. (sparc_target): New template class. * sparc-nbsd-nat.c (the_sparc_nbsd_nat_target): New. (_initialize_sparcnbsd_nat): Adjust to C++ification. * sparc64-fbsd-nat.c (the_sparc64_fbsd_nat_target): New. (_initialize_sparc64fbsd_nat): Adjust to C++ification. Use add_target. * sparc64-nbsd-nat.c (the_sparc64_nbsd_nat_target): New. (_initialize_sparc64nbsd_nat): Adjust to C++ification. * sparc64-obsd-nat.c (the_sparc64_obsd_nat_target): New. (_initialize_sparc64obsd_nat): Adjust to C++ification. Use add_target. * vax-bsd-nat.c (vax_bsd_nat_target): New class. (the_vax_bsd_nat_target): New. (vaxbsd_fetch_inferior_registers) (vaxbsd_store_inferior_registers): Refactor as vax_bsd_nat_target methods. (_initialize_vaxbsd_nat): Adjust to C++ification. * bsd-kvm.c (bsd_kvm_target): New class. (bsd_kvm_ops): Now a bsd_kvm_target. (bsd_kvm_open, bsd_kvm_close, bsd_kvm_xfer_partial) (bsd_kvm_files_info, bsd_kvm_fetch_registers) (bsd_kvm_thread_alive, bsd_kvm_pid_to_str): Refactor as methods of bsd_kvm_target. (bsd_kvm_return_one): Delete. (bsd_kvm_add_target): Adjust to C++ification. * nto-procfs.c (nto_procfs_target, nto_procfs_target_native) (nto_procfs_target_procfs): New classes. (procfs_open_1, procfs_thread_alive, procfs_update_thread_list) (procfs_files_info, procfs_pid_to_exec_file, procfs_attach) (procfs_post_attach, procfs_wait, procfs_fetch_registers) (procfs_xfer_partial, procfs_detach, procfs_insert_breakpoint) (procfs_remove_breakpoint, procfs_insert_hw_breakpoint) (procfs_remove_hw_breakpoint, procfs_resume) (procfs_mourn_inferior, procfs_create_inferior, procfs_interrupt) (procfs_kill_inferior, procfs_store_registers) (procfs_pass_signals, procfs_pid_to_str, procfs_can_run): Refactor as methods of nto_procfs_target. (nto_procfs_ops): Now an nto_procfs_target_procfs. (nto_native_ops): Delete. (procfs_open, procfs_native_open): Delete. (nto_native_ops): Now an nto_procfs_target_native. (init_procfs_targets): Adjust to C++ification. (procfs_can_use_hw_breakpoint, procfs_remove_hw_watchpoint) (procfs_insert_hw_watchpoint, procfs_stopped_by_watchpoint): Refactor as methods of nto_procfs_target. * go32-nat.c (go32_nat_target): New class. (the_go32_nat_target): New. (go32_attach, go32_resume, go32_wait, go32_fetch_registers) (go32_store_registers, go32_xfer_partial, go32_files_info) (go32_kill_inferior, go32_create_inferior, go32_mourn_inferior) (go32_terminal_init, go32_terminal_info, go32_terminal_inferior) (go32_terminal_ours, go32_pass_ctrlc, go32_thread_alive) (go32_pid_to_str): Refactor as methods of go32_nat_target. (go32_target): Delete. (_initialize_go32_nat): Adjust to C++ification. * gnu-nat.c (gnu_wait, gnu_resume, gnu_kill_inferior) (gnu_mourn_inferior, gnu_create_inferior, gnu_attach, gnu_detach) (gnu_stop, gnu_thread_alive, gnu_xfer_partial) (gnu_find_memory_regions, gnu_pid_to_str): Refactor as methods of gnu_nat_target. (gnu_target): Delete. * gnu-nat.h (gnu_target): Delete. (gnu_nat_target): New class. * i386-gnu-nat.c (gnu_base_target): New. (i386_gnu_nat_target): New class. (the_i386_gnu_nat_target): New. (_initialize_i386gnu_nat): Adjust to C++ification. gdb/testsuite/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * gdb.base/breakpoint-in-ro-region.exp: Adjust to to_resume and to_log_command renames. * gdb.base/sss-bp-on-user-bp-2.exp: Likewise.
2018-05-03 07:37:22 +08:00
ppc_linux_nat_target::watchpoint_addr_within_range (CORE_ADDR addr,
CORE_ADDR start,
int length)
{
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
gdb_assert (!m_dreg_interface.unavailable_p ());
int mask;
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
if (m_dreg_interface.hwdebug_p ()
&& linux_get_hwcap (current_top_target ()) & PPC_FEATURE_BOOKE)
2010-04-22 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * ppc-linux-nat.c (PTRACE_GET_DEBUGREG): Update comment. (PPC_PTRACE_GETWDBGINFO, PPC_PTRACE_SETHWDEBUG, PPC_PTRACE_DELHWDEBUG, ppc_debug_info, PPC_DEBUG_FEATURE_INSN_BP_RANGE, PPC_DEBUG_FEATURE_INSN_BP_MASK, PPC_DEBUG_FEATURE_DATA_BP_RANGE, PPC_DEBUG_FEATURE_DATA_BP_MASK, ppc_hw_breakpoint, PPC_BREAKPOINT_TRIGGER_EXECUTE, PPC_BREAKPOINT_TRIGGER READ, PPC_BREAKPOINT_TRIGGER_WRITE, PPC_BREAKPOINT_TRIGGER_RW, PPC_BREAKPOINT_MODE_EXACT PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE, PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE, PPC_BREAKPOINT_MODE_MASK, PPC_BREAKPOINT_CONDITION_NONE, PPC_BREAKPOINT_CONDITION_AND, PPC_BREAKPOINT_CONDITION_EXACT, PPC_BREAKPOINT_CONDITION_OR, PPC_BREAKPOINT_CONDITION_AND_OR, PPC_BREAKPOINT_CONDITION_BE_ALL, PPC_BREAKPOINT_CONDITION_BE_SHIFT, PPC_BREAKPOINT_CONDITION_BE): Define, in case <ptrace.h> doesn't provide it. (booke_debug_info): New variable. (max_slots_number): Ditto. (hw_break_tuple): New struct. (thread_points): Ditto. (ppc_threads): New variable. (PPC_DEBUG_CURRENT_VERSION): New define. (have_ptrace_new_debug_booke): New function. (ppc_linux_check_watch_resources): Renamed to ... (ppc_linux_can_use_hw_breakpoint): ... this. Handle BookE processors. (ppc_linux_region_ok_for_hw_watchpoint): Handle BookE processors. (booke_cmp_hw_point): New function. (booke_find_thread_points_by_tid): Ditto. (booke_insert_point): Ditto. (booke_remove_point): Ditto. (ppc_linux_insert_hw_breakpoint): Ditto. (ppc_linux_remove_hw_breakpoint): Ditto. (get_trigger_type): Ditto. (ppc_linux_insert_watchpoint): Handle BookE processors. (ppc_linux_remove_watchpoint): Ditto. (ppc_linux_new_thread): Ditto. (ppc_linux_thread_exit): New function.. (ppc_linux_stopped_data_address): Handle BookE processors. (ppc_linux_watchpoint_addr_within_range): Ditto. (_initialize_ppc_linux_nat): Initialize to_insert_hw_breakpoint and to_remove_hw_breakpoint fields of the target operations struct. Add observe for the thread_exit event.
2010-04-23 06:26:36 +08:00
return start <= addr && start + length >= addr;
else if (linux_get_hwcap (current_top_target ()) & PPC_FEATURE_BOOKE)
mask = 3;
else
mask = 7;
addr &= ~mask;
/* Check whether [start, start+length-1] intersects [addr, addr+mask]. */
return start <= addr + mask && start + length - 1 >= addr;
}
2011-05-06 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Implement support for PowerPC BookE masked watchpoints. gdb/ * NEWS: Mention masked watchpoint support. Create "Changed commands" section. * breakpoint.h (struct breakpoint_ops) <works_in_software_mode>: New method. Initialize to NULL in all existing breakpoint_ops instances. (struct breakpoint) <hw_wp_mask>: New field. * breakpoint.c (is_masked_watchpoint): Add prototype. (update_watchpoint): Don't set b->val for masked watchpoints. Call breakpoint's breakpoint_ops.works_in_software_mode if available. (watchpoints_triggered): Handle the case of a hardware masked watchpoint trigger. (watchpoint_check): Likewise. (works_in_software_mode_watchpoint): New function. (insert_masked_watchpoint, remove_masked_watchpoint) (resources_needed_masked_watchpoint) (works_in_software_mode_masked_watchpoint, print_it_masked_watchpoint) (print_one_detail_masked_watchpoint, print_mention_masked_watchpoint) (print_recreate_masked_watchpoint, is_masked_watchpoint): New functions. (masked_watchpoint_breakpoint_ops): New structure. (watch_command_1): Check for the existence of the `mask' parameter. Set b->ops according to the type of hardware watchpoint being created. * ppc-linux-nat.c (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_masked_watch_num_registers): New functions. (_initialize_ppc_linux_nat): Initialize to_insert_mask_watchpoint, to_remove_mask_watchpoint and to_masked_watch_num_registers. * target.c (update_current_target): Mention to_insert_mask_watchpoint, to_remove_mask_watchpoint, and to_masked_watch_num_registers. (target_insert_mask_watchpoint, target_remove_mask_watchpoint) (target_masked_watch_num_registers): New functions. * target.h (struct target_ops) <to_insert_mask_watchpoint>, <to_remove_mask_watchpoint>, <to_masked_watch_num_registers>: New methods. (target_insert_mask_watchpoint, target_remove_mask_watchpoint) (target_masked_watch_num_registers): Add prototypes. gdb/doc/ * gdb.texinfo (Set Watchpoints): Document mask parameter. (PowerPC Embedded): Mention support of masked watchpoints.
2011-05-07 02:46:33 +08:00
/* Return the number of registers needed for a masked hardware watchpoint. */
Convert struct target_ops to C++ I.e., use C++ virtual methods and inheritance instead of tables of function pointers. Unfortunately, there's no way to do a smooth transition. ALL native targets in the tree must be converted at the same time. I've tested all I could with cross compilers and with help from GCC compile farm, but naturally I haven't been able to test many of the ports. Still, I made a best effort to port everything over, and while I expect some build problems due to typos and such, which should be trivial to fix, I don't expect any design problems. * Implementation notes: - The flattened current_target is gone. References to current_target or current_target.beneath are replaced with references to target_stack (the top of the stack) directly. - To keep "set debug target" working, this adds a new debug_stratum layer that sits on top of the stack, prints the debug, and delegates to the target beneath. In addition, this makes the shortname and longname properties of target_ops be virtual methods instead of data fields, and makes the debug target defer those to the target beneath. This is so that debug code sprinkled around that does "if (debugtarget) ..." can transparently print the name of the target beneath. A patch later in the series actually splits out the shortname/longname methods to a separate structure, but I preferred to keep that chance separate as it is associated with changing a bit the design of how targets are registered and open. - Since you can't check whether a C++ virtual method is overridden, the old method of checking whether a target_ops implements a method by comparing the function pointer must be replaced with something else. Some cases are fixed by adding a parallel "can_do_foo" target_ops methods. E.g.,: + for (t = target_stack; t != NULL; t = t->beneath) { - if (t->to_create_inferior != NULL) + if (t->can_create_inferior ()) break; } Others are fixed by changing void return type to bool or int return type, and have the default implementation return false or -1, to indicate lack of support. - make-target-delegates was adjusted to generate C++ classes and methods. It needed tweaks to grok "virtual" in front of the target method name, and for the fact that methods are no longer function pointers. (In particular, the current code parsing the return type was simple because it could simply parse up until the '(' in '(*to_foo)'. It now generates a couple C++ classes that inherit target_ops: dummy_target and debug_target. Since we need to generate the class declarations as well, i.e., we need to emit methods twice, we now generate the code in two passes. - The core_target global is renamed to avoid conflict with the "core_target" class. - ctf/tfile targets init_tracefile_ops is replaced by a base class that is inherited by both ctf and tfile. - bsd-uthread The bsd_uthread_ops_hack hack is gone. It's not needed because nothing was extending a target created by bsd_uthread_target. - remote/extended-remote targets This is a first pass, just enough to C++ify target_ops. A later pass will convert more free functions to methods, and make remote_state be truly per remote instance, allowing multiple simultaneous instances of remote targets. - inf-child/"native" is converted to an actual base class (inf_child_target), that is inherited by all native targets. - GNU/Linux The old weird double-target linux_ops mechanism in linux-nat.c, is gone, replaced by adding a few virtual methods to linux-nat.h's target_ops, called low_XXX, that the concrete linux-nat implementations override. Sort of like gdbserver's linux_target_ops, but simpler, for requiring only one target_ops-like hierarchy, which spares implementing the same method twice when we need to forward the method to a low implementation. The low target simply reimplements the target_ops method directly in that case. There are a few remaining linux-nat.c hooks that would be better converted to low_ methods like above too. E.g.: linux_nat_set_new_thread (t, x86_linux_new_thread); linux_nat_set_new_fork (t, x86_linux_new_fork); linux_nat_set_forget_process That'll be done in a follow up patch. - We can no longer use functions like x86_use_watchpoints to install custom methods on an arbitrary base target. The patch replaces instances of such a pattern with template mixins. For example memory_breakpoint_target defined in target.h, or x86_nat_target in x86-nat.h. - linux_trad_target, MIPS and Alpha GNU/Linux The code in the new linux-nat-trad.h/c files which was split off of inf-ptrace.h/c recently, is converted to a C++ base class, and used by the MIPS and Alpha GNU/Linux ports. - BSD targets The $architecture x NetBSD/OpenBSD/FreeBSD support matrix complicates things a bit. There's common BSD target code, and there's common architecture-specific code shared between the different BSDs. Currently, all that is stiched together to form a final target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target functions etc. This introduces new fbsd_nat_target, obsd_nat_target and nbsd_nat_target classes that serve as base/prototype target for the corresponding BSD variant. And introduces generic i386/AMD64 BSD targets, to be used as template mixin to build a final target. Similarly, a generic SPARC target is added, used by both BSD and Linux ports. - bsd_kvm_add_target, BSD libkvm target I considered making bsd_kvm_supply_pcb a virtual method, and then have each port inherit bsd_kvm_target and override that method, but that was resulting in lots of unjustified churn, so I left the function pointer mechanism alone. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> John Baldwin <jhb@freebsd.org> * target.h (enum strata) <debug_stratum>: New. (struct target_ops) <all delegation methods>: Replace by C++ virtual methods, and drop "to_" prefix. All references updated throughout. <to_shortname, to_longname, to_doc, to_data, to_have_steppable_watchpoint, to_have_continuable_watchpoint, to_has_thread_control, to_attach_no_wait>: Delete, replaced by virtual methods. All references updated throughout. <can_attach, supports_terminal_ours, can_create_inferior, get_thread_control_capabilities, attach_no_wait>: New virtual methods. <insert_breakpoint, remove_breakpoint>: Now TARGET_DEFAULT_NORETURN methods. <info_proc>: Now returns bool. <to_magic>: Delete. (OPS_MAGIC): Delete. (current_target): Delete. All references replaced by references to ... (target_stack): ... this. New. (target_shortname, target_longname): Adjust. (target_can_run): Now a function declaration. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (memory_breakpoint_target): New template class. (test_target_ops): Refactor as a C++ class with virtual methods. * make-target-delegates (NAME_PART): Tighten. (POINTER_PART, CP_SYMBOL): New. (SIMPLE_RETURN_PART): Reimplement. (VEC_RETURN_PART): Expect less. (RETURN_PART, VIRTUAL_PART): New. (METHOD): Adjust to C++ virtual methods. (scan_target_h): Remove reference to C99. (dname): Output "target_ops::" prefix. (write_function_header): Adjust to output a C++ class method. (write_declaration): New. (write_delegator): Adjust to output a C++ class method. (tdname): Output "dummy_target::" prefix. (write_tdefault, write_debugmethod): Adjust to output a C++ class method. (tdefault_names, debug_names): Delete. (return_types, tdefaults, styles, argtypes_array): New. (top level): All methods are delegators. (print_class): New. (top level): Print dummy_target and debug_target classes. * target-delegates.c: Regenerate. * target-debug.h (target_debug_print_enum_info_proc_what) (target_debug_print_thread_control_capabilities) (target_debug_print_thread_info_p): New. * target.c (dummy_target): Delete. (the_dummy_target, the_debug_target): New. (target_stack): Now extern. (set_targetdebug): Push/unpush debug target. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (add_target_with_completer): No longer call complete_target_initialization. (target_supports_terminal_ours): Use regular delegation. (update_current_target): Delete. (push_target): No longer check magic number. Don't call update_current_target. (unpush_target): Don't call update_current_target. (target_is_pushed): No longer check magic number. (target_require_runnable): Skip for all stratums over process_stratum. (target_ops::info_proc): New. (target_info_proc): Use find_target_at and find_default_run_target. (target_supports_disable_randomization): Use regular delegation. (target_get_osdata): Use find_target_at. (target_ops::open, target_ops::close, target_ops::can_attach) (target_ops::attach, target_ops::can_create_inferior) (target_ops::create_inferior, target_ops::can_run) (target_can_run): New. (default_fileio_target): Use regular delegation. (target_ops::fileio_open, target_ops::fileio_pwrite) (target_ops::fileio_pread, target_ops::fileio_fstat) (target_ops::fileio_close, target_ops::fileio_unlink) (target_ops::fileio_readlink): New. (target_fileio_open_1, target_fileio_unlink) (target_fileio_readlink): Always call the target method. Handle FILEIO_ENOSYS. (return_zero, return_zero_has_execution): Delete. (init_dummy_target): Delete. (dummy_target::dummy_target, dummy_target::shortname) (dummy_target::longname, dummy_target::doc) (debug_target::debug_target, debug_target::shortname) (debug_target::longname, debug_target::doc): New. (target_supports_delete_record): Use regular delegation. (setup_target_debug): Delete. (maintenance_print_target_stack): Skip debug_stratum. (initialize_targets): Instantiate the_dummy_target and the_debug_target. * auxv.c (target_auxv_parse): Remove 'ops' parameter. Adjust to use target_stack. (target_auxv_search, fprint_target_auxv): Adjust. (info_auxv_command): Adjust to use target_stack. * auxv.h (target_auxv_parse): Remove 'ops' parameter. * exceptions.c (print_flush): Handle a NULL target_stack. * regcache.c (target_ops_no_register): Refactor as class with virtual methods. * exec.c (exec_target): New class. (exec_ops): Now an exec_target. (exec_open, exec_close_1, exec_get_section_table) (exec_xfer_partial, exec_files_info, exec_has_memory) (exec_make_note_section): Refactor as exec_target methods. (exec_file_clear, ignore, exec_remove_breakpoint, init_exec_ops): Delete. (exec_target::find_memory_regions): New. (_initialize_exec): Don't call init_exec_ops. * gdbcore.h (exec_file_clear): Delete. * corefile.c (core_target): Delete. (core_file_command): Adjust. * corelow.c (core_target): New class. (the_core_target): New. (core_close): Remove target_ops parameter. (core_close_cleanup): Adjust. (core_target::close): New. (core_open, core_detach, get_core_registers, core_files_info) (core_xfer_partial, core_thread_alive, core_read_description) (core_pid_to_str, core_thread_name, core_has_memory) (core_has_stack, core_has_registers, core_info_proc): Rework as core_target methods. (ignore, core_remove_breakpoint, init_core_ops): Delete. (_initialize_corelow): Initialize the_core_target. * gdbcore.h (core_target): Delete. (the_core_target): New. * ctf.c: (ctf_target): New class. (ctf_ops): Now a ctf_target. (ctf_open, ctf_close, ctf_files_info, ctf_fetch_registers) (ctf_xfer_partial, ctf_get_trace_state_variable_value) (ctf_trace_find, ctf_traceframe_info): Refactor as ctf_target methods. (init_ctf_ops): Delete. (_initialize_ctf): Don't call it. * tracefile-tfile.c (tfile_target): New class. (tfile_ops): Now a tfile_target. (tfile_open, tfile_close, tfile_files_info) (tfile_get_tracepoint_status, tfile_trace_find) (tfile_fetch_registers, tfile_xfer_partial) (tfile_get_trace_state_variable_value, tfile_traceframe_info): Refactor as tfile_target methods. (tfile_xfer_partial_features): Remove target_ops parameter. (init_tfile_ops): Delete. (_initialize_tracefile_tfile): Don't call it. * tracefile.c (tracefile_has_all_memory, tracefile_has_memory) (tracefile_has_stack, tracefile_has_registers) (tracefile_thread_alive, tracefile_get_trace_status): Refactor as tracefile_target methods. (init_tracefile_ops): Delete. (tracefile_target::tracefile_target): New. * tracefile.h: Include "target.h". (tracefile_target): New class. (init_tracefile_ops): Delete. * spu-multiarch.c (spu_multiarch_target): New class. (spu_ops): Now a spu_multiarch_target. (spu_thread_architecture, spu_region_ok_for_hw_watchpoint) (spu_fetch_registers, spu_store_registers, spu_xfer_partial) (spu_search_memory, spu_mourn_inferior): Refactor as spu_multiarch_target methods. (init_spu_ops): Delete. (_initialize_spu_multiarch): Remove references to init_spu_ops, complete_target_initialization. * ravenscar-thread.c (ravenscar_thread_target): New class. (ravenscar_ops): Now a ravenscar_thread_target. (ravenscar_resume, ravenscar_wait, ravenscar_update_thread_list) (ravenscar_thread_alive, ravenscar_pid_to_str) (ravenscar_fetch_registers, ravenscar_store_registers) (ravenscar_prepare_to_store, ravenscar_stopped_by_sw_breakpoint) (ravenscar_stopped_by_hw_breakpoint) (ravenscar_stopped_by_watchpoint, ravenscar_stopped_data_address) (ravenscar_mourn_inferior, ravenscar_core_of_thread) (ravenscar_get_ada_task_ptid): Refactor as ravenscar_thread_target methods. (init_ravenscar_thread_ops): Delete. (_initialize_ravenscar): Remove references to init_ravenscar_thread_ops and complete_target_initialization. * bsd-uthread.c (bsd_uthread_ops_hack): Delete. (bsd_uthread_target): New class. (bsd_uthread_ops): Now a bsd_uthread_target. (bsd_uthread_activate): Adjust to refer to bsd_uthread_ops. (bsd_uthread_close, bsd_uthread_mourn_inferior) (bsd_uthread_fetch_registers, bsd_uthread_store_registers) (bsd_uthread_wait, bsd_uthread_resume, bsd_uthread_thread_alive) (bsd_uthread_update_thread_list, bsd_uthread_extra_thread_info) (bsd_uthread_pid_to_str): Refactor as bsd_uthread_target methods. (bsd_uthread_target): Delete function. (_initialize_bsd_uthread): Remove reference to complete_target_initialization. * bfd-target.c (target_bfd_data): Delete. Fields folded into ... (target_bfd): ... this new class. (target_bfd_xfer_partial, target_bfd_get_section_table) (target_bfd_close): Refactor as target_bfd methods. (target_bfd::~target_bfd): New. (target_bfd_reopen): Adjust. (target_bfd::close): New. * record-btrace.c (record_btrace_target): New class. (record_btrace_ops): Now a record_btrace_target. (record_btrace_open, record_btrace_stop_recording) (record_btrace_disconnect, record_btrace_close) (record_btrace_async, record_btrace_info) (record_btrace_insn_history, record_btrace_insn_history_range) (record_btrace_insn_history_from, record_btrace_call_history) (record_btrace_call_history_range) (record_btrace_call_history_from, record_btrace_record_method) (record_btrace_is_replaying, record_btrace_will_replay) (record_btrace_xfer_partial, record_btrace_insert_breakpoint) (record_btrace_remove_breakpoint, record_btrace_fetch_registers) (record_btrace_store_registers, record_btrace_prepare_to_store) (record_btrace_to_get_unwinder) (record_btrace_to_get_tailcall_unwinder, record_btrace_resume) (record_btrace_commit_resume, record_btrace_wait) (record_btrace_stop, record_btrace_can_execute_reverse) (record_btrace_stopped_by_sw_breakpoint) (record_btrace_supports_stopped_by_sw_breakpoint) (record_btrace_stopped_by_hw_breakpoint) (record_btrace_supports_stopped_by_hw_breakpoint) (record_btrace_update_thread_list, record_btrace_thread_alive) (record_btrace_goto_begin, record_btrace_goto_end) (record_btrace_goto, record_btrace_stop_replaying_all) (record_btrace_execution_direction) (record_btrace_prepare_to_generate_core) (record_btrace_done_generating_core): Refactor as record_btrace_target methods. (init_record_btrace_ops): Delete. (_initialize_record_btrace): Remove reference to init_record_btrace_ops. * record-full.c (RECORD_FULL_IS_REPLAY): Adjust to always refer to the execution_direction global. (record_full_base_target, record_full_target) (record_full_core_target): New classes. (record_full_ops): Now a record_full_target. (record_full_core_ops): Now a record_full_core_target. (record_full_target::detach, record_full_target::disconnect) (record_full_core_target::disconnect) (record_full_target::mourn_inferior, record_full_target::kill): New. (record_full_open, record_full_close, record_full_async): Refactor as methods of the record_full_base_target class. (record_full_resume, record_full_commit_resume): Refactor as methods of the record_full_target class. (record_full_wait, record_full_stopped_by_watchpoint) (record_full_stopped_data_address) (record_full_stopped_by_sw_breakpoint) (record_full_supports_stopped_by_sw_breakpoint) (record_full_stopped_by_hw_breakpoint) (record_full_supports_stopped_by_hw_breakpoint): Refactor as methods of the record_full_base_target class. (record_full_store_registers, record_full_xfer_partial) (record_full_insert_breakpoint, record_full_remove_breakpoint): Refactor as methods of the record_full_target class. (record_full_can_execute_reverse, record_full_get_bookmark) (record_full_goto_bookmark, record_full_execution_direction) (record_full_record_method, record_full_info, record_full_delete) (record_full_is_replaying, record_full_will_replay) (record_full_goto_begin, record_full_goto_end, record_full_goto) (record_full_stop_replaying): Refactor as methods of the record_full_base_target class. (record_full_core_resume, record_full_core_kill) (record_full_core_fetch_registers) (record_full_core_prepare_to_store) (record_full_core_store_registers, record_full_core_xfer_partial) (record_full_core_insert_breakpoint) (record_full_core_remove_breakpoint) (record_full_core_has_execution): Refactor as methods of the record_full_core_target class. (record_full_base_target::supports_delete_record): New. (init_record_full_ops): Delete. (init_record_full_core_ops): Delete. (record_full_save): Refactor as method of the record_full_base_target class. (_initialize_record_full): Remove references to init_record_full_ops and init_record_full_core_ops. * remote.c (remote_target, extended_remote_target): New classes. (remote_ops): Now a remote_target. (extended_remote_ops): Now an extended_remote_target. (remote_insert_fork_catchpoint, remote_remove_fork_catchpoint) (remote_insert_vfork_catchpoint, remote_remove_vfork_catchpoint) (remote_insert_exec_catchpoint, remote_remove_exec_catchpoint) (remote_pass_signals, remote_set_syscall_catchpoint) (remote_program_signals, ) (remote_thread_always_alive): Remove target_ops parameter. (remote_thread_alive, remote_thread_name) (remote_update_thread_list, remote_threads_extra_info) (remote_static_tracepoint_marker_at) (remote_static_tracepoint_markers_by_strid) (remote_get_ada_task_ptid, remote_close, remote_start_remote) (remote_open): Refactor as methods of remote_target. (extended_remote_open, extended_remote_detach) (extended_remote_attach, extended_remote_post_attach): (extended_remote_supports_disable_randomization) (extended_remote_create_inferior): : Refactor as method of extended_remote_target. (remote_set_permissions, remote_open_1, remote_detach) (remote_follow_fork, remote_follow_exec, remote_disconnect) (remote_resume, remote_commit_resume, remote_stop) (remote_interrupt, remote_pass_ctrlc, remote_terminal_inferior) (remote_terminal_ours, remote_wait, remote_fetch_registers) (remote_prepare_to_store, remote_store_registers) (remote_flash_erase, remote_flash_done, remote_files_info) (remote_kill, remote_mourn, remote_insert_breakpoint) (remote_remove_breakpoint, remote_insert_watchpoint) (remote_watchpoint_addr_within_range) (remote_remove_watchpoint, remote_region_ok_for_hw_watchpoint) (remote_check_watch_resources, remote_stopped_by_sw_breakpoint) (remote_supports_stopped_by_sw_breakpoint) (remote_stopped_by_hw_breakpoint) (remote_supports_stopped_by_hw_breakpoint) (remote_stopped_by_watchpoint, remote_stopped_data_address) (remote_insert_hw_breakpoint, remote_remove_hw_breakpoint) (remote_verify_memory): Refactor as methods of remote_target. (remote_write_qxfer, remote_read_qxfer): Remove target_ops parameter. (remote_xfer_partial, remote_get_memory_xfer_limit) (remote_search_memory, remote_rcmd, remote_memory_map) (remote_pid_to_str, remote_get_thread_local_address) (remote_get_tib_address, remote_read_description): Refactor as methods of remote_target. (remote_target::fileio_open, remote_target::fileio_pwrite) (remote_target::fileio_pread, remote_target::fileio_close): New. (remote_hostio_readlink, remote_hostio_fstat) (remote_filesystem_is_local, remote_can_execute_reverse) (remote_supports_non_stop, remote_supports_disable_randomization) (remote_supports_multi_process, remote_supports_cond_breakpoints) (remote_supports_enable_disable_tracepoint) (remote_supports_string_tracing) (remote_can_run_breakpoint_commands, remote_trace_init) (remote_download_tracepoint, remote_can_download_tracepoint) (remote_download_trace_state_variable, remote_enable_tracepoint) (remote_disable_tracepoint, remote_trace_set_readonly_regions) (remote_trace_start, remote_get_trace_status) (remote_get_tracepoint_status, remote_trace_stop) (remote_trace_find, remote_get_trace_state_variable_value) (remote_save_trace_data, remote_get_raw_trace_data) (remote_set_disconnected_tracing, remote_core_of_thread) (remote_set_circular_trace_buffer, remote_traceframe_info) (remote_get_min_fast_tracepoint_insn_len) (remote_set_trace_buffer_size, remote_set_trace_notes) (remote_use_agent, remote_can_use_agent, remote_enable_btrace) (remote_disable_btrace, remote_teardown_btrace) (remote_read_btrace, remote_btrace_conf) (remote_augmented_libraries_svr4_read, remote_load) (remote_pid_to_exec_file, remote_can_do_single_step) (remote_execution_direction, remote_thread_handle_to_thread_info): Refactor as methods of remote_target. (init_remote_ops, init_extended_remote_ops): Delete. (remote_can_async_p, remote_is_async_p, remote_async) (remote_thread_events, remote_upload_tracepoints) (remote_upload_trace_state_variables): Refactor as methods of remote_target. (_initialize_remote): Remove references to init_remote_ops and init_extended_remote_ops. * remote-sim.c (gdbsim_target): New class. (gdbsim_fetch_register, gdbsim_store_register, gdbsim_kill) (gdbsim_load, gdbsim_create_inferior, gdbsim_open, gdbsim_close) (gdbsim_detach, gdbsim_resume, gdbsim_interrupt) (gdbsim_wait, gdbsim_prepare_to_store, gdbsim_xfer_partial) (gdbsim_files_info, gdbsim_mourn_inferior, gdbsim_thread_alive) (gdbsim_pid_to_str, gdbsim_has_all_memory, gdbsim_has_memory): Refactor as methods of gdbsim_target. (gdbsim_ops): Now a gdbsim_target. (init_gdbsim_ops): Delete. (gdbsim_cntrl_c): Adjust. (_initialize_remote_sim): Remove reference to init_gdbsim_ops. * amd64-linux-nat.c (amd64_linux_nat_target): New class. (the_amd64_linux_nat_target): New. (amd64_linux_fetch_inferior_registers) (amd64_linux_store_inferior_registers): Refactor as methods of amd64_linux_nat_target. (_initialize_amd64_linux_nat): Adjust. Set linux_target. * i386-linux-nat.c: Don't include "linux-nat.h". (i386_linux_nat_target): New class. (the_i386_linux_nat_target): New. (i386_linux_fetch_inferior_registers) (i386_linux_store_inferior_registers, i386_linux_resume): Refactor as methods of i386_linux_nat_target. (_initialize_i386_linux_nat): Adjust. Set linux_target. * inf-child.c (inf_child_ops): Delete. (inf_child_fetch_inferior_registers) (inf_child_store_inferior_registers): Delete. (inf_child_post_attach, inf_child_prepare_to_store): Refactor as methods of inf_child_target. (inf_child_target::supports_terminal_ours) (inf_child_target::terminal_init) (inf_child_target::terminal_inferior) (inf_child_target::terminal_ours_for_output) (inf_child_target::terminal_ours, inf_child_target::interrupt) (inf_child_target::pass_ctrlc, inf_child_target::terminal_info): New. (inf_child_open, inf_child_disconnect, inf_child_close) (inf_child_mourn_inferior, inf_child_maybe_unpush_target) (inf_child_post_startup_inferior, inf_child_can_run) (inf_child_pid_to_exec_file): Refactor as methods of inf_child_target. (inf_child_follow_fork): Delete. (inf_child_target::can_create_inferior) (inf_child_target::can_attach): New. (inf_child_target::has_all_memory, inf_child_target::has_memory) (inf_child_target::has_stack, inf_child_target::has_registers) (inf_child_target::has_execution): New. (inf_child_fileio_open, inf_child_fileio_pwrite) (inf_child_fileio_pread, inf_child_fileio_fstat) (inf_child_fileio_close, inf_child_fileio_unlink) (inf_child_fileio_readlink, inf_child_use_agent) (inf_child_can_use_agent): Refactor as methods of inf_child_target. (return_zero, inf_child_target): Delete. (inf_child_target::inf_child_target): New. * inf-child.h: Include "target.h". (inf_child_target): Delete function prototype. (inf_child_target): New class. (inf_child_open_target, inf_child_mourn_inferior) (inf_child_maybe_unpush_target): Delete. * inf-ptrace.c (inf_ptrace_target::~inf_ptrace_target): New. (inf_ptrace_follow_fork, inf_ptrace_insert_fork_catchpoint) (inf_ptrace_remove_fork_catchpoint, inf_ptrace_create_inferior) (inf_ptrace_post_startup_inferior, inf_ptrace_mourn_inferior) (inf_ptrace_attach, inf_ptrace_post_attach, inf_ptrace_detach) (inf_ptrace_detach_success, inf_ptrace_kill, inf_ptrace_resume) (inf_ptrace_wait, inf_ptrace_xfer_partial) (inf_ptrace_thread_alive, inf_ptrace_files_info) (inf_ptrace_pid_to_str, inf_ptrace_auxv_parse): Refactor as methods of inf_ptrace_target. (inf_ptrace_target): Delete function. * inf-ptrace.h: Include "inf-child.h". (inf_ptrace_target): Delete function declaration. (inf_ptrace_target): New class. (inf_ptrace_trad_target, inf_ptrace_detach_success): Delete. * linux-nat.c (linux_target): New. (linux_ops, linux_ops_saved, super_xfer_partial): Delete. (linux_nat_target::~linux_nat_target): New. (linux_child_post_attach, linux_child_post_startup_inferior) (linux_child_follow_fork, linux_child_insert_fork_catchpoint) (linux_child_remove_fork_catchpoint) (linux_child_insert_vfork_catchpoint) (linux_child_remove_vfork_catchpoint) (linux_child_insert_exec_catchpoint) (linux_child_remove_exec_catchpoint) (linux_child_set_syscall_catchpoint, linux_nat_pass_signals) (linux_nat_create_inferior, linux_nat_attach, linux_nat_detach) (linux_nat_resume, linux_nat_stopped_by_watchpoint) (linux_nat_stopped_data_address) (linux_nat_stopped_by_sw_breakpoint) (linux_nat_supports_stopped_by_sw_breakpoint) (linux_nat_stopped_by_hw_breakpoint) (linux_nat_supports_stopped_by_hw_breakpoint, linux_nat_wait) (linux_nat_kill, linux_nat_mourn_inferior) (linux_nat_xfer_partial, linux_nat_thread_alive) (linux_nat_update_thread_list, linux_nat_pid_to_str) (linux_nat_thread_name, linux_child_pid_to_exec_file) (linux_child_static_tracepoint_markers_by_strid) (linux_nat_is_async_p, linux_nat_can_async_p) (linux_nat_supports_non_stop, linux_nat_always_non_stop_p) (linux_nat_supports_multi_process) (linux_nat_supports_disable_randomization, linux_nat_async) (linux_nat_stop, linux_nat_close, linux_nat_thread_address_space) (linux_nat_core_of_thread, linux_nat_filesystem_is_local) (linux_nat_fileio_open, linux_nat_fileio_readlink) (linux_nat_fileio_unlink, linux_nat_thread_events): Refactor as methods of linux_nat_target. (linux_nat_wait_1, linux_xfer_siginfo, linux_proc_xfer_partial) (linux_proc_xfer_spu, linux_nat_xfer_osdata): Remove target_ops parameter. (check_stopped_by_watchpoint): Adjust. (linux_xfer_partial): Delete. (linux_target_install_ops, linux_target, linux_nat_add_target): Delete. (linux_nat_target::linux_nat_target): New. * linux-nat.h: Include "inf-ptrace.h". (linux_nat_target): New. (linux_target, linux_target_install_ops, linux_nat_add_target): Delete function declarations. (linux_target): Declare global. * linux-thread-db.c (thread_db_target): New. (thread_db_target::thread_db_target): New. (thread_db_ops): Delete. (the_thread_db_target): New. (thread_db_detach, thread_db_wait, thread_db_mourn_inferior) (thread_db_update_thread_list, thread_db_pid_to_str) (thread_db_extra_thread_info) (thread_db_thread_handle_to_thread_info) (thread_db_get_thread_local_address, thread_db_get_ada_task_ptid) (thread_db_resume): Refactor as methods of thread_db_target. (init_thread_db_ops): Delete. (_initialize_thread_db): Remove reference to init_thread_db_ops. * x86-linux-nat.c: Don't include "linux-nat.h". (super_post_startup_inferior): Delete. (x86_linux_nat_target::~x86_linux_nat_target): New. (x86_linux_child_post_startup_inferior) (x86_linux_read_description, x86_linux_enable_btrace) (x86_linux_disable_btrace, x86_linux_teardown_btrace) (x86_linux_read_btrace, x86_linux_btrace_conf): Refactor as methods of x86_linux_nat_target. (x86_linux_create_target): Delete. Bits folded ... (x86_linux_add_target): ... here. Now takes a linux_nat_target pointer. * x86-linux-nat.h: Include "linux-nat.h" and "x86-nat.h". (x86_linux_nat_target): New class. (x86_linux_create_target): Delete. (x86_linux_add_target): Now takes a linux_nat_target pointer. * x86-nat.c (x86_insert_watchpoint, x86_remove_watchpoint) (x86_region_ok_for_watchpoint, x86_stopped_data_address) (x86_stopped_by_watchpoint, x86_insert_hw_breakpoint) (x86_remove_hw_breakpoint, x86_can_use_hw_breakpoint) (x86_stopped_by_hw_breakpoint): Remove target_ops parameter and make extern. (x86_use_watchpoints): Delete. * x86-nat.h: Include "breakpoint.h" and "target.h". (x86_use_watchpoints): Delete. (x86_can_use_hw_breakpoint, x86_region_ok_for_hw_watchpoint) (x86_stopped_by_watchpoint, x86_stopped_data_address) (x86_insert_watchpoint, x86_remove_watchpoint) (x86_insert_hw_breakpoint, x86_remove_hw_breakpoint) (x86_stopped_by_hw_breakpoint): New declarations. (x86_nat_target): New template class. * ppc-linux-nat.c (ppc_linux_nat_target): New class. (the_ppc_linux_nat_target): New. (ppc_linux_fetch_inferior_registers) (ppc_linux_can_use_hw_breakpoint) (ppc_linux_region_ok_for_hw_watchpoint) (ppc_linux_ranged_break_num_registers) (ppc_linux_insert_hw_breakpoint, ppc_linux_remove_hw_breakpoint) (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_can_accel_watchpoint_condition) (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint) (ppc_linux_stopped_data_address, ppc_linux_stopped_by_watchpoint) (ppc_linux_watchpoint_addr_within_range) (ppc_linux_masked_watch_num_registers) (ppc_linux_store_inferior_registers, ppc_linux_auxv_parse) (ppc_linux_read_description): Refactor as methods of ppc_linux_nat_target. (_initialize_ppc_linux_nat): Adjust. Set linux_target. * procfs.c (procfs_xfer_partial): Delete forward declaration. (procfs_target): New class. (the_procfs_target): New. (procfs_target): Delete function. (procfs_auxv_parse, procfs_attach, procfs_detach) (procfs_fetch_registers, procfs_store_registers, procfs_wait) (procfs_xfer_partial, procfs_resume, procfs_pass_signals) (procfs_files_info, procfs_kill_inferior, procfs_mourn_inferior) (procfs_create_inferior, procfs_update_thread_list) (procfs_thread_alive, procfs_pid_to_str) (procfs_can_use_hw_breakpoint, procfs_stopped_by_watchpoint) (procfs_stopped_data_address, procfs_insert_watchpoint) (procfs_remove_watchpoint, procfs_region_ok_for_hw_watchpoint) (proc_find_memory_regions, procfs_info_proc) (procfs_make_note_section): Refactor as methods of procfs_target. (_initialize_procfs): Adjust. * sol-thread.c (sol_thread_target): New class. (sol_thread_ops): Now a sol_thread_target. (sol_thread_detach, sol_thread_resume, sol_thread_wait) (sol_thread_fetch_registers, sol_thread_store_registers) (sol_thread_xfer_partial, sol_thread_mourn_inferior) (sol_thread_alive, solaris_pid_to_str, sol_update_thread_list) (sol_get_ada_task_ptid): Refactor as methods of sol_thread_target. (init_sol_thread_ops): Delete. (_initialize_sol_thread): Adjust. Remove references to init_sol_thread_ops and complete_target_initialization. * windows-nat.c (windows_nat_target): New class. (windows_fetch_inferior_registers) (windows_store_inferior_registers, windows_resume, windows_wait) (windows_attach, windows_detach, windows_pid_to_exec_file) (windows_files_info, windows_create_inferior) (windows_mourn_inferior, windows_interrupt, windows_kill_inferior) (windows_close, windows_pid_to_str, windows_xfer_partial) (windows_get_tib_address, windows_get_ada_task_ptid) (windows_thread_name, windows_thread_alive): Refactor as windows_nat_target methods. (do_initial_windows_stuff): Adjust. (windows_target): Delete function. (_initialize_windows_nat): Adjust. * darwin-nat.c (darwin_resume, darwin_wait_to, darwin_interrupt) (darwin_mourn_inferior, darwin_kill_inferior) (darwin_create_inferior, darwin_attach, darwin_detach) (darwin_pid_to_str, darwin_thread_alive, darwin_xfer_partial) (darwin_pid_to_exec_file, darwin_get_ada_task_ptid) (darwin_supports_multi_process): Refactor as darwin_nat_target methods. (darwin_resume_to, darwin_files_info): Delete. (_initialize_darwin_inferior): Rename to ... (_initialize_darwin_nat): ... this. Adjust to C++ification. * darwin-nat.h: Include "inf-child.h". (darwin_nat_target): New class. (darwin_complete_target): Delete. * i386-darwin-nat.c (i386_darwin_nat_target): New class. (darwin_target): New. (i386_darwin_fetch_inferior_registers) (i386_darwin_store_inferior_registers): Refactor as methods of darwin_nat_target. (darwin_complete_target): Delete, with ... (_initialize_i386_darwin_nat): ... bits factored out here. * alpha-linux-nat.c (alpha_linux_nat_target): New class. (the_alpha_linux_nat_target): New. (alpha_linux_register_u_offset): Refactor as alpha_linux_nat_target method. (_initialize_alpha_linux_nat): Adjust. * linux-nat-trad.c (inf_ptrace_register_u_offset): Delete. (inf_ptrace_fetch_register, inf_ptrace_fetch_registers) (inf_ptrace_store_register, inf_ptrace_store_registers): Refact as methods of linux_nat_trad_target. (linux_trad_target): Delete. * linux-nat-trad.h (linux_trad_target): Delete function. (linux_nat_trad_target): New class. * mips-linux-nat.c (mips_linux_nat_target): New class. (super_fetch_registers, super_store_registers, super_close): Delete. (the_mips_linux_nat_target): New. (mips64_linux_regsets_fetch_registers) (mips64_linux_regsets_store_registers) (mips64_linux_fetch_registers, mips64_linux_store_registers) (mips_linux_register_u_offset, mips_linux_read_description) (mips_linux_can_use_hw_breakpoint) (mips_linux_stopped_by_watchpoint) (mips_linux_stopped_data_address) (mips_linux_region_ok_for_hw_watchpoint) (mips_linux_insert_watchpoint, mips_linux_remove_watchpoint) (mips_linux_close): Refactor as methods of mips_linux_nat. (_initialize_mips_linux_nat): Adjust to C++ification. * aix-thread.c (aix_thread_target): New class. (aix_thread_ops): Now an aix_thread_target. (aix_thread_detach, aix_thread_resume, aix_thread_wait) (aix_thread_fetch_registers, aix_thread_store_registers) (aix_thread_xfer_partial, aix_thread_mourn_inferior) (aix_thread_thread_alive, aix_thread_pid_to_str) (aix_thread_extra_thread_info, aix_thread_get_ada_task_ptid): Refactor as methods of aix_thread_target. (init_aix_thread_ops): Delete. (_initialize_aix_thread): Remove references to init_aix_thread_ops and complete_target_initialization. * rs6000-nat.c (rs6000_xfer_shared_libraries): Delete. (rs6000_nat_target): New class. (the_rs6000_nat_target): New. (rs6000_fetch_inferior_registers, rs6000_store_inferior_registers) (rs6000_xfer_partial, rs6000_wait, rs6000_create_inferior) (rs6000_xfer_shared_libraries): Refactor as rs6000_nat_target methods. (super_create_inferior): Delete. (_initialize_rs6000_nat): Adjust to C++ification. * arm-linux-nat.c (arm_linux_nat_target): New class. (the_arm_linux_nat_target): New. (arm_linux_fetch_inferior_registers) (arm_linux_store_inferior_registers, arm_linux_read_description) (arm_linux_can_use_hw_breakpoint, arm_linux_insert_hw_breakpoint) (arm_linux_remove_hw_breakpoint) (arm_linux_region_ok_for_hw_watchpoint) (arm_linux_insert_watchpoint, arm_linux_remove_watchpoint) (arm_linux_stopped_data_address, arm_linux_stopped_by_watchpoint) (arm_linux_watchpoint_addr_within_range): Refactor as methods of arm_linux_nat_target. (_initialize_arm_linux_nat): Adjust to C++ification. * aarch64-linux-nat.c (aarch64_linux_nat_target): New class. (the_aarch64_linux_nat_target): New. (aarch64_linux_fetch_inferior_registers) (aarch64_linux_store_inferior_registers) (aarch64_linux_child_post_startup_inferior) (aarch64_linux_read_description) (aarch64_linux_can_use_hw_breakpoint) (aarch64_linux_insert_hw_breakpoint) (aarch64_linux_remove_hw_breakpoint) (aarch64_linux_insert_watchpoint, aarch64_linux_remove_watchpoint) (aarch64_linux_region_ok_for_hw_watchpoint) (aarch64_linux_stopped_data_address) (aarch64_linux_stopped_by_watchpoint) (aarch64_linux_watchpoint_addr_within_range) (aarch64_linux_can_do_single_step): Refactor as methods of aarch64_linux_nat_target. (super_post_startup_inferior): Delete. (_initialize_aarch64_linux_nat): Adjust to C++ification. * hppa-linux-nat.c (hppa_linux_nat_target): New class. (the_hppa_linux_nat_target): New. (hppa_linux_fetch_inferior_registers) (hppa_linux_store_inferior_registers): Refactor as methods of hppa_linux_nat_target. (_initialize_hppa_linux_nat): Adjust to C++ification. * ia64-linux-nat.c (ia64_linux_nat_target): New class. (the_ia64_linux_nat_target): New. (ia64_linux_insert_watchpoint, ia64_linux_remove_watchpoint) (ia64_linux_stopped_data_address) (ia64_linux_stopped_by_watchpoint, ia64_linux_fetch_registers) (ia64_linux_store_registers, ia64_linux_xfer_partial): Refactor as ia64_linux_nat_target methods. (super_xfer_partial): Delete. (_initialize_ia64_linux_nat): Adjust to C++ification. * m32r-linux-nat.c (m32r_linux_nat_target): New class. (the_m32r_linux_nat_target): New. (m32r_linux_fetch_inferior_registers) (m32r_linux_store_inferior_registers): Refactor as m32r_linux_nat_target methods. (_initialize_m32r_linux_nat): Adjust to C++ification. * m68k-linux-nat.c (m68k_linux_nat_target): New class. (the_m68k_linux_nat_target): New. (m68k_linux_fetch_inferior_registers) (m68k_linux_store_inferior_registers): Refactor as m68k_linux_nat_target methods. (_initialize_m68k_linux_nat): Adjust to C++ification. * s390-linux-nat.c (s390_linux_nat_target): New class. (the_s390_linux_nat_target): New. (s390_linux_fetch_inferior_registers) (s390_linux_store_inferior_registers, s390_stopped_by_watchpoint) (s390_insert_watchpoint, s390_remove_watchpoint) (s390_can_use_hw_breakpoint, s390_insert_hw_breakpoint) (s390_remove_hw_breakpoint, s390_region_ok_for_hw_watchpoint) (s390_auxv_parse, s390_read_description): Refactor as methods of s390_linux_nat_target. (_initialize_s390_nat): Adjust to C++ification. * sparc-linux-nat.c (sparc_linux_nat_target): New class. (the_sparc_linux_nat_target): New. (_initialize_sparc_linux_nat): Adjust to C++ification. * sparc-nat.c (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc64-linux-nat.c (sparc64_linux_nat_target): New class. (the_sparc64_linux_nat_target): New. (_initialize_sparc64_linux_nat): Adjust to C++ification. * spu-linux-nat.c (spu_linux_nat_target): New class. (the_spu_linux_nat_target): New. (spu_child_post_startup_inferior, spu_child_post_attach) (spu_child_wait, spu_fetch_inferior_registers) (spu_store_inferior_registers, spu_xfer_partial) (spu_can_use_hw_breakpoint): Refactor as spu_linux_nat_target methods. (_initialize_spu_nat): Adjust to C++ification. * tilegx-linux-nat.c (tilegx_linux_nat_target): New class. (the_tilegx_linux_nat_target): New. (fetch_inferior_registers, store_inferior_registers): Refactor as methods. (_initialize_tile_linux_nat): Adjust to C++ification. * xtensa-linux-nat.c (xtensa_linux_nat_target): New class. (the_xtensa_linux_nat_target): New. (xtensa_linux_fetch_inferior_registers) (xtensa_linux_store_inferior_registers): Refactor as xtensa_linux_nat_target methods. (_initialize_xtensa_linux_nat): Adjust to C++ification. * fbsd-nat.c (USE_SIGTRAP_SIGINFO): Delete. (fbsd_pid_to_exec_file, fbsd_find_memory_regions) (fbsd_find_memory_regions, fbsd_info_proc, fbsd_xfer_partial) (fbsd_thread_alive, fbsd_pid_to_str, fbsd_thread_name) (fbsd_update_thread_list, fbsd_resume, fbsd_wait) (fbsd_stopped_by_sw_breakpoint) (fbsd_supports_stopped_by_sw_breakpoint, fbsd_follow_fork) (fbsd_insert_fork_catchpoint, fbsd_remove_fork_catchpoint) (fbsd_insert_vfork_catchpoint, fbsd_remove_vfork_catchpoint) (fbsd_post_startup_inferior, fbsd_post_attach) (fbsd_insert_exec_catchpoint, fbsd_remove_exec_catchpoint) (fbsd_set_syscall_catchpoint) (super_xfer_partial, super_resume, super_wait) (fbsd_supports_stopped_by_hw_breakpoint): Delete. (fbsd_handle_debug_trap): Remove target_ops parameter. (fbsd_nat_add_target): Delete. * fbsd-nat.h: Include "inf-ptrace.h". (fbsd_nat_add_target): Delete. (USE_SIGTRAP_SIGINFO): Define. (fbsd_nat_target): New class. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers) (amd64bsd_store_inferior_registers): Remove target_ops parameter. (amd64bsd_target): Delete. * amd64-bsd-nat.h: New file. * amd64-fbsd-nat.c: Include "amd64-bsd-nat.h" instead of "x86-bsd-nat.h". (amd64_fbsd_nat_target): New class. (the_amd64_fbsd_nat_target): New. (amd64fbsd_read_description): Refactor as method of amd64_fbsd_nat_target. (amd64_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_amd64fbsd_nat): Adjust to C++ification. * amd64-nat.h (amd64bsd_target): Delete function declaration. * i386-bsd-nat.c (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Remove target_ops parameter. (i386bsd_target): Delete. * i386-bsd-nat.h (i386bsd_target): Delete function declaration. (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Declare. (i386_bsd_nat_target): New class. * i386-fbsd-nat.c (i386_fbsd_nat_target): New class. (the_i386_fbsd_nat_target): New. (i386fbsd_resume, i386fbsd_read_description): Refactor as i386_fbsd_nat_target methods. (i386_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_i386fbsd_nat): Adjust to C++ification. * x86-bsd-nat.c (super_mourn_inferior): Delete. (x86bsd_mourn_inferior, x86bsd_target): Delete. (_initialize_x86_bsd_nat): Adjust to C++ification. * x86-bsd-nat.h: Include "x86-nat.h". (x86bsd_target): Delete declaration. (x86bsd_nat_target): New class. * aarch64-fbsd-nat.c (aarch64_fbsd_nat_target): New class. (the_aarch64_fbsd_nat_target): New. (aarch64_fbsd_fetch_inferior_registers) (aarch64_fbsd_store_inferior_registers): Refactor as methods of aarch64_fbsd_nat_target. (_initialize_aarch64_fbsd_nat): Adjust to C++ification. * alpha-bsd-nat.c (alpha_bsd_nat_target): New class. (the_alpha_bsd_nat_target): New. (alphabsd_fetch_inferior_registers) (alphabsd_store_inferior_registers): Refactor as alpha_bsd_nat_target methods. (_initialize_alphabsd_nat): Refactor as methods of alpha_bsd_nat_target. * amd64-nbsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_nbsd_nat_target): New. (_initialize_amd64nbsd_nat): Adjust to C++ification. * amd64-obsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_obsd_nat_target): New. (_initialize_amd64obsd_nat): Adjust to C++ification. * arm-fbsd-nat.c (arm_fbsd_nat_target): New. (the_arm_fbsd_nat_target): New. (arm_fbsd_fetch_inferior_registers) (arm_fbsd_store_inferior_registers, arm_fbsd_read_description): (_initialize_arm_fbsd_nat): Refactor as methods of arm_fbsd_nat_target. (_initialize_arm_fbsd_nat): Adjust to C++ification. * arm-nbsd-nat.c (arm_netbsd_nat_target): New class. (the_arm_netbsd_nat_target): New. (armnbsd_fetch_registers, armnbsd_store_registers): Refactor as arm_netbsd_nat_target. (_initialize_arm_netbsd_nat): Adjust to C++ification. * hppa-nbsd-nat.c (hppa_nbsd_nat_target): New class. (the_hppa_nbsd_nat_target): New. (hppanbsd_fetch_registers, hppanbsd_store_registers): Refactor as hppa_nbsd_nat_target methods. (_initialize_hppanbsd_nat): Adjust to C++ification. * hppa-obsd-nat.c (hppa_obsd_nat_target): New class. (the_hppa_obsd_nat_target): New. (hppaobsd_fetch_registers, hppaobsd_store_registers): Refactor as methods of hppa_obsd_nat_target. (_initialize_hppaobsd_nat): Adjust to C++ification. Use add_target. * i386-nbsd-nat.c (the_i386_nbsd_nat_target): New. (_initialize_i386nbsd_nat): Adjust to C++ification. Use add_target. * i386-obsd-nat.c (the_i386_obsd_nat_target): New. (_initialize_i386obsd_nat): Use add_target. * m68k-bsd-nat.c (m68k_bsd_nat_target): New class. (the_m68k_bsd_nat_target): New. (m68kbsd_fetch_inferior_registers) (m68kbsd_store_inferior_registers): Refactor as methods of m68k_bsd_nat_target. (_initialize_m68kbsd_nat): Adjust to C++ification. * mips-fbsd-nat.c (mips_fbsd_nat_target): New class. (the_mips_fbsd_nat_target): New. (mips_fbsd_fetch_inferior_registers) (mips_fbsd_store_inferior_registers): Refactor as methods of mips_fbsd_nat_target. (_initialize_mips_fbsd_nat): Adjust to C++ification. Use add_target. * mips-nbsd-nat.c (mips_nbsd_nat_target): New class. (the_mips_nbsd_nat_target): New. (mipsnbsd_fetch_inferior_registers) (mipsnbsd_store_inferior_registers): Refactor as methods of mips_nbsd_nat_target. (_initialize_mipsnbsd_nat): Adjust to C++ification. * mips64-obsd-nat.c (mips64_obsd_nat_target): New class. (the_mips64_obsd_nat_target): New. (mips64obsd_fetch_inferior_registers) (mips64obsd_store_inferior_registers): Refactor as methods of mips64_obsd_nat_target. (_initialize_mips64obsd_nat): Adjust to C++ification. Use add_target. * nbsd-nat.c (nbsd_pid_to_exec_file): Refactor as method of nbsd_nat_target. * nbsd-nat.h: Include "inf-ptrace.h". (nbsd_nat_target): New class. * obsd-nat.c (obsd_pid_to_str, obsd_update_thread_list) (obsd_wait): Refactor as methods of obsd_nat_target. (obsd_add_target): Delete. * obsd-nat.h: Include "inf-ptrace.h". (obsd_nat_target): New class. * ppc-fbsd-nat.c (ppc_fbsd_nat_target): New class. (the_ppc_fbsd_nat_target): New. (ppcfbsd_fetch_inferior_registers) (ppcfbsd_store_inferior_registers): Refactor as methods of ppc_fbsd_nat_target. (_initialize_ppcfbsd_nat): Adjust to C++ification. Use add_target. * ppc-nbsd-nat.c (ppc_nbsd_nat_target): New class. (the_ppc_nbsd_nat_target): New. (ppcnbsd_fetch_inferior_registers) (ppcnbsd_store_inferior_registers): Refactor as methods of ppc_nbsd_nat_target. (_initialize_ppcnbsd_nat): Adjust to C++ification. * ppc-obsd-nat.c (ppc_obsd_nat_target): New class. (the_ppc_obsd_nat_target): New. (ppcobsd_fetch_registers, ppcobsd_store_registers): Refactor as methods of ppc_obsd_nat_target. (_initialize_ppcobsd_nat): Adjust to C++ification. Use add_target. * sh-nbsd-nat.c (sh_nbsd_nat_target): New class. (the_sh_nbsd_nat_target): New. (shnbsd_fetch_inferior_registers) (shnbsd_store_inferior_registers): Refactor as methods of sh_nbsd_nat_target. (_initialize_shnbsd_nat): Adjust to C++ification. * sparc-nat.c (sparc_xfer_wcookie): Make extern. (inf_ptrace_xfer_partial): Delete. (sparc_xfer_partial, sparc_target): Delete. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers, sparc_xfer_wcookie): Declare. (sparc_target): Delete function declaration. (sparc_target): New template class. * sparc-nbsd-nat.c (the_sparc_nbsd_nat_target): New. (_initialize_sparcnbsd_nat): Adjust to C++ification. * sparc64-fbsd-nat.c (the_sparc64_fbsd_nat_target): New. (_initialize_sparc64fbsd_nat): Adjust to C++ification. Use add_target. * sparc64-nbsd-nat.c (the_sparc64_nbsd_nat_target): New. (_initialize_sparc64nbsd_nat): Adjust to C++ification. * sparc64-obsd-nat.c (the_sparc64_obsd_nat_target): New. (_initialize_sparc64obsd_nat): Adjust to C++ification. Use add_target. * vax-bsd-nat.c (vax_bsd_nat_target): New class. (the_vax_bsd_nat_target): New. (vaxbsd_fetch_inferior_registers) (vaxbsd_store_inferior_registers): Refactor as vax_bsd_nat_target methods. (_initialize_vaxbsd_nat): Adjust to C++ification. * bsd-kvm.c (bsd_kvm_target): New class. (bsd_kvm_ops): Now a bsd_kvm_target. (bsd_kvm_open, bsd_kvm_close, bsd_kvm_xfer_partial) (bsd_kvm_files_info, bsd_kvm_fetch_registers) (bsd_kvm_thread_alive, bsd_kvm_pid_to_str): Refactor as methods of bsd_kvm_target. (bsd_kvm_return_one): Delete. (bsd_kvm_add_target): Adjust to C++ification. * nto-procfs.c (nto_procfs_target, nto_procfs_target_native) (nto_procfs_target_procfs): New classes. (procfs_open_1, procfs_thread_alive, procfs_update_thread_list) (procfs_files_info, procfs_pid_to_exec_file, procfs_attach) (procfs_post_attach, procfs_wait, procfs_fetch_registers) (procfs_xfer_partial, procfs_detach, procfs_insert_breakpoint) (procfs_remove_breakpoint, procfs_insert_hw_breakpoint) (procfs_remove_hw_breakpoint, procfs_resume) (procfs_mourn_inferior, procfs_create_inferior, procfs_interrupt) (procfs_kill_inferior, procfs_store_registers) (procfs_pass_signals, procfs_pid_to_str, procfs_can_run): Refactor as methods of nto_procfs_target. (nto_procfs_ops): Now an nto_procfs_target_procfs. (nto_native_ops): Delete. (procfs_open, procfs_native_open): Delete. (nto_native_ops): Now an nto_procfs_target_native. (init_procfs_targets): Adjust to C++ification. (procfs_can_use_hw_breakpoint, procfs_remove_hw_watchpoint) (procfs_insert_hw_watchpoint, procfs_stopped_by_watchpoint): Refactor as methods of nto_procfs_target. * go32-nat.c (go32_nat_target): New class. (the_go32_nat_target): New. (go32_attach, go32_resume, go32_wait, go32_fetch_registers) (go32_store_registers, go32_xfer_partial, go32_files_info) (go32_kill_inferior, go32_create_inferior, go32_mourn_inferior) (go32_terminal_init, go32_terminal_info, go32_terminal_inferior) (go32_terminal_ours, go32_pass_ctrlc, go32_thread_alive) (go32_pid_to_str): Refactor as methods of go32_nat_target. (go32_target): Delete. (_initialize_go32_nat): Adjust to C++ification. * gnu-nat.c (gnu_wait, gnu_resume, gnu_kill_inferior) (gnu_mourn_inferior, gnu_create_inferior, gnu_attach, gnu_detach) (gnu_stop, gnu_thread_alive, gnu_xfer_partial) (gnu_find_memory_regions, gnu_pid_to_str): Refactor as methods of gnu_nat_target. (gnu_target): Delete. * gnu-nat.h (gnu_target): Delete. (gnu_nat_target): New class. * i386-gnu-nat.c (gnu_base_target): New. (i386_gnu_nat_target): New class. (the_i386_gnu_nat_target): New. (_initialize_i386gnu_nat): Adjust to C++ification. gdb/testsuite/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * gdb.base/breakpoint-in-ro-region.exp: Adjust to to_resume and to_log_command renames. * gdb.base/sss-bp-on-user-bp-2.exp: Likewise.
2018-05-03 07:37:22 +08:00
int
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
ppc_linux_nat_target::masked_watch_num_registers (CORE_ADDR addr,
CORE_ADDR mask)
2011-05-06 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Implement support for PowerPC BookE masked watchpoints. gdb/ * NEWS: Mention masked watchpoint support. Create "Changed commands" section. * breakpoint.h (struct breakpoint_ops) <works_in_software_mode>: New method. Initialize to NULL in all existing breakpoint_ops instances. (struct breakpoint) <hw_wp_mask>: New field. * breakpoint.c (is_masked_watchpoint): Add prototype. (update_watchpoint): Don't set b->val for masked watchpoints. Call breakpoint's breakpoint_ops.works_in_software_mode if available. (watchpoints_triggered): Handle the case of a hardware masked watchpoint trigger. (watchpoint_check): Likewise. (works_in_software_mode_watchpoint): New function. (insert_masked_watchpoint, remove_masked_watchpoint) (resources_needed_masked_watchpoint) (works_in_software_mode_masked_watchpoint, print_it_masked_watchpoint) (print_one_detail_masked_watchpoint, print_mention_masked_watchpoint) (print_recreate_masked_watchpoint, is_masked_watchpoint): New functions. (masked_watchpoint_breakpoint_ops): New structure. (watch_command_1): Check for the existence of the `mask' parameter. Set b->ops according to the type of hardware watchpoint being created. * ppc-linux-nat.c (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_masked_watch_num_registers): New functions. (_initialize_ppc_linux_nat): Initialize to_insert_mask_watchpoint, to_remove_mask_watchpoint and to_masked_watch_num_registers. * target.c (update_current_target): Mention to_insert_mask_watchpoint, to_remove_mask_watchpoint, and to_masked_watch_num_registers. (target_insert_mask_watchpoint, target_remove_mask_watchpoint) (target_masked_watch_num_registers): New functions. * target.h (struct target_ops) <to_insert_mask_watchpoint>, <to_remove_mask_watchpoint>, <to_masked_watch_num_registers>: New methods. (target_insert_mask_watchpoint, target_remove_mask_watchpoint) (target_masked_watch_num_registers): Add prototypes. gdb/doc/ * gdb.texinfo (Set Watchpoints): Document mask parameter. (PowerPC Embedded): Mention support of masked watchpoints.
2011-05-07 02:46:33 +08:00
{
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
m_dreg_interface.detect (inferior_ptid);
if (!m_dreg_interface.hwdebug_p ()
|| (m_dreg_interface.hwdebug_info ().features
& PPC_DEBUG_FEATURE_DATA_BP_MASK) == 0)
2011-05-06 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Implement support for PowerPC BookE masked watchpoints. gdb/ * NEWS: Mention masked watchpoint support. Create "Changed commands" section. * breakpoint.h (struct breakpoint_ops) <works_in_software_mode>: New method. Initialize to NULL in all existing breakpoint_ops instances. (struct breakpoint) <hw_wp_mask>: New field. * breakpoint.c (is_masked_watchpoint): Add prototype. (update_watchpoint): Don't set b->val for masked watchpoints. Call breakpoint's breakpoint_ops.works_in_software_mode if available. (watchpoints_triggered): Handle the case of a hardware masked watchpoint trigger. (watchpoint_check): Likewise. (works_in_software_mode_watchpoint): New function. (insert_masked_watchpoint, remove_masked_watchpoint) (resources_needed_masked_watchpoint) (works_in_software_mode_masked_watchpoint, print_it_masked_watchpoint) (print_one_detail_masked_watchpoint, print_mention_masked_watchpoint) (print_recreate_masked_watchpoint, is_masked_watchpoint): New functions. (masked_watchpoint_breakpoint_ops): New structure. (watch_command_1): Check for the existence of the `mask' parameter. Set b->ops according to the type of hardware watchpoint being created. * ppc-linux-nat.c (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_masked_watch_num_registers): New functions. (_initialize_ppc_linux_nat): Initialize to_insert_mask_watchpoint, to_remove_mask_watchpoint and to_masked_watch_num_registers. * target.c (update_current_target): Mention to_insert_mask_watchpoint, to_remove_mask_watchpoint, and to_masked_watch_num_registers. (target_insert_mask_watchpoint, target_remove_mask_watchpoint) (target_masked_watch_num_registers): New functions. * target.h (struct target_ops) <to_insert_mask_watchpoint>, <to_remove_mask_watchpoint>, <to_masked_watch_num_registers>: New methods. (target_insert_mask_watchpoint, target_remove_mask_watchpoint) (target_masked_watch_num_registers): Add prototypes. gdb/doc/ * gdb.texinfo (Set Watchpoints): Document mask parameter. (PowerPC Embedded): Mention support of masked watchpoints.
2011-05-07 02:46:33 +08:00
return -1;
else if ((mask & 0xC0000000) != 0xC0000000)
{
warning (_("The given mask covers kernel address space "
"and cannot be used.\n"));
return -2;
}
else
return 2;
}
[PowerPC] Fix debug register issues in ppc-linux-nat This patch fixes some issues with debug register handling for the powerpc linux native target. Currently, the target methods for installing and removing hardware breakpoints and watchpoints in ppc-linux-nat.c affect all threads known to linux-nat, including threads of different processes. This patch changes ppc-linux-nat.c so that only the process of inferior_ptid is affected by these target methods, as GDB expects. This is done in the same way as various other architectures. The install/remove target methods only register a hardware breakpoint or watchpoint, and then send a stop signal to the threads. The debug registers are only changed with ptrace right before each thread is next resumed, using low_prepare_to_resume. There are two interfaces to modify debug registers for linux running on powerpc, with different sets of ptrace requests: - PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG, and PPC_PTRACE_DELHWDEBUG. Or - PTRACE_SET_DEBUGREG and PTRACE_GET_DEBUGREG The first set (HWDEBUG) is the more flexible one and allows setting watchpoints with a variable watched region length and, for certain embedded processors, multiple types of debug registers (e.g. hardware breakpoints and hardware-assisted conditions for watchpoints). Currently, server processors only provide one watchpoint. The second one (DEBUGREG) only allows setting one debug register, a watchpoint, so we only use it if the first one is not available. The HWDEBUG interface handles debug registers with slot numbers. Once a hardware watchpoint or breakpoint is installed (with PPC_PTRACE_SETHWDEBUG), ptrace returns a slot number. This slot number can then be used to remove the watchpoint or breakpoint from the inferior (with PPC_PTRACE_DELHWDEBUG). The first interface also provides a bitmask of available debug register features, which can be obtained with PPC_PTRACE_GETHWDBGINFO. When GDB first tries to use debug registers, we try the first interface with a ptrace call, and if it isn't available, we fall back to the second one, if available. We use EIO as an indicator that an interface is not available in the kernel. For simplicity, with any other error we immediately assume no interface is available. Unfortunately this means that if a process is killed by a signal right before we try to detect the interface, we might get an ESRCH, which would prevent debug registers to be used in the GDB session. However, it isn't clear that we can safely raise an exception and try again in the future in all the contexts where we try to detect the interface. If the HWDEBUG interface works but provides no feature bits, the target falls back to the DEBUGREG interface. When the kernel is configured without CONFIG_HW_BREAKPOINTS (selected by CONFIG_PERF_EVENTS), there is a bug that causes watchpoints installed with the HWDEBUG interface not to trigger. When this is the case, the feature bits will be zero, which is used as the indicator to fall back to the DEBUGREG interface. This isn't ideal, but has always been the behavior of GDB before this patch, so I decided not to change it. A flag indicates for each thread if its debug registers need to be updated the next time it is resumed. The flag is set whenever the upper layers request or remove a hardware watchpoint or breakpoint, or when a new thread is detected. Because some kernel configurations disable watchpoints after they are hit, we also use the last stop reason of the LWP to determine whether we should update the debug registers. It isn't clear that this is also true of BookE hardware breakpoints, but we also check their stop reason to be on the safe side, since it doesn't hurt. A map from process numbers to hardware watchpoint or breakpoint objects keeps track of what has been requested by the upper layers of GDB, since for GDB installing a hardware watchpoint or breakpoint means doing so for the whole process. When using the HWDEBUG interface we also have to keep track of which slots were last installed in each thread with a map from threads to the slots, so that they can be removed when needed. When resuming a thread, we remove all the slots using this map, then we install all the hardware watchpoints and breakpoints from the per-process map of requests, and then update the per-thread map accordingly. This per-thread state is also used for copying the debug register state after a fork or a clone is detected. The kernel might do this depending on the configuration. Recent kernels running on server processors that were configured with CONFIG_PERF_EVENTS (and therefore CONFIG_HW_BREAKPOINTS) don't copy debug registers across forks and clones. Recent kernels without CONFIG_HW_BREAKPOINTS copy this state. I believe that on embedded processors (e.g. a ppc440) the debug register state is copied, but I haven't been able to test this. To handle both cases, the per-thread state is always copied when forks and clones are detected, and when we resume the thread and delete the debug register slots before updating them, we ignore ENOENT errors. We don't need to handle this when using the DEBUGREG interface since it only allows one hardware watchpoint and doesn't return slot numbers, we just set or clear this watchpoint when needed. Since we signal running threads to stop after a request is processed, so that we can update their debug registers when they are next resumed, there will be a time between signalling the threads and their stop during which the debug registers haven't been updated, even if the target methods completed. The tests in gdb.threads/watchpoint-fork.exp no longer fail with this patch. gdb/ChangeLog: 2020-03-30 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> * ppc-linux-nat.c: Include <algorithm>, <unordered_map>, and <list>. Remove inclusion of observable.h. (PPC_DEBUG_CURRENT_VERSION): Move up define. (struct arch_lwp_info): New struct. (class ppc_linux_dreg_interface): New class. (struct ppc_linux_process_info): New struct. (struct ppc_linux_nat_target) <low_delete_thread, low_new_fork> <low_new_clone, low_forget_process, low_prepare_to_resume> <copy_thread_dreg_state, mark_thread_stale> <mark_debug_registers_changed, register_hw_breakpoint> <clear_hw_breakpoint, register_wp, clear_wp> <can_use_watchpoint_cond_accel, calculate_dvc, check_condition> <num_memory_accesses, get_trigger_type> <create_watchpoint_request, hwdebug_point_cmp> <init_arch_lwp_info, get_arch_lwp_info> <low_stopped_by_watchpoint, low_stopped_data_address>: Declare as methods. <struct ptid_hash>: New inner struct. <m_dreg_interface, m_process_info, m_installed_hw_bps>: Declare members. (saved_dabr_value, hwdebug_info, max_slots_number) (struct hw_break_tuple, struct thread_points, ppc_threads) (have_ptrace_hwdebug_interface) (hwdebug_find_thread_points_by_tid) (hwdebug_insert_point, hwdebug_remove_point): Remove. (ppc_linux_nat_target::can_use_hw_breakpoint): Use m_dreg_interface, remove call to PTRACE_SET_DEBUGREG. (ppc_linux_nat_target::region_ok_for_hw_watchpoint): Add comment, use m_dreg_interface. (hwdebug_point_cmp): Change to... (ppc_linux_nat_target::hwdebug_point_cmp): ...this method. Use reference arguments instead of pointers. (ppc_linux_nat_target::ranged_break_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::insert_hw_breakpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_hw_breakpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint. (get_trigger_type): Change to... (ppc_linux_nat_target::get_trigger_type): ...this method. Add comment. (ppc_linux_nat_target::insert_mask_watchpoint): Update comment, use m_dreg_interface. Call register_hw_breakpoint. (ppc_linux_nat_target::remove_mask_watchpoint): Update comment, use m_dreg_interface. Call clear_hw_breakpoint. (can_use_watchpoint_cond_accel): Change to... (ppc_linux_nat_target::can_use_watchpoint_cond_accel): ...this method. Update comment, use m_dreg_interface and m_process_info. (calculate_dvc): Change to... (ppc_linux_nat_target::calculate_dvc): ...this method. Use m_dreg_interface. (num_memory_accesses): Change to... (ppc_linux_nat_target::num_memory_accesses): ...this method. (check_condition): Change to... (ppc_linux_nat_target::check_condition): ...this method. (ppc_linux_nat_target::can_accel_watchpoint_condition): Update comment, use m_dreg_interface. (create_watchpoint_request): Change to... (ppc_linux_nat_target::create_watchpoint_request): ...this method. Use m_dreg_interface. (ppc_linux_nat_target::insert_watchpoint): Add comment, use m_dreg_interface. Call register_hw_breakpoint or register_wp. (ppc_linux_nat_target::remove_watchpoint): Add comment, use m_dreg_interface. Call clear_hw_breakpoint or clear_wp. (ppc_linux_nat_target::low_forget_process) (ppc_linux_nat_target::low_new_fork) (ppc_linux_nat_target::low_new_clone) (ppc_linux_nat_target::low_delete_thread) (ppc_linux_nat_target::low_prepare_to_resume): New methods. (ppc_linux_nat_target::low_new_thread): Remove previous logic, only call mark_thread_stale. (ppc_linux_thread_exit): Remove. (ppc_linux_nat_target::stopped_data_address): Change to... (ppc_linux_nat_target::low_stopped_data_address): This. Add comment, use m_dreg_interface and m_thread_hw_breakpoints. (ppc_linux_nat_target::stopped_by_watchpoint): Change to... (ppc_linux_nat_target::stopped_by_watchpoint): This. Add comment. Call low_stopped_data_address. (ppc_linux_nat_target::watchpoint_addr_within_range): Use m_dreg_interface. (ppc_linux_nat_target::masked_watch_num_registers): Use m_dreg_interface. (ppc_linux_nat_target::copy_thread_dreg_state) (ppc_linux_nat_target::mark_thread_stale) (ppc_linux_nat_target::mark_debug_registers_changed) (ppc_linux_nat_target::register_hw_breakpoint) (ppc_linux_nat_target::clear_hw_breakpoint) (ppc_linux_nat_target::register_wp) (ppc_linux_nat_target::clear_wp) (ppc_linux_nat_target::init_arch_lwp_info) (ppc_linux_nat_target::get_arch_lwp_info): New methods. (_initialize_ppc_linux_nat): Remove observer callback.
2020-03-30 23:04:25 +08:00
/* Copy the per-thread debug register state, if any, from thread
PARENT_PTID to thread CHILD_PTID, if the debug register being used is
HWDEBUG. */
void
ppc_linux_nat_target::copy_thread_dreg_state (const ptid_t &parent_ptid,
const ptid_t &child_ptid)
{
gdb_assert (m_dreg_interface.hwdebug_p ());
auto installed_it = m_installed_hw_bps.find (parent_ptid);
if (installed_it != m_installed_hw_bps.end ())
m_installed_hw_bps[child_ptid] = m_installed_hw_bps[parent_ptid];
}
/* Mark the debug register stale flag for the new thread, if we have
already detected which debug register interface we use. */
void
ppc_linux_nat_target::mark_thread_stale (struct lwp_info *lp)
{
if ((!m_dreg_interface.detected_p ())
|| (m_dreg_interface.unavailable_p ()))
return;
arch_lwp_info *lp_arch_info = get_arch_lwp_info (lp);
lp_arch_info->debug_regs_stale = true;
}
/* Mark all the threads of the group of PID as stale with respect to
debug registers and issue a stop request to each such thread that
isn't already stopped. */
void
ppc_linux_nat_target::mark_debug_registers_changed (pid_t pid)
{
/* We do this in two passes to make sure all threads are marked even if
we get an exception when stopping one of them. */
iterate_over_lwps (ptid_t (pid),
[this] (struct lwp_info *lp) -> int {
this->mark_thread_stale (lp);
return 0;
});
iterate_over_lwps (ptid_t (pid),
[] (struct lwp_info *lp) -> int {
if (!lwp_is_stopped (lp))
linux_stop_lwp (lp);
return 0;
});
}
/* Register a hardware breakpoint or watchpoint BP for the pid PID, then
mark the stale flag for all threads of the group of PID, and issue a
stop request for them. The breakpoint or watchpoint will be installed
the next time each thread is resumed. Should only be used if the
debug register interface is HWDEBUG. */
void
ppc_linux_nat_target::register_hw_breakpoint (pid_t pid,
const struct
ppc_hw_breakpoint &bp)
{
gdb_assert (m_dreg_interface.hwdebug_p ());
m_process_info[pid].requested_hw_bps.push_back (bp);
mark_debug_registers_changed (pid);
}
/* Clear a registration for a hardware breakpoint or watchpoint BP for
the pid PID, then mark the stale flag for all threads of the group of
PID, and issue a stop request for them. The breakpoint or watchpoint
will be removed the next time each thread is resumed. Should only be
used if the debug register interface is HWDEBUG. */
void
ppc_linux_nat_target::clear_hw_breakpoint (pid_t pid,
const struct ppc_hw_breakpoint &bp)
{
gdb_assert (m_dreg_interface.hwdebug_p ());
auto process_it = m_process_info.find (pid);
gdb_assert (process_it != m_process_info.end ());
auto bp_it = std::find_if (process_it->second.requested_hw_bps.begin (),
process_it->second.requested_hw_bps.end (),
[&bp, this]
(const struct ppc_hw_breakpoint &curr)
{ return hwdebug_point_cmp (bp, curr); }
);
/* If GDB is removing a watchpoint, it must have been inserted. */
gdb_assert (bp_it != process_it->second.requested_hw_bps.end ());
process_it->second.requested_hw_bps.erase (bp_it);
mark_debug_registers_changed (pid);
}
/* Register the hardware watchpoint value WP_VALUE for the pid PID,
then mark the stale flag for all threads of the group of PID, and
issue a stop request for them. The breakpoint or watchpoint will be
installed the next time each thread is resumed. Should only be used
if the debug register interface is DEBUGREG. */
void
ppc_linux_nat_target::register_wp (pid_t pid, long wp_value)
{
gdb_assert (m_dreg_interface.debugreg_p ());
/* Our other functions should have told GDB that we only have one
hardware watchpoint with this interface. */
gdb_assert (!m_process_info[pid].requested_wp_val.has_value ());
m_process_info[pid].requested_wp_val.emplace (wp_value);
mark_debug_registers_changed (pid);
}
/* Clear the hardware watchpoint registration for the pid PID, then mark
the stale flag for all threads of the group of PID, and issue a stop
request for them. The breakpoint or watchpoint will be installed the
next time each thread is resumed. Should only be used if the debug
register interface is DEBUGREG. */
void
ppc_linux_nat_target::clear_wp (pid_t pid)
{
gdb_assert (m_dreg_interface.debugreg_p ());
auto process_it = m_process_info.find (pid);
gdb_assert (process_it != m_process_info.end ());
gdb_assert (process_it->second.requested_wp_val.has_value ());
process_it->second.requested_wp_val.reset ();
mark_debug_registers_changed (pid);
}
/* Initialize the arch-specific thread state for LWP, if it not already
created. */
void
ppc_linux_nat_target::init_arch_lwp_info (struct lwp_info *lp)
{
if (lwp_arch_private_info (lp) == NULL)
{
lwp_set_arch_private_info (lp, XCNEW (struct arch_lwp_info));
lwp_arch_private_info (lp)->debug_regs_stale = false;
lwp_arch_private_info (lp)->lwp_ptid = lp->ptid;
}
}
/* Get the arch-specific thread state for LWP, creating it if
necessary. */
arch_lwp_info *
ppc_linux_nat_target::get_arch_lwp_info (struct lwp_info *lp)
{
init_arch_lwp_info (lp);
return lwp_arch_private_info (lp);
}
gdb: add back declarations for _initialize functions I'd like to enable the -Wmissing-declarations warning. However, it warns for every _initialize function, for example: CXX dcache.o /home/smarchi/src/binutils-gdb/gdb/dcache.c: In function ‘void _initialize_dcache()’: /home/smarchi/src/binutils-gdb/gdb/dcache.c:688:1: error: no previous declaration for ‘void _initialize_dcache()’ [-Werror=missing-declarations] _initialize_dcache (void) ^~~~~~~~~~~~~~~~~~ The only practical way forward I found is to add back the declarations, which were removed by this commit: commit 481695ed5f6e0a8a9c9c50bfac1cdd2b3151e6c9 Author: John Baldwin <jhb@FreeBSD.org> Date: Sat Sep 9 11:02:37 2017 -0700 Remove unnecessary function prototypes. I don't think it's a big problem to have the declarations for these functions, but if anybody has a better solution for this, I'll be happy to use it. gdb/ChangeLog: * aarch64-fbsd-nat.c (_initialize_aarch64_fbsd_nat): Add declaration. * aarch64-fbsd-tdep.c (_initialize_aarch64_fbsd_tdep): Add declaration. * aarch64-linux-nat.c (_initialize_aarch64_linux_nat): Add declaration. * aarch64-linux-tdep.c (_initialize_aarch64_linux_tdep): Add declaration. * aarch64-newlib-tdep.c (_initialize_aarch64_newlib_tdep): Add declaration. * aarch64-tdep.c (_initialize_aarch64_tdep): Add declaration. * ada-exp.y (_initialize_ada_exp): Add declaration. * ada-lang.c (_initialize_ada_language): Add declaration. * ada-tasks.c (_initialize_tasks): Add declaration. * agent.c (_initialize_agent): Add declaration. * aix-thread.c (_initialize_aix_thread): Add declaration. * alpha-bsd-nat.c (_initialize_alphabsd_nat): Add declaration. * alpha-linux-nat.c (_initialize_alpha_linux_nat): Add declaration. * alpha-linux-tdep.c (_initialize_alpha_linux_tdep): Add declaration. * alpha-nbsd-tdep.c (_initialize_alphanbsd_tdep): Add declaration. * alpha-obsd-tdep.c (_initialize_alphaobsd_tdep): Add declaration. * alpha-tdep.c (_initialize_alpha_tdep): Add declaration. * amd64-darwin-tdep.c (_initialize_amd64_darwin_tdep): Add declaration. * amd64-dicos-tdep.c (_initialize_amd64_dicos_tdep): Add declaration. * amd64-fbsd-nat.c (_initialize_amd64fbsd_nat): Add declaration. * amd64-fbsd-tdep.c (_initialize_amd64fbsd_tdep): Add declaration. * amd64-linux-nat.c (_initialize_amd64_linux_nat): Add declaration. * amd64-linux-tdep.c (_initialize_amd64_linux_tdep): Add declaration. * amd64-nbsd-nat.c (_initialize_amd64nbsd_nat): Add declaration. * amd64-nbsd-tdep.c (_initialize_amd64nbsd_tdep): Add declaration. * amd64-obsd-nat.c (_initialize_amd64obsd_nat): Add declaration. * amd64-obsd-tdep.c (_initialize_amd64obsd_tdep): Add declaration. * amd64-sol2-tdep.c (_initialize_amd64_sol2_tdep): Add declaration. * amd64-tdep.c (_initialize_amd64_tdep): Add declaration. * amd64-windows-nat.c (_initialize_amd64_windows_nat): Add declaration. * amd64-windows-tdep.c (_initialize_amd64_windows_tdep): Add declaration. * annotate.c (_initialize_annotate): Add declaration. * arc-newlib-tdep.c (_initialize_arc_newlib_tdep): Add declaration. * arc-tdep.c (_initialize_arc_tdep): Add declaration. * arch-utils.c (_initialize_gdbarch_utils): Add declaration. * arm-fbsd-nat.c (_initialize_arm_fbsd_nat): Add declaration. * arm-fbsd-tdep.c (_initialize_arm_fbsd_tdep): Add declaration. * arm-linux-nat.c (_initialize_arm_linux_nat): Add declaration. * arm-linux-tdep.c (_initialize_arm_linux_tdep): Add declaration. * arm-nbsd-nat.c (_initialize_arm_netbsd_nat): Add declaration. * arm-nbsd-tdep.c (_initialize_arm_netbsd_tdep): Add declaration. * arm-obsd-tdep.c (_initialize_armobsd_tdep): Add declaration. * arm-pikeos-tdep.c (_initialize_arm_pikeos_tdep): Add declaration. * arm-symbian-tdep.c (_initialize_arm_symbian_tdep): Add declaration. * arm-tdep.c (_initialize_arm_tdep): Add declaration. * arm-wince-tdep.c (_initialize_arm_wince_tdep): Add declaration. * auto-load.c (_initialize_auto_load): Add declaration. * auxv.c (_initialize_auxv): Add declaration. * avr-tdep.c (_initialize_avr_tdep): Add declaration. * ax-gdb.c (_initialize_ax_gdb): Add declaration. * bfin-linux-tdep.c (_initialize_bfin_linux_tdep): Add declaration. * bfin-tdep.c (_initialize_bfin_tdep): Add declaration. * break-catch-sig.c (_initialize_break_catch_sig): Add declaration. * break-catch-syscall.c (_initialize_break_catch_syscall): Add declaration. * break-catch-throw.c (_initialize_break_catch_throw): Add declaration. * breakpoint.c (_initialize_breakpoint): Add declaration. * bsd-uthread.c (_initialize_bsd_uthread): Add declaration. * btrace.c (_initialize_btrace): Add declaration. * charset.c (_initialize_charset): Add declaration. * cli/cli-cmds.c (_initialize_cli_cmds): Add declaration. * cli/cli-dump.c (_initialize_cli_dump): Add declaration. * cli/cli-interp.c (_initialize_cli_interp): Add declaration. * cli/cli-logging.c (_initialize_cli_logging): Add declaration. * cli/cli-script.c (_initialize_cli_script): Add declaration. * cli/cli-style.c (_initialize_cli_style): Add declaration. * coff-pe-read.c (_initialize_coff_pe_read): Add declaration. * coffread.c (_initialize_coffread): Add declaration. * compile/compile-cplus-types.c (_initialize_compile_cplus_types): Add declaration. * compile/compile.c (_initialize_compile): Add declaration. * complaints.c (_initialize_complaints): Add declaration. * completer.c (_initialize_completer): Add declaration. * copying.c (_initialize_copying): Add declaration. * corefile.c (_initialize_core): Add declaration. * corelow.c (_initialize_corelow): Add declaration. * cp-abi.c (_initialize_cp_abi): Add declaration. * cp-namespace.c (_initialize_cp_namespace): Add declaration. * cp-support.c (_initialize_cp_support): Add declaration. * cp-valprint.c (_initialize_cp_valprint): Add declaration. * cris-linux-tdep.c (_initialize_cris_linux_tdep): Add declaration. * cris-tdep.c (_initialize_cris_tdep): Add declaration. * csky-linux-tdep.c (_initialize_csky_linux_tdep): Add declaration. * csky-tdep.c (_initialize_csky_tdep): Add declaration. * ctfread.c (_initialize_ctfread): Add declaration. * d-lang.c (_initialize_d_language): Add declaration. * darwin-nat-info.c (_initialize_darwin_info_commands): Add declaration. * darwin-nat.c (_initialize_darwin_nat): Add declaration. * dbxread.c (_initialize_dbxread): Add declaration. * dcache.c (_initialize_dcache): Add declaration. * disasm-selftests.c (_initialize_disasm_selftests): Add declaration. * disasm.c (_initialize_disasm): Add declaration. * dtrace-probe.c (_initialize_dtrace_probe): Add declaration. * dummy-frame.c (_initialize_dummy_frame): Add declaration. * dwarf-index-cache.c (_initialize_index_cache): Add declaration. * dwarf-index-write.c (_initialize_dwarf_index_write): Add declaration. * dwarf2-frame-tailcall.c (_initialize_tailcall_frame): Add declaration. * dwarf2-frame.c (_initialize_dwarf2_frame): Add declaration. * dwarf2expr.c (_initialize_dwarf2expr): Add declaration. * dwarf2loc.c (_initialize_dwarf2loc): Add declaration. * dwarf2read.c (_initialize_dwarf2_read): Add declaration. * elfread.c (_initialize_elfread): Add declaration. * exec.c (_initialize_exec): Add declaration. * extension.c (_initialize_extension): Add declaration. * f-lang.c (_initialize_f_language): Add declaration. * f-valprint.c (_initialize_f_valprint): Add declaration. * fbsd-nat.c (_initialize_fbsd_nat): Add declaration. * fbsd-tdep.c (_initialize_fbsd_tdep): Add declaration. * filesystem.c (_initialize_filesystem): Add declaration. * findcmd.c (_initialize_mem_search): Add declaration. * findvar.c (_initialize_findvar): Add declaration. * fork-child.c (_initialize_fork_child): Add declaration. * frame-base.c (_initialize_frame_base): Add declaration. * frame-unwind.c (_initialize_frame_unwind): Add declaration. * frame.c (_initialize_frame): Add declaration. * frv-linux-tdep.c (_initialize_frv_linux_tdep): Add declaration. * frv-tdep.c (_initialize_frv_tdep): Add declaration. * ft32-tdep.c (_initialize_ft32_tdep): Add declaration. * gcore.c (_initialize_gcore): Add declaration. * gdb-demangle.c (_initialize_gdb_demangle): Add declaration. * gdb_bfd.c (_initialize_gdb_bfd): Add declaration. * gdbarch-selftests.c (_initialize_gdbarch_selftests): Add declaration. * gdbarch.c (_initialize_gdbarch): Add declaration. * gdbtypes.c (_initialize_gdbtypes): Add declaration. * gnu-nat.c (_initialize_gnu_nat): Add declaration. * gnu-v2-abi.c (_initialize_gnu_v2_abi): Add declaration. * gnu-v3-abi.c (_initialize_gnu_v3_abi): Add declaration. * go-lang.c (_initialize_go_language): Add declaration. * go32-nat.c (_initialize_go32_nat): Add declaration. * guile/guile.c (_initialize_guile): Add declaration. * h8300-tdep.c (_initialize_h8300_tdep): Add declaration. * hppa-linux-nat.c (_initialize_hppa_linux_nat): Add declaration. * hppa-linux-tdep.c (_initialize_hppa_linux_tdep): Add declaration. * hppa-nbsd-nat.c (_initialize_hppanbsd_nat): Add declaration. * hppa-nbsd-tdep.c (_initialize_hppanbsd_tdep): Add declaration. * hppa-obsd-nat.c (_initialize_hppaobsd_nat): Add declaration. * hppa-obsd-tdep.c (_initialize_hppabsd_tdep): Add declaration. * hppa-tdep.c (_initialize_hppa_tdep): Add declaration. * i386-bsd-nat.c (_initialize_i386bsd_nat): Add declaration. * i386-cygwin-tdep.c (_initialize_i386_cygwin_tdep): Add declaration. * i386-darwin-nat.c (_initialize_i386_darwin_nat): Add declaration. * i386-darwin-tdep.c (_initialize_i386_darwin_tdep): Add declaration. * i386-dicos-tdep.c (_initialize_i386_dicos_tdep): Add declaration. * i386-fbsd-nat.c (_initialize_i386fbsd_nat): Add declaration. * i386-fbsd-tdep.c (_initialize_i386fbsd_tdep): Add declaration. * i386-gnu-nat.c (_initialize_i386gnu_nat): Add declaration. * i386-gnu-tdep.c (_initialize_i386gnu_tdep): Add declaration. * i386-go32-tdep.c (_initialize_i386_go32_tdep): Add declaration. * i386-linux-nat.c (_initialize_i386_linux_nat): Add declaration. * i386-linux-tdep.c (_initialize_i386_linux_tdep): Add declaration. * i386-nbsd-nat.c (_initialize_i386nbsd_nat): Add declaration. * i386-nbsd-tdep.c (_initialize_i386nbsd_tdep): Add declaration. * i386-nto-tdep.c (_initialize_i386nto_tdep): Add declaration. * i386-obsd-nat.c (_initialize_i386obsd_nat): Add declaration. * i386-obsd-tdep.c (_initialize_i386obsd_tdep): Add declaration. * i386-sol2-nat.c (_initialize_amd64_sol2_nat): Add declaration. * i386-sol2-tdep.c (_initialize_i386_sol2_tdep): Add declaration. * i386-tdep.c (_initialize_i386_tdep): Add declaration. * i386-windows-nat.c (_initialize_i386_windows_nat): Add declaration. * ia64-libunwind-tdep.c (_initialize_libunwind_frame): Add declaration. * ia64-linux-nat.c (_initialize_ia64_linux_nat): Add declaration. * ia64-linux-tdep.c (_initialize_ia64_linux_tdep): Add declaration. * ia64-tdep.c (_initialize_ia64_tdep): Add declaration. * ia64-vms-tdep.c (_initialize_ia64_vms_tdep): Add declaration. * infcall.c (_initialize_infcall): Add declaration. * infcmd.c (_initialize_infcmd): Add declaration. * inflow.c (_initialize_inflow): Add declaration. * infrun.c (_initialize_infrun): Add declaration. * interps.c (_initialize_interpreter): Add declaration. * iq2000-tdep.c (_initialize_iq2000_tdep): Add declaration. * jit.c (_initialize_jit): Add declaration. * language.c (_initialize_language): Add declaration. * linux-fork.c (_initialize_linux_fork): Add declaration. * linux-nat.c (_initialize_linux_nat): Add declaration. * linux-tdep.c (_initialize_linux_tdep): Add declaration. * linux-thread-db.c (_initialize_thread_db): Add declaration. * lm32-tdep.c (_initialize_lm32_tdep): Add declaration. * m2-lang.c (_initialize_m2_language): Add declaration. * m32c-tdep.c (_initialize_m32c_tdep): Add declaration. * m32r-linux-nat.c (_initialize_m32r_linux_nat): Add declaration. * m32r-linux-tdep.c (_initialize_m32r_linux_tdep): Add declaration. * m32r-tdep.c (_initialize_m32r_tdep): Add declaration. * m68hc11-tdep.c (_initialize_m68hc11_tdep): Add declaration. * m68k-bsd-nat.c (_initialize_m68kbsd_nat): Add declaration. * m68k-bsd-tdep.c (_initialize_m68kbsd_tdep): Add declaration. * m68k-linux-nat.c (_initialize_m68k_linux_nat): Add declaration. * m68k-linux-tdep.c (_initialize_m68k_linux_tdep): Add declaration. * m68k-tdep.c (_initialize_m68k_tdep): Add declaration. * machoread.c (_initialize_machoread): Add declaration. * macrocmd.c (_initialize_macrocmd): Add declaration. * macroscope.c (_initialize_macroscope): Add declaration. * maint-test-options.c (_initialize_maint_test_options): Add declaration. * maint-test-settings.c (_initialize_maint_test_settings): Add declaration. * maint.c (_initialize_maint_cmds): Add declaration. * mdebugread.c (_initialize_mdebugread): Add declaration. * memattr.c (_initialize_mem): Add declaration. * mep-tdep.c (_initialize_mep_tdep): Add declaration. * mi/mi-cmd-env.c (_initialize_mi_cmd_env): Add declaration. * mi/mi-cmds.c (_initialize_mi_cmds): Add declaration. * mi/mi-interp.c (_initialize_mi_interp): Add declaration. * mi/mi-main.c (_initialize_mi_main): Add declaration. * microblaze-linux-tdep.c (_initialize_microblaze_linux_tdep): Add declaration. * microblaze-tdep.c (_initialize_microblaze_tdep): Add declaration. * mips-fbsd-nat.c (_initialize_mips_fbsd_nat): Add declaration. * mips-fbsd-tdep.c (_initialize_mips_fbsd_tdep): Add declaration. * mips-linux-nat.c (_initialize_mips_linux_nat): Add declaration. * mips-linux-tdep.c (_initialize_mips_linux_tdep): Add declaration. * mips-nbsd-nat.c (_initialize_mipsnbsd_nat): Add declaration. * mips-nbsd-tdep.c (_initialize_mipsnbsd_tdep): Add declaration. * mips-sde-tdep.c (_initialize_mips_sde_tdep): Add declaration. * mips-tdep.c (_initialize_mips_tdep): Add declaration. * mips64-obsd-nat.c (_initialize_mips64obsd_nat): Add declaration. * mips64-obsd-tdep.c (_initialize_mips64obsd_tdep): Add declaration. * mipsread.c (_initialize_mipsread): Add declaration. * mn10300-linux-tdep.c (_initialize_mn10300_linux_tdep): Add declaration. * mn10300-tdep.c (_initialize_mn10300_tdep): Add declaration. * moxie-tdep.c (_initialize_moxie_tdep): Add declaration. * msp430-tdep.c (_initialize_msp430_tdep): Add declaration. * nds32-tdep.c (_initialize_nds32_tdep): Add declaration. * nios2-linux-tdep.c (_initialize_nios2_linux_tdep): Add declaration. * nios2-tdep.c (_initialize_nios2_tdep): Add declaration. * nto-procfs.c (_initialize_procfs): Add declaration. * objc-lang.c (_initialize_objc_language): Add declaration. * observable.c (_initialize_observer): Add declaration. * opencl-lang.c (_initialize_opencl_language): Add declaration. * or1k-linux-tdep.c (_initialize_or1k_linux_tdep): Add declaration. * or1k-tdep.c (_initialize_or1k_tdep): Add declaration. * osabi.c (_initialize_gdb_osabi): Add declaration. * osdata.c (_initialize_osdata): Add declaration. * p-valprint.c (_initialize_pascal_valprint): Add declaration. * parse.c (_initialize_parse): Add declaration. * ppc-fbsd-nat.c (_initialize_ppcfbsd_nat): Add declaration. * ppc-fbsd-tdep.c (_initialize_ppcfbsd_tdep): Add declaration. * ppc-linux-nat.c (_initialize_ppc_linux_nat): Add declaration. * ppc-linux-tdep.c (_initialize_ppc_linux_tdep): Add declaration. * ppc-nbsd-nat.c (_initialize_ppcnbsd_nat): Add declaration. * ppc-nbsd-tdep.c (_initialize_ppcnbsd_tdep): Add declaration. * ppc-obsd-nat.c (_initialize_ppcobsd_nat): Add declaration. * ppc-obsd-tdep.c (_initialize_ppcobsd_tdep): Add declaration. * printcmd.c (_initialize_printcmd): Add declaration. * probe.c (_initialize_probe): Add declaration. * proc-api.c (_initialize_proc_api): Add declaration. * proc-events.c (_initialize_proc_events): Add declaration. * proc-service.c (_initialize_proc_service): Add declaration. * procfs.c (_initialize_procfs): Add declaration. * producer.c (_initialize_producer): Add declaration. * psymtab.c (_initialize_psymtab): Add declaration. * python/python.c (_initialize_python): Add declaration. * ravenscar-thread.c (_initialize_ravenscar): Add declaration. * record-btrace.c (_initialize_record_btrace): Add declaration. * record-full.c (_initialize_record_full): Add declaration. * record.c (_initialize_record): Add declaration. * regcache-dump.c (_initialize_regcache_dump): Add declaration. * regcache.c (_initialize_regcache): Add declaration. * reggroups.c (_initialize_reggroup): Add declaration. * remote-notif.c (_initialize_notif): Add declaration. * remote-sim.c (_initialize_remote_sim): Add declaration. * remote.c (_initialize_remote): Add declaration. * reverse.c (_initialize_reverse): Add declaration. * riscv-fbsd-nat.c (_initialize_riscv_fbsd_nat): Add declaration. * riscv-fbsd-tdep.c (_initialize_riscv_fbsd_tdep): Add declaration. * riscv-linux-nat.c (_initialize_riscv_linux_nat): Add declaration. * riscv-linux-tdep.c (_initialize_riscv_linux_tdep): Add declaration. * riscv-tdep.c (_initialize_riscv_tdep): Add declaration. * rl78-tdep.c (_initialize_rl78_tdep): Add declaration. * rs6000-aix-tdep.c (_initialize_rs6000_aix_tdep): Add declaration. * rs6000-lynx178-tdep.c (_initialize_rs6000_lynx178_tdep): Add declaration. * rs6000-nat.c (_initialize_rs6000_nat): Add declaration. * rs6000-tdep.c (_initialize_rs6000_tdep): Add declaration. * run-on-main-thread.c (_initialize_run_on_main_thread): Add declaration. * rust-exp.y (_initialize_rust_exp): Add declaration. * rx-tdep.c (_initialize_rx_tdep): Add declaration. * s12z-tdep.c (_initialize_s12z_tdep): Add declaration. * s390-linux-nat.c (_initialize_s390_nat): Add declaration. * s390-linux-tdep.c (_initialize_s390_linux_tdep): Add declaration. * s390-tdep.c (_initialize_s390_tdep): Add declaration. * score-tdep.c (_initialize_score_tdep): Add declaration. * ser-go32.c (_initialize_ser_dos): Add declaration. * ser-mingw.c (_initialize_ser_windows): Add declaration. * ser-pipe.c (_initialize_ser_pipe): Add declaration. * ser-tcp.c (_initialize_ser_tcp): Add declaration. * ser-uds.c (_initialize_ser_socket): Add declaration. * ser-unix.c (_initialize_ser_hardwire): Add declaration. * serial.c (_initialize_serial): Add declaration. * sh-linux-tdep.c (_initialize_sh_linux_tdep): Add declaration. * sh-nbsd-nat.c (_initialize_shnbsd_nat): Add declaration. * sh-nbsd-tdep.c (_initialize_shnbsd_tdep): Add declaration. * sh-tdep.c (_initialize_sh_tdep): Add declaration. * skip.c (_initialize_step_skip): Add declaration. * sol-thread.c (_initialize_sol_thread): Add declaration. * solib-aix.c (_initialize_solib_aix): Add declaration. * solib-darwin.c (_initialize_darwin_solib): Add declaration. * solib-dsbt.c (_initialize_dsbt_solib): Add declaration. * solib-frv.c (_initialize_frv_solib): Add declaration. * solib-svr4.c (_initialize_svr4_solib): Add declaration. * solib-target.c (_initialize_solib_target): Add declaration. * solib.c (_initialize_solib): Add declaration. * source-cache.c (_initialize_source_cache): Add declaration. * source.c (_initialize_source): Add declaration. * sparc-linux-nat.c (_initialize_sparc_linux_nat): Add declaration. * sparc-linux-tdep.c (_initialize_sparc_linux_tdep): Add declaration. * sparc-nat.c (_initialize_sparc_nat): Add declaration. * sparc-nbsd-nat.c (_initialize_sparcnbsd_nat): Add declaration. * sparc-nbsd-tdep.c (_initialize_sparcnbsd_tdep): Add declaration. * sparc-obsd-tdep.c (_initialize_sparc32obsd_tdep): Add declaration. * sparc-sol2-tdep.c (_initialize_sparc_sol2_tdep): Add declaration. * sparc-tdep.c (_initialize_sparc_tdep): Add declaration. * sparc64-fbsd-nat.c (_initialize_sparc64fbsd_nat): Add declaration. * sparc64-fbsd-tdep.c (_initialize_sparc64fbsd_tdep): Add declaration. * sparc64-linux-nat.c (_initialize_sparc64_linux_nat): Add declaration. * sparc64-linux-tdep.c (_initialize_sparc64_linux_tdep): Add declaration. * sparc64-nat.c (_initialize_sparc64_nat): Add declaration. * sparc64-nbsd-nat.c (_initialize_sparc64nbsd_nat): Add declaration. * sparc64-nbsd-tdep.c (_initialize_sparc64nbsd_tdep): Add declaration. * sparc64-obsd-nat.c (_initialize_sparc64obsd_nat): Add declaration. * sparc64-obsd-tdep.c (_initialize_sparc64obsd_tdep): Add declaration. * sparc64-sol2-tdep.c (_initialize_sparc64_sol2_tdep): Add declaration. * sparc64-tdep.c (_initialize_sparc64_adi_tdep): Add declaration. * stabsread.c (_initialize_stabsread): Add declaration. * stack.c (_initialize_stack): Add declaration. * stap-probe.c (_initialize_stap_probe): Add declaration. * std-regs.c (_initialize_frame_reg): Add declaration. * symfile-debug.c (_initialize_symfile_debug): Add declaration. * symfile-mem.c (_initialize_symfile_mem): Add declaration. * symfile.c (_initialize_symfile): Add declaration. * symmisc.c (_initialize_symmisc): Add declaration. * symtab.c (_initialize_symtab): Add declaration. * target.c (_initialize_target): Add declaration. * target-connection.c (_initialize_target_connection): Add declaration. * target-dcache.c (_initialize_target_dcache): Add declaration. * target-descriptions.c (_initialize_target_descriptions): Add declaration. * thread.c (_initialize_thread): Add declaration. * tic6x-linux-tdep.c (_initialize_tic6x_linux_tdep): Add declaration. * tic6x-tdep.c (_initialize_tic6x_tdep): Add declaration. * tilegx-linux-nat.c (_initialize_tile_linux_nat): Add declaration. * tilegx-linux-tdep.c (_initialize_tilegx_linux_tdep): Add declaration. * tilegx-tdep.c (_initialize_tilegx_tdep): Add declaration. * tracectf.c (_initialize_ctf): Add declaration. * tracefile-tfile.c (_initialize_tracefile_tfile): Add declaration. * tracefile.c (_initialize_tracefile): Add declaration. * tracepoint.c (_initialize_tracepoint): Add declaration. * tui/tui-hooks.c (_initialize_tui_hooks): Add declaration. * tui/tui-interp.c (_initialize_tui_interp): Add declaration. * tui/tui-layout.c (_initialize_tui_layout): Add declaration. * tui/tui-regs.c (_initialize_tui_regs): Add declaration. * tui/tui-stack.c (_initialize_tui_stack): Add declaration. * tui/tui-win.c (_initialize_tui_win): Add declaration. * tui/tui.c (_initialize_tui): Add declaration. * typeprint.c (_initialize_typeprint): Add declaration. * ui-style.c (_initialize_ui_style): Add declaration. * unittests/array-view-selftests.c (_initialize_array_view_selftests): Add declaration. * unittests/child-path-selftests.c (_initialize_child_path_selftests): Add declaration. * unittests/cli-utils-selftests.c (_initialize_cli_utils_selftests): Add declaration. * unittests/common-utils-selftests.c (_initialize_common_utils_selftests): Add declaration. * unittests/copy_bitwise-selftests.c (_initialize_copy_bitwise_utils_selftests): Add declaration. * unittests/environ-selftests.c (_initialize_environ_selftests): Add declaration. * unittests/filtered_iterator-selftests.c (_initialize_filtered_iterator_selftests): Add declaration. * unittests/format_pieces-selftests.c (_initialize_format_pieces_selftests): Add declaration. * unittests/function-view-selftests.c (_initialize_function_view_selftests): Add declaration. * unittests/help-doc-selftests.c (_initialize_help_doc_selftests): Add declaration. * unittests/lookup_name_info-selftests.c (_initialize_lookup_name_info_selftests): Add declaration. * unittests/main-thread-selftests.c (_initialize_main_thread_selftests): Add declaration. * unittests/memory-map-selftests.c (_initialize_memory_map_selftests): Add declaration. * unittests/memrange-selftests.c (_initialize_memrange_selftests): Add declaration. * unittests/mkdir-recursive-selftests.c (_initialize_mkdir_recursive_selftests): Add declaration. * unittests/observable-selftests.c (_initialize_observer_selftest): Add declaration. * unittests/offset-type-selftests.c (_initialize_offset_type_selftests): Add declaration. * unittests/optional-selftests.c (_initialize_optional_selftests): Add declaration. * unittests/parse-connection-spec-selftests.c (_initialize_parse_connection_spec_selftests): Add declaration. * unittests/rsp-low-selftests.c (_initialize_rsp_low_selftests): Add declaration. * unittests/scoped_fd-selftests.c (_initialize_scoped_fd_selftests): Add declaration. * unittests/scoped_mmap-selftests.c (_initialize_scoped_mmap_selftests): Add declaration. * unittests/scoped_restore-selftests.c (_initialize_scoped_restore_selftests): Add declaration. * unittests/string_view-selftests.c (_initialize_string_view_selftests): Add declaration. * unittests/style-selftests.c (_initialize_style_selftest): Add declaration. * unittests/tracepoint-selftests.c (_initialize_tracepoint_selftests): Add declaration. * unittests/tui-selftests.c (_initialize_tui_selftest): Add declaration. * unittests/unpack-selftests.c (_initialize_unpack_selftests): Add declaration. * unittests/utils-selftests.c (_initialize_utils_selftests): Add declaration. * unittests/vec-utils-selftests.c (_initialize_vec_utils_selftests): Add declaration. * unittests/xml-utils-selftests.c (_initialize_xml_utils): Add declaration. * user-regs.c (_initialize_user_regs): Add declaration. * utils.c (_initialize_utils): Add declaration. * v850-tdep.c (_initialize_v850_tdep): Add declaration. * valops.c (_initialize_valops): Add declaration. * valprint.c (_initialize_valprint): Add declaration. * value.c (_initialize_values): Add declaration. * varobj.c (_initialize_varobj): Add declaration. * vax-bsd-nat.c (_initialize_vaxbsd_nat): Add declaration. * vax-nbsd-tdep.c (_initialize_vaxnbsd_tdep): Add declaration. * vax-tdep.c (_initialize_vax_tdep): Add declaration. * windows-nat.c (_initialize_windows_nat): Add declaration. (_initialize_check_for_gdb_ini): Add declaration. (_initialize_loadable): Add declaration. * windows-tdep.c (_initialize_windows_tdep): Add declaration. * x86-bsd-nat.c (_initialize_x86_bsd_nat): Add declaration. * x86-linux-nat.c (_initialize_x86_linux_nat): Add declaration. * xcoffread.c (_initialize_xcoffread): Add declaration. * xml-support.c (_initialize_xml_support): Add declaration. * xstormy16-tdep.c (_initialize_xstormy16_tdep): Add declaration. * xtensa-linux-nat.c (_initialize_xtensa_linux_nat): Add declaration. * xtensa-linux-tdep.c (_initialize_xtensa_linux_tdep): Add declaration. * xtensa-tdep.c (_initialize_xtensa_tdep): Add declaration. Change-Id: I13eec7e0ed2b3c427377a7bdb055cf46da64def9
2020-01-14 03:01:38 +08:00
void _initialize_ppc_linux_nat ();
* Makefile.in (ALLDEPFILES): Update. (alpha-linux-nat.o, sparc-linux-nat.o): New rules. (amd64-linux-nat.o, arm-linux-nat.o, hppa-linux-nat.o) (i386-linux-nat.o, ia64-linux-nat.o, linux-nat.o, m32r-linux-nat.o) (m68klinux-nat.o, mips-linux-nat.o, ppc-linux-nat.o, s390-nat.o) (sparc64-linux-nat.o): Update dependencies. * alpha-linux-nat.c, sparc-linux-nat.c: New files. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (amd64_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (amd64_linux_child_post_start_inferior): Renamed from child_post_startup_inferior and made static. Call super_post_startup_inferior. (super_post_startup_inferior): New. (_initialize_amd64_linux_nat): Set it. Call linux_target and add_target. * arm-linux-nat.c (arm_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (arm_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (_initialize_arm_linux_nat): Add a prototype. Use linux_target and add_target. * hppa-linux-nat.c (hppa_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (hppa_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (_initialize_hppa_linux_nat): New function. * i386-linux-nat.c (i386_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (i386_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (i386_linux_resume): Renamed from child_resume and made static. (i386_linux_child_post_start_inferior): Renamed from child_post_startup_inferior and made static. Call super_post_startup_inferior. (super_post_startup_inferior): New. (_initialize_i386_linux_nat): New function. * i386-nat.c: Remove LINUX_CHILD_POST_STARTUP_INFERIOR #ifndef. * ia64-linux-nat.c (ia64_linux_xfer_unwind_table): Remove. (super_xfer_partial): New. (ia64_linux_xfer_partial): New function. Use it. (_initialize_ia64_linux_nat): New function. * ia64-tdep.c (getunwind_table): Revert 2005-06-08 change; use target_read_partial and document the problem. * inf-ptrace.c (inf_ptrace_fetch_register): Use CANNOT_FETCH_REGISTER. Fix some comments. (inf_ptrace_store_register): Use CANNOT_STORE_REGISTER. Fix some comments. * linux-nat.c: Include "inf-ptrace.h" and "auxv.h". (linux_ops, super_xfer_partial): New variables. (linux_child_post_startup_inferior): Make static. (child_post_startup_inferior): Delete. (linux_nat_attach, linux_nat_detach, resume_callback) (linux_nat_resume, linux_nat_wait, linux_nat_create_inferior) (linux_nat_mourn_inferior): Use linux_ops instead of deprecated_child_ops. (child_wait): Do not depend on CHILD_WAIT. (linux_nat_xfer_memory): Remove, replace by ... (linux_nat_xfer_partial): ... this. Use linux_ops->to_xfer_partial instead of linux_proc_xfer_memory and child_xfer_memory. (linux_nat_fetch_registers, linux_nat_store_registers) (linux_nat_child_post_startup_inferior): New functions. (init_linux_nat_ops): Use the new functions. (linux_proc_xfer_memory): Remove, replace by ... (linux_proc_xfer_partial): ... this. Make static. (linux_xfer_partial, linux_register_u_offset, linux_target): New functions. (_initialize_linux_nat): Do not modify deprecated_child_ops. * linux-nat.h (linux_proc_xfer_memory): Remove prototype. (struct mem_attrib, struct target_ops): Remove forward declarations. (linux_child_post_startup_inferior): Remove prototype. (linux_target): Add prototype. * linux-thread-db.c (thread_db_xfer_memory): Remove, replace by ... (thread_db_xfer_partial): ... this. (init_thread_db_ops): Set to_xfer_partial instead of deprecated_xfer_memory. * m32r-linux-nat.c (m32r_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (m32r_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (_initialize_m32r_linux_nat): New function. * m68klinux-nat.c (m68k_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (m68k_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (old_fetch_inferior_registers, old_store_inferior_registers): Made static. (_initialize_m68k_linux_nat): Use linux_target and add_target. * mips-linux-nat.c (_initialize_mips_linux_nat): New function. * ppc-linux-nat.c (ppc_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (ppc_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (_initialize_ppc_linux_nat): New function. * s390-nat.c (s390_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (s390_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (_initialize_s390_nat): New function. * sparc64-linux-nat.c (_initialize_sparc64_linux_nat): Use linux_target and add_target. * config/nm-linux.h: Don't include "auxv.h". (struct target_waitstatus, child_wait, CHILD_WAIT) (CHILD_PID_TO_EXEC_FILE, CHILD_INSERT_FORK_CATCHPOINT) (CHILD_INSERT_VFORK_CATCHPOINT, CHILD_INSERT_EXEC_CATCHPOINT) (CHILD_POST_STARTUP_INFERIOR, CHILD_POST_ATTACH, CHILD_FOLLOW_FORK) (DEPRECATED_KILL_INFERIOR, NATIVE_XFER_AUXV): Delete. * config/alpha/alpha-linux.mh (NATDEPFILES): Replace infptrace.o and inftarg.o with inf-ptrace.o and alpha-linux-nat.o. * config/sparc/linux.mh (NATDEPFILES): Replace infptrace.o and inftarg.o with sparc-linux-nat.o. * config/sparc/linux64.mh (NATDEPFILES): Remove infptrace.o and inftarg.o. * config/arm/linux.mh (NATDEPFILES): Replace infptrace.o and inftarg.o with inf-ptrace.o. * config/i386/linux.mh (NATDEPFILES): Likewise. * config/i386/linux64.mh (NATDEPFILES): Likewise. * config/ia64/linux.mh (NATDEPFILES): Likewise. * config/m32r/linux.mh (NATDEPFILES): Likewise. * config/m68k/linux.mh (NATDEPFILES): Likewise. * config/mips/linux.mh (NATDEPFILES): Likewise. * config/pa/linux.mh (NATDEPFILES): Likewise. * config/powerpc/linux.mh (NATDEPFILES): Likewise. * config/powerpc/ppc64-linux.mh (NATDEPFILES): Likewise. * config/s390/s390.mh (NATDEPFILES): Likewise. * config/i386/nm-linux.h (DEPRECATED_CHILD_RESUME): Don't define. (LINUX_CHILD_POST_STARTUP_INFERIOR): Don't define. * config/i386/nm-linux64.h (LINUX_CHILD_POST_STARTUP_INFERIOR): Don't define. * config/ia64/nm-linux.h: Don't include "target.h". (NATIVE_XFER_UNWIND_TABLE, ia64_linux_xfer_unwind_table): Remove. * config/djgpp/fnchange.lst: Add alpha-linux-tdep.c, alpha-linux-nat.c, sparc-linux-tdep.c, and sparc-linux-nat.c.
2005-09-11 02:11:14 +08:00
void
gdb: add back declarations for _initialize functions I'd like to enable the -Wmissing-declarations warning. However, it warns for every _initialize function, for example: CXX dcache.o /home/smarchi/src/binutils-gdb/gdb/dcache.c: In function ‘void _initialize_dcache()’: /home/smarchi/src/binutils-gdb/gdb/dcache.c:688:1: error: no previous declaration for ‘void _initialize_dcache()’ [-Werror=missing-declarations] _initialize_dcache (void) ^~~~~~~~~~~~~~~~~~ The only practical way forward I found is to add back the declarations, which were removed by this commit: commit 481695ed5f6e0a8a9c9c50bfac1cdd2b3151e6c9 Author: John Baldwin <jhb@FreeBSD.org> Date: Sat Sep 9 11:02:37 2017 -0700 Remove unnecessary function prototypes. I don't think it's a big problem to have the declarations for these functions, but if anybody has a better solution for this, I'll be happy to use it. gdb/ChangeLog: * aarch64-fbsd-nat.c (_initialize_aarch64_fbsd_nat): Add declaration. * aarch64-fbsd-tdep.c (_initialize_aarch64_fbsd_tdep): Add declaration. * aarch64-linux-nat.c (_initialize_aarch64_linux_nat): Add declaration. * aarch64-linux-tdep.c (_initialize_aarch64_linux_tdep): Add declaration. * aarch64-newlib-tdep.c (_initialize_aarch64_newlib_tdep): Add declaration. * aarch64-tdep.c (_initialize_aarch64_tdep): Add declaration. * ada-exp.y (_initialize_ada_exp): Add declaration. * ada-lang.c (_initialize_ada_language): Add declaration. * ada-tasks.c (_initialize_tasks): Add declaration. * agent.c (_initialize_agent): Add declaration. * aix-thread.c (_initialize_aix_thread): Add declaration. * alpha-bsd-nat.c (_initialize_alphabsd_nat): Add declaration. * alpha-linux-nat.c (_initialize_alpha_linux_nat): Add declaration. * alpha-linux-tdep.c (_initialize_alpha_linux_tdep): Add declaration. * alpha-nbsd-tdep.c (_initialize_alphanbsd_tdep): Add declaration. * alpha-obsd-tdep.c (_initialize_alphaobsd_tdep): Add declaration. * alpha-tdep.c (_initialize_alpha_tdep): Add declaration. * amd64-darwin-tdep.c (_initialize_amd64_darwin_tdep): Add declaration. * amd64-dicos-tdep.c (_initialize_amd64_dicos_tdep): Add declaration. * amd64-fbsd-nat.c (_initialize_amd64fbsd_nat): Add declaration. * amd64-fbsd-tdep.c (_initialize_amd64fbsd_tdep): Add declaration. * amd64-linux-nat.c (_initialize_amd64_linux_nat): Add declaration. * amd64-linux-tdep.c (_initialize_amd64_linux_tdep): Add declaration. * amd64-nbsd-nat.c (_initialize_amd64nbsd_nat): Add declaration. * amd64-nbsd-tdep.c (_initialize_amd64nbsd_tdep): Add declaration. * amd64-obsd-nat.c (_initialize_amd64obsd_nat): Add declaration. * amd64-obsd-tdep.c (_initialize_amd64obsd_tdep): Add declaration. * amd64-sol2-tdep.c (_initialize_amd64_sol2_tdep): Add declaration. * amd64-tdep.c (_initialize_amd64_tdep): Add declaration. * amd64-windows-nat.c (_initialize_amd64_windows_nat): Add declaration. * amd64-windows-tdep.c (_initialize_amd64_windows_tdep): Add declaration. * annotate.c (_initialize_annotate): Add declaration. * arc-newlib-tdep.c (_initialize_arc_newlib_tdep): Add declaration. * arc-tdep.c (_initialize_arc_tdep): Add declaration. * arch-utils.c (_initialize_gdbarch_utils): Add declaration. * arm-fbsd-nat.c (_initialize_arm_fbsd_nat): Add declaration. * arm-fbsd-tdep.c (_initialize_arm_fbsd_tdep): Add declaration. * arm-linux-nat.c (_initialize_arm_linux_nat): Add declaration. * arm-linux-tdep.c (_initialize_arm_linux_tdep): Add declaration. * arm-nbsd-nat.c (_initialize_arm_netbsd_nat): Add declaration. * arm-nbsd-tdep.c (_initialize_arm_netbsd_tdep): Add declaration. * arm-obsd-tdep.c (_initialize_armobsd_tdep): Add declaration. * arm-pikeos-tdep.c (_initialize_arm_pikeos_tdep): Add declaration. * arm-symbian-tdep.c (_initialize_arm_symbian_tdep): Add declaration. * arm-tdep.c (_initialize_arm_tdep): Add declaration. * arm-wince-tdep.c (_initialize_arm_wince_tdep): Add declaration. * auto-load.c (_initialize_auto_load): Add declaration. * auxv.c (_initialize_auxv): Add declaration. * avr-tdep.c (_initialize_avr_tdep): Add declaration. * ax-gdb.c (_initialize_ax_gdb): Add declaration. * bfin-linux-tdep.c (_initialize_bfin_linux_tdep): Add declaration. * bfin-tdep.c (_initialize_bfin_tdep): Add declaration. * break-catch-sig.c (_initialize_break_catch_sig): Add declaration. * break-catch-syscall.c (_initialize_break_catch_syscall): Add declaration. * break-catch-throw.c (_initialize_break_catch_throw): Add declaration. * breakpoint.c (_initialize_breakpoint): Add declaration. * bsd-uthread.c (_initialize_bsd_uthread): Add declaration. * btrace.c (_initialize_btrace): Add declaration. * charset.c (_initialize_charset): Add declaration. * cli/cli-cmds.c (_initialize_cli_cmds): Add declaration. * cli/cli-dump.c (_initialize_cli_dump): Add declaration. * cli/cli-interp.c (_initialize_cli_interp): Add declaration. * cli/cli-logging.c (_initialize_cli_logging): Add declaration. * cli/cli-script.c (_initialize_cli_script): Add declaration. * cli/cli-style.c (_initialize_cli_style): Add declaration. * coff-pe-read.c (_initialize_coff_pe_read): Add declaration. * coffread.c (_initialize_coffread): Add declaration. * compile/compile-cplus-types.c (_initialize_compile_cplus_types): Add declaration. * compile/compile.c (_initialize_compile): Add declaration. * complaints.c (_initialize_complaints): Add declaration. * completer.c (_initialize_completer): Add declaration. * copying.c (_initialize_copying): Add declaration. * corefile.c (_initialize_core): Add declaration. * corelow.c (_initialize_corelow): Add declaration. * cp-abi.c (_initialize_cp_abi): Add declaration. * cp-namespace.c (_initialize_cp_namespace): Add declaration. * cp-support.c (_initialize_cp_support): Add declaration. * cp-valprint.c (_initialize_cp_valprint): Add declaration. * cris-linux-tdep.c (_initialize_cris_linux_tdep): Add declaration. * cris-tdep.c (_initialize_cris_tdep): Add declaration. * csky-linux-tdep.c (_initialize_csky_linux_tdep): Add declaration. * csky-tdep.c (_initialize_csky_tdep): Add declaration. * ctfread.c (_initialize_ctfread): Add declaration. * d-lang.c (_initialize_d_language): Add declaration. * darwin-nat-info.c (_initialize_darwin_info_commands): Add declaration. * darwin-nat.c (_initialize_darwin_nat): Add declaration. * dbxread.c (_initialize_dbxread): Add declaration. * dcache.c (_initialize_dcache): Add declaration. * disasm-selftests.c (_initialize_disasm_selftests): Add declaration. * disasm.c (_initialize_disasm): Add declaration. * dtrace-probe.c (_initialize_dtrace_probe): Add declaration. * dummy-frame.c (_initialize_dummy_frame): Add declaration. * dwarf-index-cache.c (_initialize_index_cache): Add declaration. * dwarf-index-write.c (_initialize_dwarf_index_write): Add declaration. * dwarf2-frame-tailcall.c (_initialize_tailcall_frame): Add declaration. * dwarf2-frame.c (_initialize_dwarf2_frame): Add declaration. * dwarf2expr.c (_initialize_dwarf2expr): Add declaration. * dwarf2loc.c (_initialize_dwarf2loc): Add declaration. * dwarf2read.c (_initialize_dwarf2_read): Add declaration. * elfread.c (_initialize_elfread): Add declaration. * exec.c (_initialize_exec): Add declaration. * extension.c (_initialize_extension): Add declaration. * f-lang.c (_initialize_f_language): Add declaration. * f-valprint.c (_initialize_f_valprint): Add declaration. * fbsd-nat.c (_initialize_fbsd_nat): Add declaration. * fbsd-tdep.c (_initialize_fbsd_tdep): Add declaration. * filesystem.c (_initialize_filesystem): Add declaration. * findcmd.c (_initialize_mem_search): Add declaration. * findvar.c (_initialize_findvar): Add declaration. * fork-child.c (_initialize_fork_child): Add declaration. * frame-base.c (_initialize_frame_base): Add declaration. * frame-unwind.c (_initialize_frame_unwind): Add declaration. * frame.c (_initialize_frame): Add declaration. * frv-linux-tdep.c (_initialize_frv_linux_tdep): Add declaration. * frv-tdep.c (_initialize_frv_tdep): Add declaration. * ft32-tdep.c (_initialize_ft32_tdep): Add declaration. * gcore.c (_initialize_gcore): Add declaration. * gdb-demangle.c (_initialize_gdb_demangle): Add declaration. * gdb_bfd.c (_initialize_gdb_bfd): Add declaration. * gdbarch-selftests.c (_initialize_gdbarch_selftests): Add declaration. * gdbarch.c (_initialize_gdbarch): Add declaration. * gdbtypes.c (_initialize_gdbtypes): Add declaration. * gnu-nat.c (_initialize_gnu_nat): Add declaration. * gnu-v2-abi.c (_initialize_gnu_v2_abi): Add declaration. * gnu-v3-abi.c (_initialize_gnu_v3_abi): Add declaration. * go-lang.c (_initialize_go_language): Add declaration. * go32-nat.c (_initialize_go32_nat): Add declaration. * guile/guile.c (_initialize_guile): Add declaration. * h8300-tdep.c (_initialize_h8300_tdep): Add declaration. * hppa-linux-nat.c (_initialize_hppa_linux_nat): Add declaration. * hppa-linux-tdep.c (_initialize_hppa_linux_tdep): Add declaration. * hppa-nbsd-nat.c (_initialize_hppanbsd_nat): Add declaration. * hppa-nbsd-tdep.c (_initialize_hppanbsd_tdep): Add declaration. * hppa-obsd-nat.c (_initialize_hppaobsd_nat): Add declaration. * hppa-obsd-tdep.c (_initialize_hppabsd_tdep): Add declaration. * hppa-tdep.c (_initialize_hppa_tdep): Add declaration. * i386-bsd-nat.c (_initialize_i386bsd_nat): Add declaration. * i386-cygwin-tdep.c (_initialize_i386_cygwin_tdep): Add declaration. * i386-darwin-nat.c (_initialize_i386_darwin_nat): Add declaration. * i386-darwin-tdep.c (_initialize_i386_darwin_tdep): Add declaration. * i386-dicos-tdep.c (_initialize_i386_dicos_tdep): Add declaration. * i386-fbsd-nat.c (_initialize_i386fbsd_nat): Add declaration. * i386-fbsd-tdep.c (_initialize_i386fbsd_tdep): Add declaration. * i386-gnu-nat.c (_initialize_i386gnu_nat): Add declaration. * i386-gnu-tdep.c (_initialize_i386gnu_tdep): Add declaration. * i386-go32-tdep.c (_initialize_i386_go32_tdep): Add declaration. * i386-linux-nat.c (_initialize_i386_linux_nat): Add declaration. * i386-linux-tdep.c (_initialize_i386_linux_tdep): Add declaration. * i386-nbsd-nat.c (_initialize_i386nbsd_nat): Add declaration. * i386-nbsd-tdep.c (_initialize_i386nbsd_tdep): Add declaration. * i386-nto-tdep.c (_initialize_i386nto_tdep): Add declaration. * i386-obsd-nat.c (_initialize_i386obsd_nat): Add declaration. * i386-obsd-tdep.c (_initialize_i386obsd_tdep): Add declaration. * i386-sol2-nat.c (_initialize_amd64_sol2_nat): Add declaration. * i386-sol2-tdep.c (_initialize_i386_sol2_tdep): Add declaration. * i386-tdep.c (_initialize_i386_tdep): Add declaration. * i386-windows-nat.c (_initialize_i386_windows_nat): Add declaration. * ia64-libunwind-tdep.c (_initialize_libunwind_frame): Add declaration. * ia64-linux-nat.c (_initialize_ia64_linux_nat): Add declaration. * ia64-linux-tdep.c (_initialize_ia64_linux_tdep): Add declaration. * ia64-tdep.c (_initialize_ia64_tdep): Add declaration. * ia64-vms-tdep.c (_initialize_ia64_vms_tdep): Add declaration. * infcall.c (_initialize_infcall): Add declaration. * infcmd.c (_initialize_infcmd): Add declaration. * inflow.c (_initialize_inflow): Add declaration. * infrun.c (_initialize_infrun): Add declaration. * interps.c (_initialize_interpreter): Add declaration. * iq2000-tdep.c (_initialize_iq2000_tdep): Add declaration. * jit.c (_initialize_jit): Add declaration. * language.c (_initialize_language): Add declaration. * linux-fork.c (_initialize_linux_fork): Add declaration. * linux-nat.c (_initialize_linux_nat): Add declaration. * linux-tdep.c (_initialize_linux_tdep): Add declaration. * linux-thread-db.c (_initialize_thread_db): Add declaration. * lm32-tdep.c (_initialize_lm32_tdep): Add declaration. * m2-lang.c (_initialize_m2_language): Add declaration. * m32c-tdep.c (_initialize_m32c_tdep): Add declaration. * m32r-linux-nat.c (_initialize_m32r_linux_nat): Add declaration. * m32r-linux-tdep.c (_initialize_m32r_linux_tdep): Add declaration. * m32r-tdep.c (_initialize_m32r_tdep): Add declaration. * m68hc11-tdep.c (_initialize_m68hc11_tdep): Add declaration. * m68k-bsd-nat.c (_initialize_m68kbsd_nat): Add declaration. * m68k-bsd-tdep.c (_initialize_m68kbsd_tdep): Add declaration. * m68k-linux-nat.c (_initialize_m68k_linux_nat): Add declaration. * m68k-linux-tdep.c (_initialize_m68k_linux_tdep): Add declaration. * m68k-tdep.c (_initialize_m68k_tdep): Add declaration. * machoread.c (_initialize_machoread): Add declaration. * macrocmd.c (_initialize_macrocmd): Add declaration. * macroscope.c (_initialize_macroscope): Add declaration. * maint-test-options.c (_initialize_maint_test_options): Add declaration. * maint-test-settings.c (_initialize_maint_test_settings): Add declaration. * maint.c (_initialize_maint_cmds): Add declaration. * mdebugread.c (_initialize_mdebugread): Add declaration. * memattr.c (_initialize_mem): Add declaration. * mep-tdep.c (_initialize_mep_tdep): Add declaration. * mi/mi-cmd-env.c (_initialize_mi_cmd_env): Add declaration. * mi/mi-cmds.c (_initialize_mi_cmds): Add declaration. * mi/mi-interp.c (_initialize_mi_interp): Add declaration. * mi/mi-main.c (_initialize_mi_main): Add declaration. * microblaze-linux-tdep.c (_initialize_microblaze_linux_tdep): Add declaration. * microblaze-tdep.c (_initialize_microblaze_tdep): Add declaration. * mips-fbsd-nat.c (_initialize_mips_fbsd_nat): Add declaration. * mips-fbsd-tdep.c (_initialize_mips_fbsd_tdep): Add declaration. * mips-linux-nat.c (_initialize_mips_linux_nat): Add declaration. * mips-linux-tdep.c (_initialize_mips_linux_tdep): Add declaration. * mips-nbsd-nat.c (_initialize_mipsnbsd_nat): Add declaration. * mips-nbsd-tdep.c (_initialize_mipsnbsd_tdep): Add declaration. * mips-sde-tdep.c (_initialize_mips_sde_tdep): Add declaration. * mips-tdep.c (_initialize_mips_tdep): Add declaration. * mips64-obsd-nat.c (_initialize_mips64obsd_nat): Add declaration. * mips64-obsd-tdep.c (_initialize_mips64obsd_tdep): Add declaration. * mipsread.c (_initialize_mipsread): Add declaration. * mn10300-linux-tdep.c (_initialize_mn10300_linux_tdep): Add declaration. * mn10300-tdep.c (_initialize_mn10300_tdep): Add declaration. * moxie-tdep.c (_initialize_moxie_tdep): Add declaration. * msp430-tdep.c (_initialize_msp430_tdep): Add declaration. * nds32-tdep.c (_initialize_nds32_tdep): Add declaration. * nios2-linux-tdep.c (_initialize_nios2_linux_tdep): Add declaration. * nios2-tdep.c (_initialize_nios2_tdep): Add declaration. * nto-procfs.c (_initialize_procfs): Add declaration. * objc-lang.c (_initialize_objc_language): Add declaration. * observable.c (_initialize_observer): Add declaration. * opencl-lang.c (_initialize_opencl_language): Add declaration. * or1k-linux-tdep.c (_initialize_or1k_linux_tdep): Add declaration. * or1k-tdep.c (_initialize_or1k_tdep): Add declaration. * osabi.c (_initialize_gdb_osabi): Add declaration. * osdata.c (_initialize_osdata): Add declaration. * p-valprint.c (_initialize_pascal_valprint): Add declaration. * parse.c (_initialize_parse): Add declaration. * ppc-fbsd-nat.c (_initialize_ppcfbsd_nat): Add declaration. * ppc-fbsd-tdep.c (_initialize_ppcfbsd_tdep): Add declaration. * ppc-linux-nat.c (_initialize_ppc_linux_nat): Add declaration. * ppc-linux-tdep.c (_initialize_ppc_linux_tdep): Add declaration. * ppc-nbsd-nat.c (_initialize_ppcnbsd_nat): Add declaration. * ppc-nbsd-tdep.c (_initialize_ppcnbsd_tdep): Add declaration. * ppc-obsd-nat.c (_initialize_ppcobsd_nat): Add declaration. * ppc-obsd-tdep.c (_initialize_ppcobsd_tdep): Add declaration. * printcmd.c (_initialize_printcmd): Add declaration. * probe.c (_initialize_probe): Add declaration. * proc-api.c (_initialize_proc_api): Add declaration. * proc-events.c (_initialize_proc_events): Add declaration. * proc-service.c (_initialize_proc_service): Add declaration. * procfs.c (_initialize_procfs): Add declaration. * producer.c (_initialize_producer): Add declaration. * psymtab.c (_initialize_psymtab): Add declaration. * python/python.c (_initialize_python): Add declaration. * ravenscar-thread.c (_initialize_ravenscar): Add declaration. * record-btrace.c (_initialize_record_btrace): Add declaration. * record-full.c (_initialize_record_full): Add declaration. * record.c (_initialize_record): Add declaration. * regcache-dump.c (_initialize_regcache_dump): Add declaration. * regcache.c (_initialize_regcache): Add declaration. * reggroups.c (_initialize_reggroup): Add declaration. * remote-notif.c (_initialize_notif): Add declaration. * remote-sim.c (_initialize_remote_sim): Add declaration. * remote.c (_initialize_remote): Add declaration. * reverse.c (_initialize_reverse): Add declaration. * riscv-fbsd-nat.c (_initialize_riscv_fbsd_nat): Add declaration. * riscv-fbsd-tdep.c (_initialize_riscv_fbsd_tdep): Add declaration. * riscv-linux-nat.c (_initialize_riscv_linux_nat): Add declaration. * riscv-linux-tdep.c (_initialize_riscv_linux_tdep): Add declaration. * riscv-tdep.c (_initialize_riscv_tdep): Add declaration. * rl78-tdep.c (_initialize_rl78_tdep): Add declaration. * rs6000-aix-tdep.c (_initialize_rs6000_aix_tdep): Add declaration. * rs6000-lynx178-tdep.c (_initialize_rs6000_lynx178_tdep): Add declaration. * rs6000-nat.c (_initialize_rs6000_nat): Add declaration. * rs6000-tdep.c (_initialize_rs6000_tdep): Add declaration. * run-on-main-thread.c (_initialize_run_on_main_thread): Add declaration. * rust-exp.y (_initialize_rust_exp): Add declaration. * rx-tdep.c (_initialize_rx_tdep): Add declaration. * s12z-tdep.c (_initialize_s12z_tdep): Add declaration. * s390-linux-nat.c (_initialize_s390_nat): Add declaration. * s390-linux-tdep.c (_initialize_s390_linux_tdep): Add declaration. * s390-tdep.c (_initialize_s390_tdep): Add declaration. * score-tdep.c (_initialize_score_tdep): Add declaration. * ser-go32.c (_initialize_ser_dos): Add declaration. * ser-mingw.c (_initialize_ser_windows): Add declaration. * ser-pipe.c (_initialize_ser_pipe): Add declaration. * ser-tcp.c (_initialize_ser_tcp): Add declaration. * ser-uds.c (_initialize_ser_socket): Add declaration. * ser-unix.c (_initialize_ser_hardwire): Add declaration. * serial.c (_initialize_serial): Add declaration. * sh-linux-tdep.c (_initialize_sh_linux_tdep): Add declaration. * sh-nbsd-nat.c (_initialize_shnbsd_nat): Add declaration. * sh-nbsd-tdep.c (_initialize_shnbsd_tdep): Add declaration. * sh-tdep.c (_initialize_sh_tdep): Add declaration. * skip.c (_initialize_step_skip): Add declaration. * sol-thread.c (_initialize_sol_thread): Add declaration. * solib-aix.c (_initialize_solib_aix): Add declaration. * solib-darwin.c (_initialize_darwin_solib): Add declaration. * solib-dsbt.c (_initialize_dsbt_solib): Add declaration. * solib-frv.c (_initialize_frv_solib): Add declaration. * solib-svr4.c (_initialize_svr4_solib): Add declaration. * solib-target.c (_initialize_solib_target): Add declaration. * solib.c (_initialize_solib): Add declaration. * source-cache.c (_initialize_source_cache): Add declaration. * source.c (_initialize_source): Add declaration. * sparc-linux-nat.c (_initialize_sparc_linux_nat): Add declaration. * sparc-linux-tdep.c (_initialize_sparc_linux_tdep): Add declaration. * sparc-nat.c (_initialize_sparc_nat): Add declaration. * sparc-nbsd-nat.c (_initialize_sparcnbsd_nat): Add declaration. * sparc-nbsd-tdep.c (_initialize_sparcnbsd_tdep): Add declaration. * sparc-obsd-tdep.c (_initialize_sparc32obsd_tdep): Add declaration. * sparc-sol2-tdep.c (_initialize_sparc_sol2_tdep): Add declaration. * sparc-tdep.c (_initialize_sparc_tdep): Add declaration. * sparc64-fbsd-nat.c (_initialize_sparc64fbsd_nat): Add declaration. * sparc64-fbsd-tdep.c (_initialize_sparc64fbsd_tdep): Add declaration. * sparc64-linux-nat.c (_initialize_sparc64_linux_nat): Add declaration. * sparc64-linux-tdep.c (_initialize_sparc64_linux_tdep): Add declaration. * sparc64-nat.c (_initialize_sparc64_nat): Add declaration. * sparc64-nbsd-nat.c (_initialize_sparc64nbsd_nat): Add declaration. * sparc64-nbsd-tdep.c (_initialize_sparc64nbsd_tdep): Add declaration. * sparc64-obsd-nat.c (_initialize_sparc64obsd_nat): Add declaration. * sparc64-obsd-tdep.c (_initialize_sparc64obsd_tdep): Add declaration. * sparc64-sol2-tdep.c (_initialize_sparc64_sol2_tdep): Add declaration. * sparc64-tdep.c (_initialize_sparc64_adi_tdep): Add declaration. * stabsread.c (_initialize_stabsread): Add declaration. * stack.c (_initialize_stack): Add declaration. * stap-probe.c (_initialize_stap_probe): Add declaration. * std-regs.c (_initialize_frame_reg): Add declaration. * symfile-debug.c (_initialize_symfile_debug): Add declaration. * symfile-mem.c (_initialize_symfile_mem): Add declaration. * symfile.c (_initialize_symfile): Add declaration. * symmisc.c (_initialize_symmisc): Add declaration. * symtab.c (_initialize_symtab): Add declaration. * target.c (_initialize_target): Add declaration. * target-connection.c (_initialize_target_connection): Add declaration. * target-dcache.c (_initialize_target_dcache): Add declaration. * target-descriptions.c (_initialize_target_descriptions): Add declaration. * thread.c (_initialize_thread): Add declaration. * tic6x-linux-tdep.c (_initialize_tic6x_linux_tdep): Add declaration. * tic6x-tdep.c (_initialize_tic6x_tdep): Add declaration. * tilegx-linux-nat.c (_initialize_tile_linux_nat): Add declaration. * tilegx-linux-tdep.c (_initialize_tilegx_linux_tdep): Add declaration. * tilegx-tdep.c (_initialize_tilegx_tdep): Add declaration. * tracectf.c (_initialize_ctf): Add declaration. * tracefile-tfile.c (_initialize_tracefile_tfile): Add declaration. * tracefile.c (_initialize_tracefile): Add declaration. * tracepoint.c (_initialize_tracepoint): Add declaration. * tui/tui-hooks.c (_initialize_tui_hooks): Add declaration. * tui/tui-interp.c (_initialize_tui_interp): Add declaration. * tui/tui-layout.c (_initialize_tui_layout): Add declaration. * tui/tui-regs.c (_initialize_tui_regs): Add declaration. * tui/tui-stack.c (_initialize_tui_stack): Add declaration. * tui/tui-win.c (_initialize_tui_win): Add declaration. * tui/tui.c (_initialize_tui): Add declaration. * typeprint.c (_initialize_typeprint): Add declaration. * ui-style.c (_initialize_ui_style): Add declaration. * unittests/array-view-selftests.c (_initialize_array_view_selftests): Add declaration. * unittests/child-path-selftests.c (_initialize_child_path_selftests): Add declaration. * unittests/cli-utils-selftests.c (_initialize_cli_utils_selftests): Add declaration. * unittests/common-utils-selftests.c (_initialize_common_utils_selftests): Add declaration. * unittests/copy_bitwise-selftests.c (_initialize_copy_bitwise_utils_selftests): Add declaration. * unittests/environ-selftests.c (_initialize_environ_selftests): Add declaration. * unittests/filtered_iterator-selftests.c (_initialize_filtered_iterator_selftests): Add declaration. * unittests/format_pieces-selftests.c (_initialize_format_pieces_selftests): Add declaration. * unittests/function-view-selftests.c (_initialize_function_view_selftests): Add declaration. * unittests/help-doc-selftests.c (_initialize_help_doc_selftests): Add declaration. * unittests/lookup_name_info-selftests.c (_initialize_lookup_name_info_selftests): Add declaration. * unittests/main-thread-selftests.c (_initialize_main_thread_selftests): Add declaration. * unittests/memory-map-selftests.c (_initialize_memory_map_selftests): Add declaration. * unittests/memrange-selftests.c (_initialize_memrange_selftests): Add declaration. * unittests/mkdir-recursive-selftests.c (_initialize_mkdir_recursive_selftests): Add declaration. * unittests/observable-selftests.c (_initialize_observer_selftest): Add declaration. * unittests/offset-type-selftests.c (_initialize_offset_type_selftests): Add declaration. * unittests/optional-selftests.c (_initialize_optional_selftests): Add declaration. * unittests/parse-connection-spec-selftests.c (_initialize_parse_connection_spec_selftests): Add declaration. * unittests/rsp-low-selftests.c (_initialize_rsp_low_selftests): Add declaration. * unittests/scoped_fd-selftests.c (_initialize_scoped_fd_selftests): Add declaration. * unittests/scoped_mmap-selftests.c (_initialize_scoped_mmap_selftests): Add declaration. * unittests/scoped_restore-selftests.c (_initialize_scoped_restore_selftests): Add declaration. * unittests/string_view-selftests.c (_initialize_string_view_selftests): Add declaration. * unittests/style-selftests.c (_initialize_style_selftest): Add declaration. * unittests/tracepoint-selftests.c (_initialize_tracepoint_selftests): Add declaration. * unittests/tui-selftests.c (_initialize_tui_selftest): Add declaration. * unittests/unpack-selftests.c (_initialize_unpack_selftests): Add declaration. * unittests/utils-selftests.c (_initialize_utils_selftests): Add declaration. * unittests/vec-utils-selftests.c (_initialize_vec_utils_selftests): Add declaration. * unittests/xml-utils-selftests.c (_initialize_xml_utils): Add declaration. * user-regs.c (_initialize_user_regs): Add declaration. * utils.c (_initialize_utils): Add declaration. * v850-tdep.c (_initialize_v850_tdep): Add declaration. * valops.c (_initialize_valops): Add declaration. * valprint.c (_initialize_valprint): Add declaration. * value.c (_initialize_values): Add declaration. * varobj.c (_initialize_varobj): Add declaration. * vax-bsd-nat.c (_initialize_vaxbsd_nat): Add declaration. * vax-nbsd-tdep.c (_initialize_vaxnbsd_tdep): Add declaration. * vax-tdep.c (_initialize_vax_tdep): Add declaration. * windows-nat.c (_initialize_windows_nat): Add declaration. (_initialize_check_for_gdb_ini): Add declaration. (_initialize_loadable): Add declaration. * windows-tdep.c (_initialize_windows_tdep): Add declaration. * x86-bsd-nat.c (_initialize_x86_bsd_nat): Add declaration. * x86-linux-nat.c (_initialize_x86_linux_nat): Add declaration. * xcoffread.c (_initialize_xcoffread): Add declaration. * xml-support.c (_initialize_xml_support): Add declaration. * xstormy16-tdep.c (_initialize_xstormy16_tdep): Add declaration. * xtensa-linux-nat.c (_initialize_xtensa_linux_nat): Add declaration. * xtensa-linux-tdep.c (_initialize_xtensa_linux_tdep): Add declaration. * xtensa-tdep.c (_initialize_xtensa_tdep): Add declaration. Change-Id: I13eec7e0ed2b3c427377a7bdb055cf46da64def9
2020-01-14 03:01:38 +08:00
_initialize_ppc_linux_nat ()
* Makefile.in (ALLDEPFILES): Update. (alpha-linux-nat.o, sparc-linux-nat.o): New rules. (amd64-linux-nat.o, arm-linux-nat.o, hppa-linux-nat.o) (i386-linux-nat.o, ia64-linux-nat.o, linux-nat.o, m32r-linux-nat.o) (m68klinux-nat.o, mips-linux-nat.o, ppc-linux-nat.o, s390-nat.o) (sparc64-linux-nat.o): Update dependencies. * alpha-linux-nat.c, sparc-linux-nat.c: New files. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (amd64_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (amd64_linux_child_post_start_inferior): Renamed from child_post_startup_inferior and made static. Call super_post_startup_inferior. (super_post_startup_inferior): New. (_initialize_amd64_linux_nat): Set it. Call linux_target and add_target. * arm-linux-nat.c (arm_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (arm_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (_initialize_arm_linux_nat): Add a prototype. Use linux_target and add_target. * hppa-linux-nat.c (hppa_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (hppa_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (_initialize_hppa_linux_nat): New function. * i386-linux-nat.c (i386_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (i386_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (i386_linux_resume): Renamed from child_resume and made static. (i386_linux_child_post_start_inferior): Renamed from child_post_startup_inferior and made static. Call super_post_startup_inferior. (super_post_startup_inferior): New. (_initialize_i386_linux_nat): New function. * i386-nat.c: Remove LINUX_CHILD_POST_STARTUP_INFERIOR #ifndef. * ia64-linux-nat.c (ia64_linux_xfer_unwind_table): Remove. (super_xfer_partial): New. (ia64_linux_xfer_partial): New function. Use it. (_initialize_ia64_linux_nat): New function. * ia64-tdep.c (getunwind_table): Revert 2005-06-08 change; use target_read_partial and document the problem. * inf-ptrace.c (inf_ptrace_fetch_register): Use CANNOT_FETCH_REGISTER. Fix some comments. (inf_ptrace_store_register): Use CANNOT_STORE_REGISTER. Fix some comments. * linux-nat.c: Include "inf-ptrace.h" and "auxv.h". (linux_ops, super_xfer_partial): New variables. (linux_child_post_startup_inferior): Make static. (child_post_startup_inferior): Delete. (linux_nat_attach, linux_nat_detach, resume_callback) (linux_nat_resume, linux_nat_wait, linux_nat_create_inferior) (linux_nat_mourn_inferior): Use linux_ops instead of deprecated_child_ops. (child_wait): Do not depend on CHILD_WAIT. (linux_nat_xfer_memory): Remove, replace by ... (linux_nat_xfer_partial): ... this. Use linux_ops->to_xfer_partial instead of linux_proc_xfer_memory and child_xfer_memory. (linux_nat_fetch_registers, linux_nat_store_registers) (linux_nat_child_post_startup_inferior): New functions. (init_linux_nat_ops): Use the new functions. (linux_proc_xfer_memory): Remove, replace by ... (linux_proc_xfer_partial): ... this. Make static. (linux_xfer_partial, linux_register_u_offset, linux_target): New functions. (_initialize_linux_nat): Do not modify deprecated_child_ops. * linux-nat.h (linux_proc_xfer_memory): Remove prototype. (struct mem_attrib, struct target_ops): Remove forward declarations. (linux_child_post_startup_inferior): Remove prototype. (linux_target): Add prototype. * linux-thread-db.c (thread_db_xfer_memory): Remove, replace by ... (thread_db_xfer_partial): ... this. (init_thread_db_ops): Set to_xfer_partial instead of deprecated_xfer_memory. * m32r-linux-nat.c (m32r_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (m32r_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (_initialize_m32r_linux_nat): New function. * m68klinux-nat.c (m68k_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (m68k_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (old_fetch_inferior_registers, old_store_inferior_registers): Made static. (_initialize_m68k_linux_nat): Use linux_target and add_target. * mips-linux-nat.c (_initialize_mips_linux_nat): New function. * ppc-linux-nat.c (ppc_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (ppc_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (_initialize_ppc_linux_nat): New function. * s390-nat.c (s390_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (s390_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (_initialize_s390_nat): New function. * sparc64-linux-nat.c (_initialize_sparc64_linux_nat): Use linux_target and add_target. * config/nm-linux.h: Don't include "auxv.h". (struct target_waitstatus, child_wait, CHILD_WAIT) (CHILD_PID_TO_EXEC_FILE, CHILD_INSERT_FORK_CATCHPOINT) (CHILD_INSERT_VFORK_CATCHPOINT, CHILD_INSERT_EXEC_CATCHPOINT) (CHILD_POST_STARTUP_INFERIOR, CHILD_POST_ATTACH, CHILD_FOLLOW_FORK) (DEPRECATED_KILL_INFERIOR, NATIVE_XFER_AUXV): Delete. * config/alpha/alpha-linux.mh (NATDEPFILES): Replace infptrace.o and inftarg.o with inf-ptrace.o and alpha-linux-nat.o. * config/sparc/linux.mh (NATDEPFILES): Replace infptrace.o and inftarg.o with sparc-linux-nat.o. * config/sparc/linux64.mh (NATDEPFILES): Remove infptrace.o and inftarg.o. * config/arm/linux.mh (NATDEPFILES): Replace infptrace.o and inftarg.o with inf-ptrace.o. * config/i386/linux.mh (NATDEPFILES): Likewise. * config/i386/linux64.mh (NATDEPFILES): Likewise. * config/ia64/linux.mh (NATDEPFILES): Likewise. * config/m32r/linux.mh (NATDEPFILES): Likewise. * config/m68k/linux.mh (NATDEPFILES): Likewise. * config/mips/linux.mh (NATDEPFILES): Likewise. * config/pa/linux.mh (NATDEPFILES): Likewise. * config/powerpc/linux.mh (NATDEPFILES): Likewise. * config/powerpc/ppc64-linux.mh (NATDEPFILES): Likewise. * config/s390/s390.mh (NATDEPFILES): Likewise. * config/i386/nm-linux.h (DEPRECATED_CHILD_RESUME): Don't define. (LINUX_CHILD_POST_STARTUP_INFERIOR): Don't define. * config/i386/nm-linux64.h (LINUX_CHILD_POST_STARTUP_INFERIOR): Don't define. * config/ia64/nm-linux.h: Don't include "target.h". (NATIVE_XFER_UNWIND_TABLE, ia64_linux_xfer_unwind_table): Remove. * config/djgpp/fnchange.lst: Add alpha-linux-tdep.c, alpha-linux-nat.c, sparc-linux-tdep.c, and sparc-linux-nat.c.
2005-09-11 02:11:14 +08:00
{
Convert struct target_ops to C++ I.e., use C++ virtual methods and inheritance instead of tables of function pointers. Unfortunately, there's no way to do a smooth transition. ALL native targets in the tree must be converted at the same time. I've tested all I could with cross compilers and with help from GCC compile farm, but naturally I haven't been able to test many of the ports. Still, I made a best effort to port everything over, and while I expect some build problems due to typos and such, which should be trivial to fix, I don't expect any design problems. * Implementation notes: - The flattened current_target is gone. References to current_target or current_target.beneath are replaced with references to target_stack (the top of the stack) directly. - To keep "set debug target" working, this adds a new debug_stratum layer that sits on top of the stack, prints the debug, and delegates to the target beneath. In addition, this makes the shortname and longname properties of target_ops be virtual methods instead of data fields, and makes the debug target defer those to the target beneath. This is so that debug code sprinkled around that does "if (debugtarget) ..." can transparently print the name of the target beneath. A patch later in the series actually splits out the shortname/longname methods to a separate structure, but I preferred to keep that chance separate as it is associated with changing a bit the design of how targets are registered and open. - Since you can't check whether a C++ virtual method is overridden, the old method of checking whether a target_ops implements a method by comparing the function pointer must be replaced with something else. Some cases are fixed by adding a parallel "can_do_foo" target_ops methods. E.g.,: + for (t = target_stack; t != NULL; t = t->beneath) { - if (t->to_create_inferior != NULL) + if (t->can_create_inferior ()) break; } Others are fixed by changing void return type to bool or int return type, and have the default implementation return false or -1, to indicate lack of support. - make-target-delegates was adjusted to generate C++ classes and methods. It needed tweaks to grok "virtual" in front of the target method name, and for the fact that methods are no longer function pointers. (In particular, the current code parsing the return type was simple because it could simply parse up until the '(' in '(*to_foo)'. It now generates a couple C++ classes that inherit target_ops: dummy_target and debug_target. Since we need to generate the class declarations as well, i.e., we need to emit methods twice, we now generate the code in two passes. - The core_target global is renamed to avoid conflict with the "core_target" class. - ctf/tfile targets init_tracefile_ops is replaced by a base class that is inherited by both ctf and tfile. - bsd-uthread The bsd_uthread_ops_hack hack is gone. It's not needed because nothing was extending a target created by bsd_uthread_target. - remote/extended-remote targets This is a first pass, just enough to C++ify target_ops. A later pass will convert more free functions to methods, and make remote_state be truly per remote instance, allowing multiple simultaneous instances of remote targets. - inf-child/"native" is converted to an actual base class (inf_child_target), that is inherited by all native targets. - GNU/Linux The old weird double-target linux_ops mechanism in linux-nat.c, is gone, replaced by adding a few virtual methods to linux-nat.h's target_ops, called low_XXX, that the concrete linux-nat implementations override. Sort of like gdbserver's linux_target_ops, but simpler, for requiring only one target_ops-like hierarchy, which spares implementing the same method twice when we need to forward the method to a low implementation. The low target simply reimplements the target_ops method directly in that case. There are a few remaining linux-nat.c hooks that would be better converted to low_ methods like above too. E.g.: linux_nat_set_new_thread (t, x86_linux_new_thread); linux_nat_set_new_fork (t, x86_linux_new_fork); linux_nat_set_forget_process That'll be done in a follow up patch. - We can no longer use functions like x86_use_watchpoints to install custom methods on an arbitrary base target. The patch replaces instances of such a pattern with template mixins. For example memory_breakpoint_target defined in target.h, or x86_nat_target in x86-nat.h. - linux_trad_target, MIPS and Alpha GNU/Linux The code in the new linux-nat-trad.h/c files which was split off of inf-ptrace.h/c recently, is converted to a C++ base class, and used by the MIPS and Alpha GNU/Linux ports. - BSD targets The $architecture x NetBSD/OpenBSD/FreeBSD support matrix complicates things a bit. There's common BSD target code, and there's common architecture-specific code shared between the different BSDs. Currently, all that is stiched together to form a final target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target functions etc. This introduces new fbsd_nat_target, obsd_nat_target and nbsd_nat_target classes that serve as base/prototype target for the corresponding BSD variant. And introduces generic i386/AMD64 BSD targets, to be used as template mixin to build a final target. Similarly, a generic SPARC target is added, used by both BSD and Linux ports. - bsd_kvm_add_target, BSD libkvm target I considered making bsd_kvm_supply_pcb a virtual method, and then have each port inherit bsd_kvm_target and override that method, but that was resulting in lots of unjustified churn, so I left the function pointer mechanism alone. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> John Baldwin <jhb@freebsd.org> * target.h (enum strata) <debug_stratum>: New. (struct target_ops) <all delegation methods>: Replace by C++ virtual methods, and drop "to_" prefix. All references updated throughout. <to_shortname, to_longname, to_doc, to_data, to_have_steppable_watchpoint, to_have_continuable_watchpoint, to_has_thread_control, to_attach_no_wait>: Delete, replaced by virtual methods. All references updated throughout. <can_attach, supports_terminal_ours, can_create_inferior, get_thread_control_capabilities, attach_no_wait>: New virtual methods. <insert_breakpoint, remove_breakpoint>: Now TARGET_DEFAULT_NORETURN methods. <info_proc>: Now returns bool. <to_magic>: Delete. (OPS_MAGIC): Delete. (current_target): Delete. All references replaced by references to ... (target_stack): ... this. New. (target_shortname, target_longname): Adjust. (target_can_run): Now a function declaration. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (memory_breakpoint_target): New template class. (test_target_ops): Refactor as a C++ class with virtual methods. * make-target-delegates (NAME_PART): Tighten. (POINTER_PART, CP_SYMBOL): New. (SIMPLE_RETURN_PART): Reimplement. (VEC_RETURN_PART): Expect less. (RETURN_PART, VIRTUAL_PART): New. (METHOD): Adjust to C++ virtual methods. (scan_target_h): Remove reference to C99. (dname): Output "target_ops::" prefix. (write_function_header): Adjust to output a C++ class method. (write_declaration): New. (write_delegator): Adjust to output a C++ class method. (tdname): Output "dummy_target::" prefix. (write_tdefault, write_debugmethod): Adjust to output a C++ class method. (tdefault_names, debug_names): Delete. (return_types, tdefaults, styles, argtypes_array): New. (top level): All methods are delegators. (print_class): New. (top level): Print dummy_target and debug_target classes. * target-delegates.c: Regenerate. * target-debug.h (target_debug_print_enum_info_proc_what) (target_debug_print_thread_control_capabilities) (target_debug_print_thread_info_p): New. * target.c (dummy_target): Delete. (the_dummy_target, the_debug_target): New. (target_stack): Now extern. (set_targetdebug): Push/unpush debug target. (default_child_has_all_memory, default_child_has_memory) (default_child_has_stack, default_child_has_registers) (default_child_has_execution): Remove target_ops parameter. (complete_target_initialization): Delete. (add_target_with_completer): No longer call complete_target_initialization. (target_supports_terminal_ours): Use regular delegation. (update_current_target): Delete. (push_target): No longer check magic number. Don't call update_current_target. (unpush_target): Don't call update_current_target. (target_is_pushed): No longer check magic number. (target_require_runnable): Skip for all stratums over process_stratum. (target_ops::info_proc): New. (target_info_proc): Use find_target_at and find_default_run_target. (target_supports_disable_randomization): Use regular delegation. (target_get_osdata): Use find_target_at. (target_ops::open, target_ops::close, target_ops::can_attach) (target_ops::attach, target_ops::can_create_inferior) (target_ops::create_inferior, target_ops::can_run) (target_can_run): New. (default_fileio_target): Use regular delegation. (target_ops::fileio_open, target_ops::fileio_pwrite) (target_ops::fileio_pread, target_ops::fileio_fstat) (target_ops::fileio_close, target_ops::fileio_unlink) (target_ops::fileio_readlink): New. (target_fileio_open_1, target_fileio_unlink) (target_fileio_readlink): Always call the target method. Handle FILEIO_ENOSYS. (return_zero, return_zero_has_execution): Delete. (init_dummy_target): Delete. (dummy_target::dummy_target, dummy_target::shortname) (dummy_target::longname, dummy_target::doc) (debug_target::debug_target, debug_target::shortname) (debug_target::longname, debug_target::doc): New. (target_supports_delete_record): Use regular delegation. (setup_target_debug): Delete. (maintenance_print_target_stack): Skip debug_stratum. (initialize_targets): Instantiate the_dummy_target and the_debug_target. * auxv.c (target_auxv_parse): Remove 'ops' parameter. Adjust to use target_stack. (target_auxv_search, fprint_target_auxv): Adjust. (info_auxv_command): Adjust to use target_stack. * auxv.h (target_auxv_parse): Remove 'ops' parameter. * exceptions.c (print_flush): Handle a NULL target_stack. * regcache.c (target_ops_no_register): Refactor as class with virtual methods. * exec.c (exec_target): New class. (exec_ops): Now an exec_target. (exec_open, exec_close_1, exec_get_section_table) (exec_xfer_partial, exec_files_info, exec_has_memory) (exec_make_note_section): Refactor as exec_target methods. (exec_file_clear, ignore, exec_remove_breakpoint, init_exec_ops): Delete. (exec_target::find_memory_regions): New. (_initialize_exec): Don't call init_exec_ops. * gdbcore.h (exec_file_clear): Delete. * corefile.c (core_target): Delete. (core_file_command): Adjust. * corelow.c (core_target): New class. (the_core_target): New. (core_close): Remove target_ops parameter. (core_close_cleanup): Adjust. (core_target::close): New. (core_open, core_detach, get_core_registers, core_files_info) (core_xfer_partial, core_thread_alive, core_read_description) (core_pid_to_str, core_thread_name, core_has_memory) (core_has_stack, core_has_registers, core_info_proc): Rework as core_target methods. (ignore, core_remove_breakpoint, init_core_ops): Delete. (_initialize_corelow): Initialize the_core_target. * gdbcore.h (core_target): Delete. (the_core_target): New. * ctf.c: (ctf_target): New class. (ctf_ops): Now a ctf_target. (ctf_open, ctf_close, ctf_files_info, ctf_fetch_registers) (ctf_xfer_partial, ctf_get_trace_state_variable_value) (ctf_trace_find, ctf_traceframe_info): Refactor as ctf_target methods. (init_ctf_ops): Delete. (_initialize_ctf): Don't call it. * tracefile-tfile.c (tfile_target): New class. (tfile_ops): Now a tfile_target. (tfile_open, tfile_close, tfile_files_info) (tfile_get_tracepoint_status, tfile_trace_find) (tfile_fetch_registers, tfile_xfer_partial) (tfile_get_trace_state_variable_value, tfile_traceframe_info): Refactor as tfile_target methods. (tfile_xfer_partial_features): Remove target_ops parameter. (init_tfile_ops): Delete. (_initialize_tracefile_tfile): Don't call it. * tracefile.c (tracefile_has_all_memory, tracefile_has_memory) (tracefile_has_stack, tracefile_has_registers) (tracefile_thread_alive, tracefile_get_trace_status): Refactor as tracefile_target methods. (init_tracefile_ops): Delete. (tracefile_target::tracefile_target): New. * tracefile.h: Include "target.h". (tracefile_target): New class. (init_tracefile_ops): Delete. * spu-multiarch.c (spu_multiarch_target): New class. (spu_ops): Now a spu_multiarch_target. (spu_thread_architecture, spu_region_ok_for_hw_watchpoint) (spu_fetch_registers, spu_store_registers, spu_xfer_partial) (spu_search_memory, spu_mourn_inferior): Refactor as spu_multiarch_target methods. (init_spu_ops): Delete. (_initialize_spu_multiarch): Remove references to init_spu_ops, complete_target_initialization. * ravenscar-thread.c (ravenscar_thread_target): New class. (ravenscar_ops): Now a ravenscar_thread_target. (ravenscar_resume, ravenscar_wait, ravenscar_update_thread_list) (ravenscar_thread_alive, ravenscar_pid_to_str) (ravenscar_fetch_registers, ravenscar_store_registers) (ravenscar_prepare_to_store, ravenscar_stopped_by_sw_breakpoint) (ravenscar_stopped_by_hw_breakpoint) (ravenscar_stopped_by_watchpoint, ravenscar_stopped_data_address) (ravenscar_mourn_inferior, ravenscar_core_of_thread) (ravenscar_get_ada_task_ptid): Refactor as ravenscar_thread_target methods. (init_ravenscar_thread_ops): Delete. (_initialize_ravenscar): Remove references to init_ravenscar_thread_ops and complete_target_initialization. * bsd-uthread.c (bsd_uthread_ops_hack): Delete. (bsd_uthread_target): New class. (bsd_uthread_ops): Now a bsd_uthread_target. (bsd_uthread_activate): Adjust to refer to bsd_uthread_ops. (bsd_uthread_close, bsd_uthread_mourn_inferior) (bsd_uthread_fetch_registers, bsd_uthread_store_registers) (bsd_uthread_wait, bsd_uthread_resume, bsd_uthread_thread_alive) (bsd_uthread_update_thread_list, bsd_uthread_extra_thread_info) (bsd_uthread_pid_to_str): Refactor as bsd_uthread_target methods. (bsd_uthread_target): Delete function. (_initialize_bsd_uthread): Remove reference to complete_target_initialization. * bfd-target.c (target_bfd_data): Delete. Fields folded into ... (target_bfd): ... this new class. (target_bfd_xfer_partial, target_bfd_get_section_table) (target_bfd_close): Refactor as target_bfd methods. (target_bfd::~target_bfd): New. (target_bfd_reopen): Adjust. (target_bfd::close): New. * record-btrace.c (record_btrace_target): New class. (record_btrace_ops): Now a record_btrace_target. (record_btrace_open, record_btrace_stop_recording) (record_btrace_disconnect, record_btrace_close) (record_btrace_async, record_btrace_info) (record_btrace_insn_history, record_btrace_insn_history_range) (record_btrace_insn_history_from, record_btrace_call_history) (record_btrace_call_history_range) (record_btrace_call_history_from, record_btrace_record_method) (record_btrace_is_replaying, record_btrace_will_replay) (record_btrace_xfer_partial, record_btrace_insert_breakpoint) (record_btrace_remove_breakpoint, record_btrace_fetch_registers) (record_btrace_store_registers, record_btrace_prepare_to_store) (record_btrace_to_get_unwinder) (record_btrace_to_get_tailcall_unwinder, record_btrace_resume) (record_btrace_commit_resume, record_btrace_wait) (record_btrace_stop, record_btrace_can_execute_reverse) (record_btrace_stopped_by_sw_breakpoint) (record_btrace_supports_stopped_by_sw_breakpoint) (record_btrace_stopped_by_hw_breakpoint) (record_btrace_supports_stopped_by_hw_breakpoint) (record_btrace_update_thread_list, record_btrace_thread_alive) (record_btrace_goto_begin, record_btrace_goto_end) (record_btrace_goto, record_btrace_stop_replaying_all) (record_btrace_execution_direction) (record_btrace_prepare_to_generate_core) (record_btrace_done_generating_core): Refactor as record_btrace_target methods. (init_record_btrace_ops): Delete. (_initialize_record_btrace): Remove reference to init_record_btrace_ops. * record-full.c (RECORD_FULL_IS_REPLAY): Adjust to always refer to the execution_direction global. (record_full_base_target, record_full_target) (record_full_core_target): New classes. (record_full_ops): Now a record_full_target. (record_full_core_ops): Now a record_full_core_target. (record_full_target::detach, record_full_target::disconnect) (record_full_core_target::disconnect) (record_full_target::mourn_inferior, record_full_target::kill): New. (record_full_open, record_full_close, record_full_async): Refactor as methods of the record_full_base_target class. (record_full_resume, record_full_commit_resume): Refactor as methods of the record_full_target class. (record_full_wait, record_full_stopped_by_watchpoint) (record_full_stopped_data_address) (record_full_stopped_by_sw_breakpoint) (record_full_supports_stopped_by_sw_breakpoint) (record_full_stopped_by_hw_breakpoint) (record_full_supports_stopped_by_hw_breakpoint): Refactor as methods of the record_full_base_target class. (record_full_store_registers, record_full_xfer_partial) (record_full_insert_breakpoint, record_full_remove_breakpoint): Refactor as methods of the record_full_target class. (record_full_can_execute_reverse, record_full_get_bookmark) (record_full_goto_bookmark, record_full_execution_direction) (record_full_record_method, record_full_info, record_full_delete) (record_full_is_replaying, record_full_will_replay) (record_full_goto_begin, record_full_goto_end, record_full_goto) (record_full_stop_replaying): Refactor as methods of the record_full_base_target class. (record_full_core_resume, record_full_core_kill) (record_full_core_fetch_registers) (record_full_core_prepare_to_store) (record_full_core_store_registers, record_full_core_xfer_partial) (record_full_core_insert_breakpoint) (record_full_core_remove_breakpoint) (record_full_core_has_execution): Refactor as methods of the record_full_core_target class. (record_full_base_target::supports_delete_record): New. (init_record_full_ops): Delete. (init_record_full_core_ops): Delete. (record_full_save): Refactor as method of the record_full_base_target class. (_initialize_record_full): Remove references to init_record_full_ops and init_record_full_core_ops. * remote.c (remote_target, extended_remote_target): New classes. (remote_ops): Now a remote_target. (extended_remote_ops): Now an extended_remote_target. (remote_insert_fork_catchpoint, remote_remove_fork_catchpoint) (remote_insert_vfork_catchpoint, remote_remove_vfork_catchpoint) (remote_insert_exec_catchpoint, remote_remove_exec_catchpoint) (remote_pass_signals, remote_set_syscall_catchpoint) (remote_program_signals, ) (remote_thread_always_alive): Remove target_ops parameter. (remote_thread_alive, remote_thread_name) (remote_update_thread_list, remote_threads_extra_info) (remote_static_tracepoint_marker_at) (remote_static_tracepoint_markers_by_strid) (remote_get_ada_task_ptid, remote_close, remote_start_remote) (remote_open): Refactor as methods of remote_target. (extended_remote_open, extended_remote_detach) (extended_remote_attach, extended_remote_post_attach): (extended_remote_supports_disable_randomization) (extended_remote_create_inferior): : Refactor as method of extended_remote_target. (remote_set_permissions, remote_open_1, remote_detach) (remote_follow_fork, remote_follow_exec, remote_disconnect) (remote_resume, remote_commit_resume, remote_stop) (remote_interrupt, remote_pass_ctrlc, remote_terminal_inferior) (remote_terminal_ours, remote_wait, remote_fetch_registers) (remote_prepare_to_store, remote_store_registers) (remote_flash_erase, remote_flash_done, remote_files_info) (remote_kill, remote_mourn, remote_insert_breakpoint) (remote_remove_breakpoint, remote_insert_watchpoint) (remote_watchpoint_addr_within_range) (remote_remove_watchpoint, remote_region_ok_for_hw_watchpoint) (remote_check_watch_resources, remote_stopped_by_sw_breakpoint) (remote_supports_stopped_by_sw_breakpoint) (remote_stopped_by_hw_breakpoint) (remote_supports_stopped_by_hw_breakpoint) (remote_stopped_by_watchpoint, remote_stopped_data_address) (remote_insert_hw_breakpoint, remote_remove_hw_breakpoint) (remote_verify_memory): Refactor as methods of remote_target. (remote_write_qxfer, remote_read_qxfer): Remove target_ops parameter. (remote_xfer_partial, remote_get_memory_xfer_limit) (remote_search_memory, remote_rcmd, remote_memory_map) (remote_pid_to_str, remote_get_thread_local_address) (remote_get_tib_address, remote_read_description): Refactor as methods of remote_target. (remote_target::fileio_open, remote_target::fileio_pwrite) (remote_target::fileio_pread, remote_target::fileio_close): New. (remote_hostio_readlink, remote_hostio_fstat) (remote_filesystem_is_local, remote_can_execute_reverse) (remote_supports_non_stop, remote_supports_disable_randomization) (remote_supports_multi_process, remote_supports_cond_breakpoints) (remote_supports_enable_disable_tracepoint) (remote_supports_string_tracing) (remote_can_run_breakpoint_commands, remote_trace_init) (remote_download_tracepoint, remote_can_download_tracepoint) (remote_download_trace_state_variable, remote_enable_tracepoint) (remote_disable_tracepoint, remote_trace_set_readonly_regions) (remote_trace_start, remote_get_trace_status) (remote_get_tracepoint_status, remote_trace_stop) (remote_trace_find, remote_get_trace_state_variable_value) (remote_save_trace_data, remote_get_raw_trace_data) (remote_set_disconnected_tracing, remote_core_of_thread) (remote_set_circular_trace_buffer, remote_traceframe_info) (remote_get_min_fast_tracepoint_insn_len) (remote_set_trace_buffer_size, remote_set_trace_notes) (remote_use_agent, remote_can_use_agent, remote_enable_btrace) (remote_disable_btrace, remote_teardown_btrace) (remote_read_btrace, remote_btrace_conf) (remote_augmented_libraries_svr4_read, remote_load) (remote_pid_to_exec_file, remote_can_do_single_step) (remote_execution_direction, remote_thread_handle_to_thread_info): Refactor as methods of remote_target. (init_remote_ops, init_extended_remote_ops): Delete. (remote_can_async_p, remote_is_async_p, remote_async) (remote_thread_events, remote_upload_tracepoints) (remote_upload_trace_state_variables): Refactor as methods of remote_target. (_initialize_remote): Remove references to init_remote_ops and init_extended_remote_ops. * remote-sim.c (gdbsim_target): New class. (gdbsim_fetch_register, gdbsim_store_register, gdbsim_kill) (gdbsim_load, gdbsim_create_inferior, gdbsim_open, gdbsim_close) (gdbsim_detach, gdbsim_resume, gdbsim_interrupt) (gdbsim_wait, gdbsim_prepare_to_store, gdbsim_xfer_partial) (gdbsim_files_info, gdbsim_mourn_inferior, gdbsim_thread_alive) (gdbsim_pid_to_str, gdbsim_has_all_memory, gdbsim_has_memory): Refactor as methods of gdbsim_target. (gdbsim_ops): Now a gdbsim_target. (init_gdbsim_ops): Delete. (gdbsim_cntrl_c): Adjust. (_initialize_remote_sim): Remove reference to init_gdbsim_ops. * amd64-linux-nat.c (amd64_linux_nat_target): New class. (the_amd64_linux_nat_target): New. (amd64_linux_fetch_inferior_registers) (amd64_linux_store_inferior_registers): Refactor as methods of amd64_linux_nat_target. (_initialize_amd64_linux_nat): Adjust. Set linux_target. * i386-linux-nat.c: Don't include "linux-nat.h". (i386_linux_nat_target): New class. (the_i386_linux_nat_target): New. (i386_linux_fetch_inferior_registers) (i386_linux_store_inferior_registers, i386_linux_resume): Refactor as methods of i386_linux_nat_target. (_initialize_i386_linux_nat): Adjust. Set linux_target. * inf-child.c (inf_child_ops): Delete. (inf_child_fetch_inferior_registers) (inf_child_store_inferior_registers): Delete. (inf_child_post_attach, inf_child_prepare_to_store): Refactor as methods of inf_child_target. (inf_child_target::supports_terminal_ours) (inf_child_target::terminal_init) (inf_child_target::terminal_inferior) (inf_child_target::terminal_ours_for_output) (inf_child_target::terminal_ours, inf_child_target::interrupt) (inf_child_target::pass_ctrlc, inf_child_target::terminal_info): New. (inf_child_open, inf_child_disconnect, inf_child_close) (inf_child_mourn_inferior, inf_child_maybe_unpush_target) (inf_child_post_startup_inferior, inf_child_can_run) (inf_child_pid_to_exec_file): Refactor as methods of inf_child_target. (inf_child_follow_fork): Delete. (inf_child_target::can_create_inferior) (inf_child_target::can_attach): New. (inf_child_target::has_all_memory, inf_child_target::has_memory) (inf_child_target::has_stack, inf_child_target::has_registers) (inf_child_target::has_execution): New. (inf_child_fileio_open, inf_child_fileio_pwrite) (inf_child_fileio_pread, inf_child_fileio_fstat) (inf_child_fileio_close, inf_child_fileio_unlink) (inf_child_fileio_readlink, inf_child_use_agent) (inf_child_can_use_agent): Refactor as methods of inf_child_target. (return_zero, inf_child_target): Delete. (inf_child_target::inf_child_target): New. * inf-child.h: Include "target.h". (inf_child_target): Delete function prototype. (inf_child_target): New class. (inf_child_open_target, inf_child_mourn_inferior) (inf_child_maybe_unpush_target): Delete. * inf-ptrace.c (inf_ptrace_target::~inf_ptrace_target): New. (inf_ptrace_follow_fork, inf_ptrace_insert_fork_catchpoint) (inf_ptrace_remove_fork_catchpoint, inf_ptrace_create_inferior) (inf_ptrace_post_startup_inferior, inf_ptrace_mourn_inferior) (inf_ptrace_attach, inf_ptrace_post_attach, inf_ptrace_detach) (inf_ptrace_detach_success, inf_ptrace_kill, inf_ptrace_resume) (inf_ptrace_wait, inf_ptrace_xfer_partial) (inf_ptrace_thread_alive, inf_ptrace_files_info) (inf_ptrace_pid_to_str, inf_ptrace_auxv_parse): Refactor as methods of inf_ptrace_target. (inf_ptrace_target): Delete function. * inf-ptrace.h: Include "inf-child.h". (inf_ptrace_target): Delete function declaration. (inf_ptrace_target): New class. (inf_ptrace_trad_target, inf_ptrace_detach_success): Delete. * linux-nat.c (linux_target): New. (linux_ops, linux_ops_saved, super_xfer_partial): Delete. (linux_nat_target::~linux_nat_target): New. (linux_child_post_attach, linux_child_post_startup_inferior) (linux_child_follow_fork, linux_child_insert_fork_catchpoint) (linux_child_remove_fork_catchpoint) (linux_child_insert_vfork_catchpoint) (linux_child_remove_vfork_catchpoint) (linux_child_insert_exec_catchpoint) (linux_child_remove_exec_catchpoint) (linux_child_set_syscall_catchpoint, linux_nat_pass_signals) (linux_nat_create_inferior, linux_nat_attach, linux_nat_detach) (linux_nat_resume, linux_nat_stopped_by_watchpoint) (linux_nat_stopped_data_address) (linux_nat_stopped_by_sw_breakpoint) (linux_nat_supports_stopped_by_sw_breakpoint) (linux_nat_stopped_by_hw_breakpoint) (linux_nat_supports_stopped_by_hw_breakpoint, linux_nat_wait) (linux_nat_kill, linux_nat_mourn_inferior) (linux_nat_xfer_partial, linux_nat_thread_alive) (linux_nat_update_thread_list, linux_nat_pid_to_str) (linux_nat_thread_name, linux_child_pid_to_exec_file) (linux_child_static_tracepoint_markers_by_strid) (linux_nat_is_async_p, linux_nat_can_async_p) (linux_nat_supports_non_stop, linux_nat_always_non_stop_p) (linux_nat_supports_multi_process) (linux_nat_supports_disable_randomization, linux_nat_async) (linux_nat_stop, linux_nat_close, linux_nat_thread_address_space) (linux_nat_core_of_thread, linux_nat_filesystem_is_local) (linux_nat_fileio_open, linux_nat_fileio_readlink) (linux_nat_fileio_unlink, linux_nat_thread_events): Refactor as methods of linux_nat_target. (linux_nat_wait_1, linux_xfer_siginfo, linux_proc_xfer_partial) (linux_proc_xfer_spu, linux_nat_xfer_osdata): Remove target_ops parameter. (check_stopped_by_watchpoint): Adjust. (linux_xfer_partial): Delete. (linux_target_install_ops, linux_target, linux_nat_add_target): Delete. (linux_nat_target::linux_nat_target): New. * linux-nat.h: Include "inf-ptrace.h". (linux_nat_target): New. (linux_target, linux_target_install_ops, linux_nat_add_target): Delete function declarations. (linux_target): Declare global. * linux-thread-db.c (thread_db_target): New. (thread_db_target::thread_db_target): New. (thread_db_ops): Delete. (the_thread_db_target): New. (thread_db_detach, thread_db_wait, thread_db_mourn_inferior) (thread_db_update_thread_list, thread_db_pid_to_str) (thread_db_extra_thread_info) (thread_db_thread_handle_to_thread_info) (thread_db_get_thread_local_address, thread_db_get_ada_task_ptid) (thread_db_resume): Refactor as methods of thread_db_target. (init_thread_db_ops): Delete. (_initialize_thread_db): Remove reference to init_thread_db_ops. * x86-linux-nat.c: Don't include "linux-nat.h". (super_post_startup_inferior): Delete. (x86_linux_nat_target::~x86_linux_nat_target): New. (x86_linux_child_post_startup_inferior) (x86_linux_read_description, x86_linux_enable_btrace) (x86_linux_disable_btrace, x86_linux_teardown_btrace) (x86_linux_read_btrace, x86_linux_btrace_conf): Refactor as methods of x86_linux_nat_target. (x86_linux_create_target): Delete. Bits folded ... (x86_linux_add_target): ... here. Now takes a linux_nat_target pointer. * x86-linux-nat.h: Include "linux-nat.h" and "x86-nat.h". (x86_linux_nat_target): New class. (x86_linux_create_target): Delete. (x86_linux_add_target): Now takes a linux_nat_target pointer. * x86-nat.c (x86_insert_watchpoint, x86_remove_watchpoint) (x86_region_ok_for_watchpoint, x86_stopped_data_address) (x86_stopped_by_watchpoint, x86_insert_hw_breakpoint) (x86_remove_hw_breakpoint, x86_can_use_hw_breakpoint) (x86_stopped_by_hw_breakpoint): Remove target_ops parameter and make extern. (x86_use_watchpoints): Delete. * x86-nat.h: Include "breakpoint.h" and "target.h". (x86_use_watchpoints): Delete. (x86_can_use_hw_breakpoint, x86_region_ok_for_hw_watchpoint) (x86_stopped_by_watchpoint, x86_stopped_data_address) (x86_insert_watchpoint, x86_remove_watchpoint) (x86_insert_hw_breakpoint, x86_remove_hw_breakpoint) (x86_stopped_by_hw_breakpoint): New declarations. (x86_nat_target): New template class. * ppc-linux-nat.c (ppc_linux_nat_target): New class. (the_ppc_linux_nat_target): New. (ppc_linux_fetch_inferior_registers) (ppc_linux_can_use_hw_breakpoint) (ppc_linux_region_ok_for_hw_watchpoint) (ppc_linux_ranged_break_num_registers) (ppc_linux_insert_hw_breakpoint, ppc_linux_remove_hw_breakpoint) (ppc_linux_insert_mask_watchpoint) (ppc_linux_remove_mask_watchpoint) (ppc_linux_can_accel_watchpoint_condition) (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint) (ppc_linux_stopped_data_address, ppc_linux_stopped_by_watchpoint) (ppc_linux_watchpoint_addr_within_range) (ppc_linux_masked_watch_num_registers) (ppc_linux_store_inferior_registers, ppc_linux_auxv_parse) (ppc_linux_read_description): Refactor as methods of ppc_linux_nat_target. (_initialize_ppc_linux_nat): Adjust. Set linux_target. * procfs.c (procfs_xfer_partial): Delete forward declaration. (procfs_target): New class. (the_procfs_target): New. (procfs_target): Delete function. (procfs_auxv_parse, procfs_attach, procfs_detach) (procfs_fetch_registers, procfs_store_registers, procfs_wait) (procfs_xfer_partial, procfs_resume, procfs_pass_signals) (procfs_files_info, procfs_kill_inferior, procfs_mourn_inferior) (procfs_create_inferior, procfs_update_thread_list) (procfs_thread_alive, procfs_pid_to_str) (procfs_can_use_hw_breakpoint, procfs_stopped_by_watchpoint) (procfs_stopped_data_address, procfs_insert_watchpoint) (procfs_remove_watchpoint, procfs_region_ok_for_hw_watchpoint) (proc_find_memory_regions, procfs_info_proc) (procfs_make_note_section): Refactor as methods of procfs_target. (_initialize_procfs): Adjust. * sol-thread.c (sol_thread_target): New class. (sol_thread_ops): Now a sol_thread_target. (sol_thread_detach, sol_thread_resume, sol_thread_wait) (sol_thread_fetch_registers, sol_thread_store_registers) (sol_thread_xfer_partial, sol_thread_mourn_inferior) (sol_thread_alive, solaris_pid_to_str, sol_update_thread_list) (sol_get_ada_task_ptid): Refactor as methods of sol_thread_target. (init_sol_thread_ops): Delete. (_initialize_sol_thread): Adjust. Remove references to init_sol_thread_ops and complete_target_initialization. * windows-nat.c (windows_nat_target): New class. (windows_fetch_inferior_registers) (windows_store_inferior_registers, windows_resume, windows_wait) (windows_attach, windows_detach, windows_pid_to_exec_file) (windows_files_info, windows_create_inferior) (windows_mourn_inferior, windows_interrupt, windows_kill_inferior) (windows_close, windows_pid_to_str, windows_xfer_partial) (windows_get_tib_address, windows_get_ada_task_ptid) (windows_thread_name, windows_thread_alive): Refactor as windows_nat_target methods. (do_initial_windows_stuff): Adjust. (windows_target): Delete function. (_initialize_windows_nat): Adjust. * darwin-nat.c (darwin_resume, darwin_wait_to, darwin_interrupt) (darwin_mourn_inferior, darwin_kill_inferior) (darwin_create_inferior, darwin_attach, darwin_detach) (darwin_pid_to_str, darwin_thread_alive, darwin_xfer_partial) (darwin_pid_to_exec_file, darwin_get_ada_task_ptid) (darwin_supports_multi_process): Refactor as darwin_nat_target methods. (darwin_resume_to, darwin_files_info): Delete. (_initialize_darwin_inferior): Rename to ... (_initialize_darwin_nat): ... this. Adjust to C++ification. * darwin-nat.h: Include "inf-child.h". (darwin_nat_target): New class. (darwin_complete_target): Delete. * i386-darwin-nat.c (i386_darwin_nat_target): New class. (darwin_target): New. (i386_darwin_fetch_inferior_registers) (i386_darwin_store_inferior_registers): Refactor as methods of darwin_nat_target. (darwin_complete_target): Delete, with ... (_initialize_i386_darwin_nat): ... bits factored out here. * alpha-linux-nat.c (alpha_linux_nat_target): New class. (the_alpha_linux_nat_target): New. (alpha_linux_register_u_offset): Refactor as alpha_linux_nat_target method. (_initialize_alpha_linux_nat): Adjust. * linux-nat-trad.c (inf_ptrace_register_u_offset): Delete. (inf_ptrace_fetch_register, inf_ptrace_fetch_registers) (inf_ptrace_store_register, inf_ptrace_store_registers): Refact as methods of linux_nat_trad_target. (linux_trad_target): Delete. * linux-nat-trad.h (linux_trad_target): Delete function. (linux_nat_trad_target): New class. * mips-linux-nat.c (mips_linux_nat_target): New class. (super_fetch_registers, super_store_registers, super_close): Delete. (the_mips_linux_nat_target): New. (mips64_linux_regsets_fetch_registers) (mips64_linux_regsets_store_registers) (mips64_linux_fetch_registers, mips64_linux_store_registers) (mips_linux_register_u_offset, mips_linux_read_description) (mips_linux_can_use_hw_breakpoint) (mips_linux_stopped_by_watchpoint) (mips_linux_stopped_data_address) (mips_linux_region_ok_for_hw_watchpoint) (mips_linux_insert_watchpoint, mips_linux_remove_watchpoint) (mips_linux_close): Refactor as methods of mips_linux_nat. (_initialize_mips_linux_nat): Adjust to C++ification. * aix-thread.c (aix_thread_target): New class. (aix_thread_ops): Now an aix_thread_target. (aix_thread_detach, aix_thread_resume, aix_thread_wait) (aix_thread_fetch_registers, aix_thread_store_registers) (aix_thread_xfer_partial, aix_thread_mourn_inferior) (aix_thread_thread_alive, aix_thread_pid_to_str) (aix_thread_extra_thread_info, aix_thread_get_ada_task_ptid): Refactor as methods of aix_thread_target. (init_aix_thread_ops): Delete. (_initialize_aix_thread): Remove references to init_aix_thread_ops and complete_target_initialization. * rs6000-nat.c (rs6000_xfer_shared_libraries): Delete. (rs6000_nat_target): New class. (the_rs6000_nat_target): New. (rs6000_fetch_inferior_registers, rs6000_store_inferior_registers) (rs6000_xfer_partial, rs6000_wait, rs6000_create_inferior) (rs6000_xfer_shared_libraries): Refactor as rs6000_nat_target methods. (super_create_inferior): Delete. (_initialize_rs6000_nat): Adjust to C++ification. * arm-linux-nat.c (arm_linux_nat_target): New class. (the_arm_linux_nat_target): New. (arm_linux_fetch_inferior_registers) (arm_linux_store_inferior_registers, arm_linux_read_description) (arm_linux_can_use_hw_breakpoint, arm_linux_insert_hw_breakpoint) (arm_linux_remove_hw_breakpoint) (arm_linux_region_ok_for_hw_watchpoint) (arm_linux_insert_watchpoint, arm_linux_remove_watchpoint) (arm_linux_stopped_data_address, arm_linux_stopped_by_watchpoint) (arm_linux_watchpoint_addr_within_range): Refactor as methods of arm_linux_nat_target. (_initialize_arm_linux_nat): Adjust to C++ification. * aarch64-linux-nat.c (aarch64_linux_nat_target): New class. (the_aarch64_linux_nat_target): New. (aarch64_linux_fetch_inferior_registers) (aarch64_linux_store_inferior_registers) (aarch64_linux_child_post_startup_inferior) (aarch64_linux_read_description) (aarch64_linux_can_use_hw_breakpoint) (aarch64_linux_insert_hw_breakpoint) (aarch64_linux_remove_hw_breakpoint) (aarch64_linux_insert_watchpoint, aarch64_linux_remove_watchpoint) (aarch64_linux_region_ok_for_hw_watchpoint) (aarch64_linux_stopped_data_address) (aarch64_linux_stopped_by_watchpoint) (aarch64_linux_watchpoint_addr_within_range) (aarch64_linux_can_do_single_step): Refactor as methods of aarch64_linux_nat_target. (super_post_startup_inferior): Delete. (_initialize_aarch64_linux_nat): Adjust to C++ification. * hppa-linux-nat.c (hppa_linux_nat_target): New class. (the_hppa_linux_nat_target): New. (hppa_linux_fetch_inferior_registers) (hppa_linux_store_inferior_registers): Refactor as methods of hppa_linux_nat_target. (_initialize_hppa_linux_nat): Adjust to C++ification. * ia64-linux-nat.c (ia64_linux_nat_target): New class. (the_ia64_linux_nat_target): New. (ia64_linux_insert_watchpoint, ia64_linux_remove_watchpoint) (ia64_linux_stopped_data_address) (ia64_linux_stopped_by_watchpoint, ia64_linux_fetch_registers) (ia64_linux_store_registers, ia64_linux_xfer_partial): Refactor as ia64_linux_nat_target methods. (super_xfer_partial): Delete. (_initialize_ia64_linux_nat): Adjust to C++ification. * m32r-linux-nat.c (m32r_linux_nat_target): New class. (the_m32r_linux_nat_target): New. (m32r_linux_fetch_inferior_registers) (m32r_linux_store_inferior_registers): Refactor as m32r_linux_nat_target methods. (_initialize_m32r_linux_nat): Adjust to C++ification. * m68k-linux-nat.c (m68k_linux_nat_target): New class. (the_m68k_linux_nat_target): New. (m68k_linux_fetch_inferior_registers) (m68k_linux_store_inferior_registers): Refactor as m68k_linux_nat_target methods. (_initialize_m68k_linux_nat): Adjust to C++ification. * s390-linux-nat.c (s390_linux_nat_target): New class. (the_s390_linux_nat_target): New. (s390_linux_fetch_inferior_registers) (s390_linux_store_inferior_registers, s390_stopped_by_watchpoint) (s390_insert_watchpoint, s390_remove_watchpoint) (s390_can_use_hw_breakpoint, s390_insert_hw_breakpoint) (s390_remove_hw_breakpoint, s390_region_ok_for_hw_watchpoint) (s390_auxv_parse, s390_read_description): Refactor as methods of s390_linux_nat_target. (_initialize_s390_nat): Adjust to C++ification. * sparc-linux-nat.c (sparc_linux_nat_target): New class. (the_sparc_linux_nat_target): New. (_initialize_sparc_linux_nat): Adjust to C++ification. * sparc-nat.c (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers): Remove target_ops parameter. * sparc64-linux-nat.c (sparc64_linux_nat_target): New class. (the_sparc64_linux_nat_target): New. (_initialize_sparc64_linux_nat): Adjust to C++ification. * spu-linux-nat.c (spu_linux_nat_target): New class. (the_spu_linux_nat_target): New. (spu_child_post_startup_inferior, spu_child_post_attach) (spu_child_wait, spu_fetch_inferior_registers) (spu_store_inferior_registers, spu_xfer_partial) (spu_can_use_hw_breakpoint): Refactor as spu_linux_nat_target methods. (_initialize_spu_nat): Adjust to C++ification. * tilegx-linux-nat.c (tilegx_linux_nat_target): New class. (the_tilegx_linux_nat_target): New. (fetch_inferior_registers, store_inferior_registers): Refactor as methods. (_initialize_tile_linux_nat): Adjust to C++ification. * xtensa-linux-nat.c (xtensa_linux_nat_target): New class. (the_xtensa_linux_nat_target): New. (xtensa_linux_fetch_inferior_registers) (xtensa_linux_store_inferior_registers): Refactor as xtensa_linux_nat_target methods. (_initialize_xtensa_linux_nat): Adjust to C++ification. * fbsd-nat.c (USE_SIGTRAP_SIGINFO): Delete. (fbsd_pid_to_exec_file, fbsd_find_memory_regions) (fbsd_find_memory_regions, fbsd_info_proc, fbsd_xfer_partial) (fbsd_thread_alive, fbsd_pid_to_str, fbsd_thread_name) (fbsd_update_thread_list, fbsd_resume, fbsd_wait) (fbsd_stopped_by_sw_breakpoint) (fbsd_supports_stopped_by_sw_breakpoint, fbsd_follow_fork) (fbsd_insert_fork_catchpoint, fbsd_remove_fork_catchpoint) (fbsd_insert_vfork_catchpoint, fbsd_remove_vfork_catchpoint) (fbsd_post_startup_inferior, fbsd_post_attach) (fbsd_insert_exec_catchpoint, fbsd_remove_exec_catchpoint) (fbsd_set_syscall_catchpoint) (super_xfer_partial, super_resume, super_wait) (fbsd_supports_stopped_by_hw_breakpoint): Delete. (fbsd_handle_debug_trap): Remove target_ops parameter. (fbsd_nat_add_target): Delete. * fbsd-nat.h: Include "inf-ptrace.h". (fbsd_nat_add_target): Delete. (USE_SIGTRAP_SIGINFO): Define. (fbsd_nat_target): New class. * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers) (amd64bsd_store_inferior_registers): Remove target_ops parameter. (amd64bsd_target): Delete. * amd64-bsd-nat.h: New file. * amd64-fbsd-nat.c: Include "amd64-bsd-nat.h" instead of "x86-bsd-nat.h". (amd64_fbsd_nat_target): New class. (the_amd64_fbsd_nat_target): New. (amd64fbsd_read_description): Refactor as method of amd64_fbsd_nat_target. (amd64_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_amd64fbsd_nat): Adjust to C++ification. * amd64-nat.h (amd64bsd_target): Delete function declaration. * i386-bsd-nat.c (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Remove target_ops parameter. (i386bsd_target): Delete. * i386-bsd-nat.h (i386bsd_target): Delete function declaration. (i386bsd_fetch_inferior_registers) (i386bsd_store_inferior_registers): Declare. (i386_bsd_nat_target): New class. * i386-fbsd-nat.c (i386_fbsd_nat_target): New class. (the_i386_fbsd_nat_target): New. (i386fbsd_resume, i386fbsd_read_description): Refactor as i386_fbsd_nat_target methods. (i386_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New. (_initialize_i386fbsd_nat): Adjust to C++ification. * x86-bsd-nat.c (super_mourn_inferior): Delete. (x86bsd_mourn_inferior, x86bsd_target): Delete. (_initialize_x86_bsd_nat): Adjust to C++ification. * x86-bsd-nat.h: Include "x86-nat.h". (x86bsd_target): Delete declaration. (x86bsd_nat_target): New class. * aarch64-fbsd-nat.c (aarch64_fbsd_nat_target): New class. (the_aarch64_fbsd_nat_target): New. (aarch64_fbsd_fetch_inferior_registers) (aarch64_fbsd_store_inferior_registers): Refactor as methods of aarch64_fbsd_nat_target. (_initialize_aarch64_fbsd_nat): Adjust to C++ification. * alpha-bsd-nat.c (alpha_bsd_nat_target): New class. (the_alpha_bsd_nat_target): New. (alphabsd_fetch_inferior_registers) (alphabsd_store_inferior_registers): Refactor as alpha_bsd_nat_target methods. (_initialize_alphabsd_nat): Refactor as methods of alpha_bsd_nat_target. * amd64-nbsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_nbsd_nat_target): New. (_initialize_amd64nbsd_nat): Adjust to C++ification. * amd64-obsd-nat.c: Include "amd64-bsd-nat.h". (the_amd64_obsd_nat_target): New. (_initialize_amd64obsd_nat): Adjust to C++ification. * arm-fbsd-nat.c (arm_fbsd_nat_target): New. (the_arm_fbsd_nat_target): New. (arm_fbsd_fetch_inferior_registers) (arm_fbsd_store_inferior_registers, arm_fbsd_read_description): (_initialize_arm_fbsd_nat): Refactor as methods of arm_fbsd_nat_target. (_initialize_arm_fbsd_nat): Adjust to C++ification. * arm-nbsd-nat.c (arm_netbsd_nat_target): New class. (the_arm_netbsd_nat_target): New. (armnbsd_fetch_registers, armnbsd_store_registers): Refactor as arm_netbsd_nat_target. (_initialize_arm_netbsd_nat): Adjust to C++ification. * hppa-nbsd-nat.c (hppa_nbsd_nat_target): New class. (the_hppa_nbsd_nat_target): New. (hppanbsd_fetch_registers, hppanbsd_store_registers): Refactor as hppa_nbsd_nat_target methods. (_initialize_hppanbsd_nat): Adjust to C++ification. * hppa-obsd-nat.c (hppa_obsd_nat_target): New class. (the_hppa_obsd_nat_target): New. (hppaobsd_fetch_registers, hppaobsd_store_registers): Refactor as methods of hppa_obsd_nat_target. (_initialize_hppaobsd_nat): Adjust to C++ification. Use add_target. * i386-nbsd-nat.c (the_i386_nbsd_nat_target): New. (_initialize_i386nbsd_nat): Adjust to C++ification. Use add_target. * i386-obsd-nat.c (the_i386_obsd_nat_target): New. (_initialize_i386obsd_nat): Use add_target. * m68k-bsd-nat.c (m68k_bsd_nat_target): New class. (the_m68k_bsd_nat_target): New. (m68kbsd_fetch_inferior_registers) (m68kbsd_store_inferior_registers): Refactor as methods of m68k_bsd_nat_target. (_initialize_m68kbsd_nat): Adjust to C++ification. * mips-fbsd-nat.c (mips_fbsd_nat_target): New class. (the_mips_fbsd_nat_target): New. (mips_fbsd_fetch_inferior_registers) (mips_fbsd_store_inferior_registers): Refactor as methods of mips_fbsd_nat_target. (_initialize_mips_fbsd_nat): Adjust to C++ification. Use add_target. * mips-nbsd-nat.c (mips_nbsd_nat_target): New class. (the_mips_nbsd_nat_target): New. (mipsnbsd_fetch_inferior_registers) (mipsnbsd_store_inferior_registers): Refactor as methods of mips_nbsd_nat_target. (_initialize_mipsnbsd_nat): Adjust to C++ification. * mips64-obsd-nat.c (mips64_obsd_nat_target): New class. (the_mips64_obsd_nat_target): New. (mips64obsd_fetch_inferior_registers) (mips64obsd_store_inferior_registers): Refactor as methods of mips64_obsd_nat_target. (_initialize_mips64obsd_nat): Adjust to C++ification. Use add_target. * nbsd-nat.c (nbsd_pid_to_exec_file): Refactor as method of nbsd_nat_target. * nbsd-nat.h: Include "inf-ptrace.h". (nbsd_nat_target): New class. * obsd-nat.c (obsd_pid_to_str, obsd_update_thread_list) (obsd_wait): Refactor as methods of obsd_nat_target. (obsd_add_target): Delete. * obsd-nat.h: Include "inf-ptrace.h". (obsd_nat_target): New class. * ppc-fbsd-nat.c (ppc_fbsd_nat_target): New class. (the_ppc_fbsd_nat_target): New. (ppcfbsd_fetch_inferior_registers) (ppcfbsd_store_inferior_registers): Refactor as methods of ppc_fbsd_nat_target. (_initialize_ppcfbsd_nat): Adjust to C++ification. Use add_target. * ppc-nbsd-nat.c (ppc_nbsd_nat_target): New class. (the_ppc_nbsd_nat_target): New. (ppcnbsd_fetch_inferior_registers) (ppcnbsd_store_inferior_registers): Refactor as methods of ppc_nbsd_nat_target. (_initialize_ppcnbsd_nat): Adjust to C++ification. * ppc-obsd-nat.c (ppc_obsd_nat_target): New class. (the_ppc_obsd_nat_target): New. (ppcobsd_fetch_registers, ppcobsd_store_registers): Refactor as methods of ppc_obsd_nat_target. (_initialize_ppcobsd_nat): Adjust to C++ification. Use add_target. * sh-nbsd-nat.c (sh_nbsd_nat_target): New class. (the_sh_nbsd_nat_target): New. (shnbsd_fetch_inferior_registers) (shnbsd_store_inferior_registers): Refactor as methods of sh_nbsd_nat_target. (_initialize_shnbsd_nat): Adjust to C++ification. * sparc-nat.c (sparc_xfer_wcookie): Make extern. (inf_ptrace_xfer_partial): Delete. (sparc_xfer_partial, sparc_target): Delete. * sparc-nat.h (sparc_fetch_inferior_registers) (sparc_store_inferior_registers, sparc_xfer_wcookie): Declare. (sparc_target): Delete function declaration. (sparc_target): New template class. * sparc-nbsd-nat.c (the_sparc_nbsd_nat_target): New. (_initialize_sparcnbsd_nat): Adjust to C++ification. * sparc64-fbsd-nat.c (the_sparc64_fbsd_nat_target): New. (_initialize_sparc64fbsd_nat): Adjust to C++ification. Use add_target. * sparc64-nbsd-nat.c (the_sparc64_nbsd_nat_target): New. (_initialize_sparc64nbsd_nat): Adjust to C++ification. * sparc64-obsd-nat.c (the_sparc64_obsd_nat_target): New. (_initialize_sparc64obsd_nat): Adjust to C++ification. Use add_target. * vax-bsd-nat.c (vax_bsd_nat_target): New class. (the_vax_bsd_nat_target): New. (vaxbsd_fetch_inferior_registers) (vaxbsd_store_inferior_registers): Refactor as vax_bsd_nat_target methods. (_initialize_vaxbsd_nat): Adjust to C++ification. * bsd-kvm.c (bsd_kvm_target): New class. (bsd_kvm_ops): Now a bsd_kvm_target. (bsd_kvm_open, bsd_kvm_close, bsd_kvm_xfer_partial) (bsd_kvm_files_info, bsd_kvm_fetch_registers) (bsd_kvm_thread_alive, bsd_kvm_pid_to_str): Refactor as methods of bsd_kvm_target. (bsd_kvm_return_one): Delete. (bsd_kvm_add_target): Adjust to C++ification. * nto-procfs.c (nto_procfs_target, nto_procfs_target_native) (nto_procfs_target_procfs): New classes. (procfs_open_1, procfs_thread_alive, procfs_update_thread_list) (procfs_files_info, procfs_pid_to_exec_file, procfs_attach) (procfs_post_attach, procfs_wait, procfs_fetch_registers) (procfs_xfer_partial, procfs_detach, procfs_insert_breakpoint) (procfs_remove_breakpoint, procfs_insert_hw_breakpoint) (procfs_remove_hw_breakpoint, procfs_resume) (procfs_mourn_inferior, procfs_create_inferior, procfs_interrupt) (procfs_kill_inferior, procfs_store_registers) (procfs_pass_signals, procfs_pid_to_str, procfs_can_run): Refactor as methods of nto_procfs_target. (nto_procfs_ops): Now an nto_procfs_target_procfs. (nto_native_ops): Delete. (procfs_open, procfs_native_open): Delete. (nto_native_ops): Now an nto_procfs_target_native. (init_procfs_targets): Adjust to C++ification. (procfs_can_use_hw_breakpoint, procfs_remove_hw_watchpoint) (procfs_insert_hw_watchpoint, procfs_stopped_by_watchpoint): Refactor as methods of nto_procfs_target. * go32-nat.c (go32_nat_target): New class. (the_go32_nat_target): New. (go32_attach, go32_resume, go32_wait, go32_fetch_registers) (go32_store_registers, go32_xfer_partial, go32_files_info) (go32_kill_inferior, go32_create_inferior, go32_mourn_inferior) (go32_terminal_init, go32_terminal_info, go32_terminal_inferior) (go32_terminal_ours, go32_pass_ctrlc, go32_thread_alive) (go32_pid_to_str): Refactor as methods of go32_nat_target. (go32_target): Delete. (_initialize_go32_nat): Adjust to C++ification. * gnu-nat.c (gnu_wait, gnu_resume, gnu_kill_inferior) (gnu_mourn_inferior, gnu_create_inferior, gnu_attach, gnu_detach) (gnu_stop, gnu_thread_alive, gnu_xfer_partial) (gnu_find_memory_regions, gnu_pid_to_str): Refactor as methods of gnu_nat_target. (gnu_target): Delete. * gnu-nat.h (gnu_target): Delete. (gnu_nat_target): New class. * i386-gnu-nat.c (gnu_base_target): New. (i386_gnu_nat_target): New class. (the_i386_gnu_nat_target): New. (_initialize_i386gnu_nat): Adjust to C++ification. gdb/testsuite/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * gdb.base/breakpoint-in-ro-region.exp: Adjust to to_resume and to_log_command renames. * gdb.base/sss-bp-on-user-bp-2.exp: Likewise.
2018-05-03 07:37:22 +08:00
linux_target = &the_ppc_linux_nat_target;
* Makefile.in (ALLDEPFILES): Update. (alpha-linux-nat.o, sparc-linux-nat.o): New rules. (amd64-linux-nat.o, arm-linux-nat.o, hppa-linux-nat.o) (i386-linux-nat.o, ia64-linux-nat.o, linux-nat.o, m32r-linux-nat.o) (m68klinux-nat.o, mips-linux-nat.o, ppc-linux-nat.o, s390-nat.o) (sparc64-linux-nat.o): Update dependencies. * alpha-linux-nat.c, sparc-linux-nat.c: New files. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (amd64_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (amd64_linux_child_post_start_inferior): Renamed from child_post_startup_inferior and made static. Call super_post_startup_inferior. (super_post_startup_inferior): New. (_initialize_amd64_linux_nat): Set it. Call linux_target and add_target. * arm-linux-nat.c (arm_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (arm_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (_initialize_arm_linux_nat): Add a prototype. Use linux_target and add_target. * hppa-linux-nat.c (hppa_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (hppa_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (_initialize_hppa_linux_nat): New function. * i386-linux-nat.c (i386_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (i386_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (i386_linux_resume): Renamed from child_resume and made static. (i386_linux_child_post_start_inferior): Renamed from child_post_startup_inferior and made static. Call super_post_startup_inferior. (super_post_startup_inferior): New. (_initialize_i386_linux_nat): New function. * i386-nat.c: Remove LINUX_CHILD_POST_STARTUP_INFERIOR #ifndef. * ia64-linux-nat.c (ia64_linux_xfer_unwind_table): Remove. (super_xfer_partial): New. (ia64_linux_xfer_partial): New function. Use it. (_initialize_ia64_linux_nat): New function. * ia64-tdep.c (getunwind_table): Revert 2005-06-08 change; use target_read_partial and document the problem. * inf-ptrace.c (inf_ptrace_fetch_register): Use CANNOT_FETCH_REGISTER. Fix some comments. (inf_ptrace_store_register): Use CANNOT_STORE_REGISTER. Fix some comments. * linux-nat.c: Include "inf-ptrace.h" and "auxv.h". (linux_ops, super_xfer_partial): New variables. (linux_child_post_startup_inferior): Make static. (child_post_startup_inferior): Delete. (linux_nat_attach, linux_nat_detach, resume_callback) (linux_nat_resume, linux_nat_wait, linux_nat_create_inferior) (linux_nat_mourn_inferior): Use linux_ops instead of deprecated_child_ops. (child_wait): Do not depend on CHILD_WAIT. (linux_nat_xfer_memory): Remove, replace by ... (linux_nat_xfer_partial): ... this. Use linux_ops->to_xfer_partial instead of linux_proc_xfer_memory and child_xfer_memory. (linux_nat_fetch_registers, linux_nat_store_registers) (linux_nat_child_post_startup_inferior): New functions. (init_linux_nat_ops): Use the new functions. (linux_proc_xfer_memory): Remove, replace by ... (linux_proc_xfer_partial): ... this. Make static. (linux_xfer_partial, linux_register_u_offset, linux_target): New functions. (_initialize_linux_nat): Do not modify deprecated_child_ops. * linux-nat.h (linux_proc_xfer_memory): Remove prototype. (struct mem_attrib, struct target_ops): Remove forward declarations. (linux_child_post_startup_inferior): Remove prototype. (linux_target): Add prototype. * linux-thread-db.c (thread_db_xfer_memory): Remove, replace by ... (thread_db_xfer_partial): ... this. (init_thread_db_ops): Set to_xfer_partial instead of deprecated_xfer_memory. * m32r-linux-nat.c (m32r_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (m32r_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (_initialize_m32r_linux_nat): New function. * m68klinux-nat.c (m68k_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (m68k_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (old_fetch_inferior_registers, old_store_inferior_registers): Made static. (_initialize_m68k_linux_nat): Use linux_target and add_target. * mips-linux-nat.c (_initialize_mips_linux_nat): New function. * ppc-linux-nat.c (ppc_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (ppc_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (_initialize_ppc_linux_nat): New function. * s390-nat.c (s390_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (s390_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (_initialize_s390_nat): New function. * sparc64-linux-nat.c (_initialize_sparc64_linux_nat): Use linux_target and add_target. * config/nm-linux.h: Don't include "auxv.h". (struct target_waitstatus, child_wait, CHILD_WAIT) (CHILD_PID_TO_EXEC_FILE, CHILD_INSERT_FORK_CATCHPOINT) (CHILD_INSERT_VFORK_CATCHPOINT, CHILD_INSERT_EXEC_CATCHPOINT) (CHILD_POST_STARTUP_INFERIOR, CHILD_POST_ATTACH, CHILD_FOLLOW_FORK) (DEPRECATED_KILL_INFERIOR, NATIVE_XFER_AUXV): Delete. * config/alpha/alpha-linux.mh (NATDEPFILES): Replace infptrace.o and inftarg.o with inf-ptrace.o and alpha-linux-nat.o. * config/sparc/linux.mh (NATDEPFILES): Replace infptrace.o and inftarg.o with sparc-linux-nat.o. * config/sparc/linux64.mh (NATDEPFILES): Remove infptrace.o and inftarg.o. * config/arm/linux.mh (NATDEPFILES): Replace infptrace.o and inftarg.o with inf-ptrace.o. * config/i386/linux.mh (NATDEPFILES): Likewise. * config/i386/linux64.mh (NATDEPFILES): Likewise. * config/ia64/linux.mh (NATDEPFILES): Likewise. * config/m32r/linux.mh (NATDEPFILES): Likewise. * config/m68k/linux.mh (NATDEPFILES): Likewise. * config/mips/linux.mh (NATDEPFILES): Likewise. * config/pa/linux.mh (NATDEPFILES): Likewise. * config/powerpc/linux.mh (NATDEPFILES): Likewise. * config/powerpc/ppc64-linux.mh (NATDEPFILES): Likewise. * config/s390/s390.mh (NATDEPFILES): Likewise. * config/i386/nm-linux.h (DEPRECATED_CHILD_RESUME): Don't define. (LINUX_CHILD_POST_STARTUP_INFERIOR): Don't define. * config/i386/nm-linux64.h (LINUX_CHILD_POST_STARTUP_INFERIOR): Don't define. * config/ia64/nm-linux.h: Don't include "target.h". (NATIVE_XFER_UNWIND_TABLE, ia64_linux_xfer_unwind_table): Remove. * config/djgpp/fnchange.lst: Add alpha-linux-tdep.c, alpha-linux-nat.c, sparc-linux-tdep.c, and sparc-linux-nat.c.
2005-09-11 02:11:14 +08:00
/* Register the target. */
target factories, target open and multiple instances of targets Currently, to open a target, with "target TARGET_NAME", GDB finds the target_ops instance with "TARGET_NAME" as short name, and then calls its target_ops::open virtual method. In reality, there's no actual target/name lookup, a pointer to the target_ops object was associated with the "target TARGET_NAME" command at add_target time (when GDB is initialized), as the command's context. This creates a chicken and egg situation. Consider the case of wanting to open multiple remote connections. We want to be able to have one remote target_ops instance per connection, but, if we're not connected yet, so we don't yet have an instance to call target->open() on... This patch fixes this by separating out common info about a target_ops to a separate structure (shortname, longname, doc), and changing the add_target routine to take a reference to such an object instead of a pointer to a target_ops, and a pointer to a factory function that is responsible to open an instance of the corresponding target when the user types "target TARGET_NAME". -extern void add_target (struct target_ops *); +extern void add_target (const target_info &info, target_open_ftype *func); I.e. this factory function replaces the target_ops::open virtual method. For static/singleton targets, nothing changes, the target_open_ftype function pushes the global target_ops instance on the target stack. At target_close time, the connection is tor down, but the global target_ops object remains live. However, targets that support being open multiple times will make their target_open_ftype routine allocate a new target_ops instance on the heap [e.g., new remote_target()], and push that on the stack. At target_close time, the new object is destroyed (by the target_ops::close virtual method). Both the core target and the remote targets will support being open multiple times (others could/should too, but those were my stopping point), but not in this patch yet. We need to get rid of more globals first before that'd be useful. Native targets are somewhat special, given find_default_run_target & friends. Those routines also expect to return a target_ops pointer, even before we've open the target. However, we'll never need more than one instance of the native target, so we can assume/require that native targets are global/simpletons, and have the backends register a pointer to the native target_ops. Since all native targets inherit inf_child_target, we can centralize that registration. See add_inf_child_target, get_native_target/set_native_target and find_default_run_target. gdb/ChangeLog: 2018-05-02 Pedro Alves <palves@redhat.com> * aarch64-fbsd-nat.c (_initialize_aarch64_fbsd_nat): Use add_inf_child_target. * aarch64-linux-nat.c (_initialize_aarch64_linux_nat): Use add_inf_child_target. * aix-thread.c (aix_thread_target_info): New. (aix_thread_target) <shortname, longname, doc>: Delete. <info>: New. * alpha-bsd-nat.c (_initialize_alphabsd_nat): Use add_inf_child_target. * alpha-linux-nat.c (_initialize_alpha_linux_nat): Use add_inf_child_target. * amd64-fbsd-nat.c (_initialize_amd64fbsd_nat): Use add_inf_child_target. * amd64-linux-nat.c (_initialize_amd64_linux_nat): Use add_inf_child_target. * amd64-nbsd-nat.c (_initialize_amd64nbsd_nat): Use add_inf_child_target. * amd64-obsd-nat.c (_initialize_amd64obsd_nat): Use add_inf_child_target. * arm-fbsd-nat.c (_initialize_arm_fbsd_nat): Use add_inf_child_target. * arm-linux-nat.c (_initialize_arm_linux_nat): Use add_inf_child_target. * arm-nbsd-nat.c (_initialize_arm_netbsd_nat): Use add_inf_child_target. * bfd-target.c (target_bfd_target_info): New. (target_bfd) <shortname, longname, doc>: Delete. <info>: New. * bsd-kvm.c (bsd_kvm_target_info): New. (bsd_kvm_target) <shortname, longname, doc>: Delete. <info>: New. (bsd_kvm_target::open): Rename to ... (bsd_kvm_target_open): ... this. Adjust. * bsd-uthread.c (bsd_uthread_target_info): New. (bsd_uthread_target) <shortname, longname, doc>: Delete. <info>: New. * corefile.c (core_file_command): Adjust. * corelow.c (core_target_info): New. (core_target) <shortname, longname, doc>: Delete. <info>: New. (core_target::open): Rename to ... (core_target_open): ... this. Adjust. * ctf.c (ctf_target_info): New. (ctf_target) <shortname, longname, doc>: Delete. <info>: New. (ctf_target::open): Rename to ... (ctf_target_open): ... this. (_initialize_ctf): Adjust. * exec.c (exec_target_info): New. (exec_target) <shortname, longname, doc>: Delete. <info>: New. (exec_target::open): Rename to ... (exec_target_open): ... this. * gdbcore.h (core_target_open): Declare. * go32-nat.c (_initialize_go32_nat): Use add_inf_child_target. * hppa-linux-nat.c (_initialize_hppa_linux_nat): Use add_inf_child_target. * hppa-nbsd-nat.c (_initialize_hppanbsd_nat): Use add_inf_child_target. * hppa-obsd-nat.c (_initialize_hppaobsd_nat): Use add_inf_child_target. * i386-darwin-nat.c (_initialize_i386_darwin_nat): Use add_inf_child_target. * i386-fbsd-nat.c (_initialize_i386fbsd_nat): Use add_inf_child_target. * i386-gnu-nat.c (_initialize_i386gnu_nat): Use add_inf_child_target. * i386-linux-nat.c (_initialize_i386_linux_nat): Use add_inf_child_target. * i386-nbsd-nat.c (_initialize_i386nbsd_nat): Use add_inf_child_target. * i386-obsd-nat.c (_initialize_i386obsd_nat): Use add_inf_child_target. * ia64-linux-nat.c (_initialize_ia64_linux_nat): Use add_inf_child_target. * inf-child.c (inf_child_target_info): New. (inf_child_target::info): New. (inf_child_open_target): Remove 'target' parameter. Use get_native_target instead. (inf_child_target::open): Delete. (add_inf_child_target): New. * inf-child.h (inf_child_target) <shortname, longname, doc, open>: Delete. <info>: New. (add_inf_child_target): Declare. (inf_child_open_target): Declare. * linux-thread-db.c (thread_db_target_info): New. (thread_db_target) <shortname, longname, doc>: Delete. <info>: New. * m32r-linux-nat.c (_initialize_m32r_linux_nat): Use add_inf_child_target. * m68k-bsd-nat.c (_initialize_m68kbsd_nat): Use add_inf_child_target. * m68k-linux-nat.c (_initialize_m68k_linux_nat): Use add_inf_child_target. * m88k-bsd-nat.c (_initialize_m88kbsd_nat): Use add_inf_child_target. * make-target-delegates (print_class): Adjust. * mips-fbsd-nat.c (_initialize_mips_fbsd_nat): Use add_inf_child_target. * mips-linux-nat.c (_initialize_mips_linux_nat): Use add_inf_child_target. * mips-nbsd-nat.c (_initialize_mipsnbsd_nat): Use add_inf_child_target. * mips64-obsd-nat.c (_initialize_mips64obsd_nat): Use add_inf_child_target. * nto-procfs.c (nto_native_target_info): New. (nto_procfs_target_native) <shortname, longname, doc>: Delete. <info>: New. (nto_procfs_target_info): New. (nto_procfs_target_procfs) <shortname, longname, doc>: Delete. <info>: New. (init_procfs_targets): Adjust. * ppc-fbsd-nat.c (_initialize_ppcfbsd_nat): Use add_inf_child_target. * ppc-linux-nat.c (_initialize_ppc_linux_nat): Use add_inf_child_target. * ppc-nbsd-nat.c (_initialize_ppcnbsd_nat): Use add_inf_child_target. * ppc-obsd-nat.c (_initialize_ppcobsd_nat): Use add_inf_child_target. * ravenscar-thread.c (ravenscar_target_info): New. (ravenscar_thread_target) <shortname, longname, doc>: Delete. <info>: New. * record-btrace.c (record_btrace_target_info): (record_btrace_target) <shortname, longname, doc>: Delete. <info>: New. (record_btrace_target::open): Rename to ... (record_btrace_target_open): ... this. Adjust. * record-full.c (record_longname, record_doc): New. (record_full_base_target) <shortname, longname, doc>: Delete. <info>: New. (record_full_target_info): New. (record_full_target): <shortname>: Delete. <info>: New. (record_full_core_open_1, record_full_open_1): Update comments. (record_full_base_target::open): Rename to ... (record_full_open): ... this. (cmd_record_full_restore): Update. (_initialize_record_full): Update. * remote-sim.c (remote_sim_target_info): New. (gdbsim_target) <shortname, longname, doc>: Delete. <info>: New. (gdbsim_target::open): Rename to ... (gdbsim_target_open): ... this. (_initialize_remote_sim): Adjust. * remote.c (remote_doc): New. (remote_target_info): New. (remote_target) <shortname, longname, doc>: Delete. <info>: New. (extended_remote_target_info): New. (extended_remote_target) <shortname, longname, doc>: Delete. <info>: New. (remote_target::open_1): Make static. Adjust. * rs6000-nat.c (_initialize_rs6000_nat): Use add_inf_child_target. * s390-linux-nat.c (_initialize_s390_nat): Use add_inf_child_target. * sh-nbsd-nat.c (_initialize_shnbsd_nat): Use add_inf_child_target. * sol-thread.c (thread_db_target_info): New. (sol_thread_target) <shortname, longname, doc>: Delete. <info>: New. * sparc-linux-nat.c (_initialize_sparc_linux_nat): Use add_inf_child_target. * sparc-nbsd-nat.c (_initialize_sparcnbsd_nat): Use add_inf_child_target. * sparc64-fbsd-nat.c (_initialize_sparc64fbsd_nat): Use add_inf_child_target. * sparc64-linux-nat.c (_initialize_sparc64_linux_nat): Use add_inf_child_target. * sparc64-nbsd-nat.c (_initialize_sparc64nbsd_nat): Use add_inf_child_target. * sparc64-obsd-nat.c (_initialize_sparc64obsd_nat): Use add_inf_child_target. * spu-linux-nat.c (_initialize_spu_nat): Use add_inf_child_target. * spu-multiarch.c (spu_multiarch_target_info): New. (spu_multiarch_target) <shortname, longname, doc>: Delete. <info>: New. * target-delegates.c: Regenerate. * target.c: Include <unordered_map>. (target_ops_p): Delete. (DEF_VEC_P(target_ops_p)): Delete. (target_factories): New. (test_target_info): New. (test_target_ops::info): New. (open_target): Adjust to use target_factories. (add_target_with_completer): Rename to ... (add_target): ... this. Change prototype. Register target_info and open callback in target_factories. Register target_info in command context instead of target_ops. (add_target): Delete old implementation. (add_deprecated_target_alias): Change prototype. Adjust. (the_native_target): New. (set_native_target, get_native_target): New. (find_default_run_target): Use the_native_target. (find_attach_target, find_run_target): Simplify. (target_ops::open): Delete. (dummy_target_info): New. (dummy_target::shortname, dummy_target::longname) (dummy_target::doc): Delete. (dummy_target::info): New. (debug_target::shortname, debug_target::longname) (debug_target::doc): Delete. (debug_target::info): New. * target.h (struct target_info): New. (target_ops::~target_ops): Add comment. (target_ops::info): New. (target_ops::shortname, target_ops::longname, target_ops::doc): No longer virtual. Implement in terms of target_info. (set_native_target, get_native_target): Declare. (target_open_ftype): New. (add_target, add_target_with_completer) (add_deprecated_target_alias): Change prototype. (test_target) <shortname, longname, doc>: Delete. <info>: New. * tilegx-linux-nat.c (_initialize_tile_linux_nat): Use add_inf_child_target. * tracefile-tfile.c (tfile_target_info): New. (tfile_target) <shortname, longname, doc>: Delete. <info>: New. (tfile_target::open): Rename to ... (tfile_target_open): ... this. (_initialize_tracefile_tfile): Adjust. * vax-bsd-nat.c (_initialize_vaxbsd_nat): Use add_inf_child_target. * windows-nat.c (_initialize_windows_nat): Use add_inf_child_target. * xtensa-linux-nat.c (_initialize_xtensa_linux_nat): Use add_inf_child_target.
2018-05-03 07:37:32 +08:00
add_inf_child_target (linux_target);
* Makefile.in (ALLDEPFILES): Update. (alpha-linux-nat.o, sparc-linux-nat.o): New rules. (amd64-linux-nat.o, arm-linux-nat.o, hppa-linux-nat.o) (i386-linux-nat.o, ia64-linux-nat.o, linux-nat.o, m32r-linux-nat.o) (m68klinux-nat.o, mips-linux-nat.o, ppc-linux-nat.o, s390-nat.o) (sparc64-linux-nat.o): Update dependencies. * alpha-linux-nat.c, sparc-linux-nat.c: New files. * amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (amd64_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (amd64_linux_child_post_start_inferior): Renamed from child_post_startup_inferior and made static. Call super_post_startup_inferior. (super_post_startup_inferior): New. (_initialize_amd64_linux_nat): Set it. Call linux_target and add_target. * arm-linux-nat.c (arm_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (arm_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (_initialize_arm_linux_nat): Add a prototype. Use linux_target and add_target. * hppa-linux-nat.c (hppa_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (hppa_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (_initialize_hppa_linux_nat): New function. * i386-linux-nat.c (i386_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (i386_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (i386_linux_resume): Renamed from child_resume and made static. (i386_linux_child_post_start_inferior): Renamed from child_post_startup_inferior and made static. Call super_post_startup_inferior. (super_post_startup_inferior): New. (_initialize_i386_linux_nat): New function. * i386-nat.c: Remove LINUX_CHILD_POST_STARTUP_INFERIOR #ifndef. * ia64-linux-nat.c (ia64_linux_xfer_unwind_table): Remove. (super_xfer_partial): New. (ia64_linux_xfer_partial): New function. Use it. (_initialize_ia64_linux_nat): New function. * ia64-tdep.c (getunwind_table): Revert 2005-06-08 change; use target_read_partial and document the problem. * inf-ptrace.c (inf_ptrace_fetch_register): Use CANNOT_FETCH_REGISTER. Fix some comments. (inf_ptrace_store_register): Use CANNOT_STORE_REGISTER. Fix some comments. * linux-nat.c: Include "inf-ptrace.h" and "auxv.h". (linux_ops, super_xfer_partial): New variables. (linux_child_post_startup_inferior): Make static. (child_post_startup_inferior): Delete. (linux_nat_attach, linux_nat_detach, resume_callback) (linux_nat_resume, linux_nat_wait, linux_nat_create_inferior) (linux_nat_mourn_inferior): Use linux_ops instead of deprecated_child_ops. (child_wait): Do not depend on CHILD_WAIT. (linux_nat_xfer_memory): Remove, replace by ... (linux_nat_xfer_partial): ... this. Use linux_ops->to_xfer_partial instead of linux_proc_xfer_memory and child_xfer_memory. (linux_nat_fetch_registers, linux_nat_store_registers) (linux_nat_child_post_startup_inferior): New functions. (init_linux_nat_ops): Use the new functions. (linux_proc_xfer_memory): Remove, replace by ... (linux_proc_xfer_partial): ... this. Make static. (linux_xfer_partial, linux_register_u_offset, linux_target): New functions. (_initialize_linux_nat): Do not modify deprecated_child_ops. * linux-nat.h (linux_proc_xfer_memory): Remove prototype. (struct mem_attrib, struct target_ops): Remove forward declarations. (linux_child_post_startup_inferior): Remove prototype. (linux_target): Add prototype. * linux-thread-db.c (thread_db_xfer_memory): Remove, replace by ... (thread_db_xfer_partial): ... this. (init_thread_db_ops): Set to_xfer_partial instead of deprecated_xfer_memory. * m32r-linux-nat.c (m32r_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (m32r_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (_initialize_m32r_linux_nat): New function. * m68klinux-nat.c (m68k_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (m68k_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (old_fetch_inferior_registers, old_store_inferior_registers): Made static. (_initialize_m68k_linux_nat): Use linux_target and add_target. * mips-linux-nat.c (_initialize_mips_linux_nat): New function. * ppc-linux-nat.c (ppc_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (ppc_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (_initialize_ppc_linux_nat): New function. * s390-nat.c (s390_linux_fetch_inferior_registers): Renamed from fetch_inferior_registers and made static. (s390_linux_store_inferior_registers): Renamed from store_inferior_registers and made static. (_initialize_s390_nat): New function. * sparc64-linux-nat.c (_initialize_sparc64_linux_nat): Use linux_target and add_target. * config/nm-linux.h: Don't include "auxv.h". (struct target_waitstatus, child_wait, CHILD_WAIT) (CHILD_PID_TO_EXEC_FILE, CHILD_INSERT_FORK_CATCHPOINT) (CHILD_INSERT_VFORK_CATCHPOINT, CHILD_INSERT_EXEC_CATCHPOINT) (CHILD_POST_STARTUP_INFERIOR, CHILD_POST_ATTACH, CHILD_FOLLOW_FORK) (DEPRECATED_KILL_INFERIOR, NATIVE_XFER_AUXV): Delete. * config/alpha/alpha-linux.mh (NATDEPFILES): Replace infptrace.o and inftarg.o with inf-ptrace.o and alpha-linux-nat.o. * config/sparc/linux.mh (NATDEPFILES): Replace infptrace.o and inftarg.o with sparc-linux-nat.o. * config/sparc/linux64.mh (NATDEPFILES): Remove infptrace.o and inftarg.o. * config/arm/linux.mh (NATDEPFILES): Replace infptrace.o and inftarg.o with inf-ptrace.o. * config/i386/linux.mh (NATDEPFILES): Likewise. * config/i386/linux64.mh (NATDEPFILES): Likewise. * config/ia64/linux.mh (NATDEPFILES): Likewise. * config/m32r/linux.mh (NATDEPFILES): Likewise. * config/m68k/linux.mh (NATDEPFILES): Likewise. * config/mips/linux.mh (NATDEPFILES): Likewise. * config/pa/linux.mh (NATDEPFILES): Likewise. * config/powerpc/linux.mh (NATDEPFILES): Likewise. * config/powerpc/ppc64-linux.mh (NATDEPFILES): Likewise. * config/s390/s390.mh (NATDEPFILES): Likewise. * config/i386/nm-linux.h (DEPRECATED_CHILD_RESUME): Don't define. (LINUX_CHILD_POST_STARTUP_INFERIOR): Don't define. * config/i386/nm-linux64.h (LINUX_CHILD_POST_STARTUP_INFERIOR): Don't define. * config/ia64/nm-linux.h: Don't include "target.h". (NATIVE_XFER_UNWIND_TABLE, ia64_linux_xfer_unwind_table): Remove. * config/djgpp/fnchange.lst: Add alpha-linux-tdep.c, alpha-linux-nat.c, sparc-linux-tdep.c, and sparc-linux-nat.c.
2005-09-11 02:11:14 +08:00
}