/* PPC GNU/Linux native support.

   Copyright (C) 1988-2024 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 "extract-store-integer.h"
#include "frame.h"
#include "inferior.h"
#include "gdbthread.h"
#include "gdbcore.h"
#include "regcache.h"
#include "regset.h"
#include "target.h"
#include "linux-nat.h"
#include <sys/types.h>
#include <signal.h>
#include <sys/user.h>
#include <sys/ioctl.h>
#include <sys/uio.h>
#include "gdbsupport/gdb_wait.h"
#include <fcntl.h>
#include <sys/procfs.h>
#include "nat/gdb_ptrace.h"
#include "nat/linux-ptrace.h"
#include "inf-ptrace.h"
#include <algorithm>
#include <unordered_map>
#include <list>

/* Prototypes for supply_gregset etc.  */
#include "gregset.h"
#include "ppc-tdep.h"
#include "ppc-linux-tdep.h"

/* Required when using the AUXV.  */
#include "elf/common.h"
#include "auxv.h"

#include "arch/ppc-linux-common.h"
#include "arch/ppc-linux-tdesc.h"
#include "nat/ppc-linux.h"
#include "linux-tdep.h"
#include "expop.h"

/* 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.  */
#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.  */
#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.  */
	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.  */
	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 */

/* Feature defined on Linux kernel v5.1: Second watchpoint support.  */
#ifndef PPC_DEBUG_FEATURE_DATA_BP_ARCH_31
#define PPC_DEBUG_FEATURE_DATA_BP_ARCH_31 0x20
#endif /* PPC_DEBUG_FEATURE_DATA_BP_ARCH_31 */

/* 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): */

/*
Big-Endian:
   |.|.|.|.|.....|.|.|.|.||.|.|.|x||.|
   <------->     <-------><-------><->
     VR0           VR31     VSCR    VRSAVE
Little-Endian:
   |.|.|.|.|.....|.|.|.|.||X|.|.|.||.|
   <------->     <-------><-------><->
     VR0           VR31     VSCR    VRSAVE
*/

typedef char gdb_vrregset_t[PPC_LINUX_SIZEOF_VRREGSET];

/* 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
   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,
   '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;
};

/* 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;

/* 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 precondition.  */

  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)
	>= 0)
      {
	/* 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) >= 0)
	  {
	    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 which interface is available.  */

  enum debug_reg_interface
    {
     UNAVAILABLE,
     HWDEBUG,
     DEBUGREG
    };

  /* The interface option.  Initialized if has_value () returns true.  */
  std::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.  */
  std::optional<long> requested_wp_val;
};

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;

  bool watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int) override;

  bool can_accel_watchpoint_condition (CORE_ADDR, int, int, struct expression *)
    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 (const gdb_byte **readptr,
		  const gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
    override;

  /* Override linux_nat_target low methods.  */
  bool low_stopped_by_watchpoint () override;

  bool low_stopped_data_address (CORE_ADDR *) override;

  void low_new_thread (struct lwp_info *lp) override;

  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;
};

static ppc_linux_nat_target the_ppc_linux_nat_target;

/* 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 */

static int
ppc_register_u_addr (struct gdbarch *gdbarch, int regno)
{
  int u_addr = -1;
  ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_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.  */
  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;
  if (regno == PPC_ORIG_R3_REGNUM)
    u_addr = PT_ORIG_R3 * wordsize;
  if (regno == PPC_TRAP_REGNUM)
    u_addr = PT_TRAP * wordsize;
  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
	 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;
      /* 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;
}

/* 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
fetch_vsx_registers (struct regcache *regcache, int tid, int regno)
{
  int ret;
  gdb_vsxregset_t regs;
  const struct regset *vsxregset = ppc_linux_vsxregset ();

  ret = ptrace (PTRACE_GETVSXREGS, tid, 0, &regs);
  if (ret < 0)
    {
      if (errno == EIO)
	{
	  have_ptrace_getsetvsxregs = 0;
	  return;
	}
      perror_with_name (_("Unable to fetch VSX registers"));
    }

  vsxregset->supply_regset (vsxregset, regcache, regno, &regs,
			    PPC_LINUX_SIZEOF_VSXREGSET);
}

/* 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
fetch_altivec_registers (struct regcache *regcache, int tid,
			 int regno)
{
  int ret;
  gdb_vrregset_t regs;
  struct gdbarch *gdbarch = regcache->arch ();
  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;
	}
      perror_with_name (_("Unable to fetch AltiVec registers"));
    }

  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.  */
	    perror_with_name (_("Unable to fetch SPE registers"));
	}
    }

  memset (evrregset, 0, sizeof (*evrregset));
}

/* 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
fetch_spe_register (struct regcache *regcache, int tid, int regno)
{
  struct gdbarch *gdbarch = regcache->arch ();
  ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
  struct gdb_evrregset_t evrregs;

  gdb_assert (sizeof (evrregs.evr[0])
	      == register_size (gdbarch, tdep->ppc_ev0_upper_regnum));
  gdb_assert (sizeof (evrregs.acc)
	      == register_size (gdbarch, tdep->ppc_acc_regnum));
  gdb_assert (sizeof (evrregs.spefscr)
	      == register_size (gdbarch, tdep->ppc_spefscr_regnum));

  get_spe_registers (tid, &evrregs);

  if (regno == -1)
    {
      int i;

      for (i = 0; i < ppc_num_gprs; i++)
	regcache->raw_supply (tdep->ppc_ev0_upper_regnum + i, &evrregs.evr[i]);
    }
  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]);

  if (regno == -1
      || regno == tdep->ppc_acc_regnum)
    regcache->raw_supply (tdep->ppc_acc_regnum, &evrregs.acc);

  if (regno == -1
      || regno == tdep->ppc_spefscr_regnum)
    regcache->raw_supply (tdep->ppc_spefscr_regnum, &evrregs.spefscr);
}

/* 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
fetch_register (struct regcache *regcache, int tid, int regno)
{
  struct gdbarch *gdbarch = regcache->arch ();
  ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_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];

  if (altivec_register_p (gdbarch, regno))
    {
      /* If this is the first time through, or if it is not the first
	 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)
       {
	 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))
    {
      if (have_ptrace_getsetvsxregs)
	{
	  fetch_vsx_registers (regcache, tid, regno);
	  return;
	}
    }
  else if (spe_register_p (gdbarch, regno))
    {
      fetch_spe_register (regcache, tid, regno);
      return;
    }
  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;
    }
  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;
    }
  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;
    }
  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)
    {
      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;
       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).  */
  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);
    }
  else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
    {
      /* Big-endian values are found at the right end of the bytes
	 transferred.  */
      size_t padding = (bytes_transferred - register_size (gdbarch, regno));
      regcache->raw_supply (regno, buf + padding);
    }
  else 
    internal_error (_("fetch_register: unexpected byte order: %d"),
		    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)
{
  struct gdbarch *gdbarch = regcache->arch ();
  ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_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)
{
  struct gdbarch *gdbarch = regcache->arch ();
  ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_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 
fetch_ppc_registers (struct regcache *regcache, int tid)
{
  struct gdbarch *gdbarch = regcache->arch ();
  ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);

  fetch_gp_regs (regcache, tid);
  if (tdep->ppc_fp0_regnum >= 0)
    fetch_fp_regs (regcache, tid);
  fetch_register (regcache, tid, gdbarch_pc_regnum (gdbarch));
  if (tdep->ppc_ps_regnum != -1)
    fetch_register (regcache, tid, tdep->ppc_ps_regnum);
  if (tdep->ppc_cr_regnum != -1)
    fetch_register (regcache, tid, tdep->ppc_cr_regnum);
  if (tdep->ppc_lr_regnum != -1)
    fetch_register (regcache, tid, tdep->ppc_lr_regnum);
  if (tdep->ppc_ctr_regnum != -1)
    fetch_register (regcache, tid, tdep->ppc_ctr_regnum);
  if (tdep->ppc_xer_regnum != -1)
    fetch_register (regcache, tid, tdep->ppc_xer_regnum);
  if (tdep->ppc_mq_regnum != -1)
    fetch_register (regcache, tid, tdep->ppc_mq_regnum);
  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)
    fetch_register (regcache, tid, tdep->ppc_fpscr_regnum);
  if (have_ptrace_getvrregs)
    if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1)
      fetch_altivec_registers (regcache, tid, -1);
  if (have_ptrace_getsetvsxregs)
    if (tdep->ppc_vsr0_upper_regnum != -1)
      fetch_vsx_registers (regcache, tid, -1);
  if (tdep->ppc_ev0_upper_regnum >= 0)
    fetch_spe_register (regcache, tid, -1);
  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);
  if (tdep->ppc_tar_regnum != -1)
    fetch_regset (regcache, tid, NT_PPC_TAR,
		  PPC_LINUX_SIZEOF_TARREGSET,
		  &ppc32_linux_tarregset);
  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);
  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.  */
void
ppc_linux_nat_target::fetch_registers (struct regcache *regcache, int regno)
{
  pid_t tid = get_ptrace_pid (regcache->ptid ());

  if (regno == -1)
    fetch_ppc_registers (regcache, tid);
  else 
    fetch_register (regcache, tid, regno);
}

static void
store_vsx_registers (const struct regcache *regcache, int tid, int regno)
{
  int ret;
  gdb_vsxregset_t regs;
  const struct regset *vsxregset = ppc_linux_vsxregset ();

  ret = ptrace (PTRACE_GETVSXREGS, tid, 0, &regs);
  if (ret < 0)
    {
      if (errno == EIO)
	{
	  have_ptrace_getsetvsxregs = 0;
	  return;
	}
      perror_with_name (_("Unable to fetch VSX registers"));
    }

  vsxregset->collect_regset (vsxregset, regcache, regno, &regs,
			     PPC_LINUX_SIZEOF_VSXREGSET);

  ret = ptrace (PTRACE_SETVSXREGS, tid, 0, &regs);
  if (ret < 0)
    perror_with_name (_("Unable to store VSX registers"));
}

static void
store_altivec_registers (const struct regcache *regcache, int tid,
			 int regno)
{
  int ret;
  gdb_vrregset_t regs;
  struct gdbarch *gdbarch = regcache->arch ();
  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;
	}
      perror_with_name (_("Unable to fetch AltiVec registers"));
    }

  vrregset->collect_regset (vrregset, regcache, regno, &regs,
			    PPC_LINUX_SIZEOF_VRREGSET);

  ret = ptrace (PTRACE_SETVRREGS, tid, 0, &regs);
  if (ret < 0)
    perror_with_name (_("Unable to store AltiVec registers"));
}

/* 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.  */
	    perror_with_name (_("Unable to set SPE registers"));
	}
    }
}

/* 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
store_spe_register (const struct regcache *regcache, int tid, int regno)
{
  struct gdbarch *gdbarch = regcache->arch ();
  ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
  struct gdb_evrregset_t evrregs;

  gdb_assert (sizeof (evrregs.evr[0])
	      == register_size (gdbarch, tdep->ppc_ev0_upper_regnum));
  gdb_assert (sizeof (evrregs.acc)
	      == register_size (gdbarch, tdep->ppc_acc_regnum));
  gdb_assert (sizeof (evrregs.spefscr)
	      == register_size (gdbarch, tdep->ppc_spefscr_regnum));

  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)
    {
      int i;

      for (i = 0; i < ppc_num_gprs; i++)
	regcache->raw_collect (tdep->ppc_ev0_upper_regnum + i,
			       &evrregs.evr[i]);
    }
  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]);

  if (regno == -1
      || regno == tdep->ppc_acc_regnum)
    regcache->raw_collect (tdep->ppc_acc_regnum,
			   &evrregs.acc);

  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
store_register (const struct regcache *regcache, int tid, int regno)
{
  struct gdbarch *gdbarch = regcache->arch ();
  ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_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];

  if (altivec_register_p (gdbarch, regno))
    {
      store_altivec_registers (regcache, tid, regno);
      return;
    }
  else if (vsx_register_p (gdbarch, regno))
    {
      store_vsx_registers (regcache, tid, regno);
      return;
    }
  else if (spe_register_p (gdbarch, regno))
    {
      store_spe_register (regcache, tid, regno);
      return;
    }
  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;
    }
  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;
    }
  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;
    }
  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);
  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);
    }
  else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
    {
      /* Big-endian values sit at the right end of the buffer.  */
      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 
	  && (regno == tdep->ppc_fpscr_regnum
	      || regno == PPC_ORIG_R3_REGNUM
	      || regno == PPC_TRAP_REGNUM))
	{
	  /* 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)
{
  struct gdbarch *gdbarch = regcache->arch ();
  ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_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".  */
  for (i = 0; i < ppc_num_gprs; i++)
    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)
{
  struct gdbarch *gdbarch = regcache->arch ();
  ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_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)
{
  struct gdbarch *gdbarch = regcache->arch ();
  ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
 
  store_gp_regs (regcache, tid, -1);
  if (tdep->ppc_fp0_regnum >= 0)
    store_fp_regs (regcache, tid, -1);
  store_register (regcache, tid, gdbarch_pc_regnum (gdbarch));
  if (tdep->ppc_ps_regnum != -1)
    store_register (regcache, tid, tdep->ppc_ps_regnum);
  if (tdep->ppc_cr_regnum != -1)
    store_register (regcache, tid, tdep->ppc_cr_regnum);
  if (tdep->ppc_lr_regnum != -1)
    store_register (regcache, tid, tdep->ppc_lr_regnum);
  if (tdep->ppc_ctr_regnum != -1)
    store_register (regcache, tid, tdep->ppc_ctr_regnum);
  if (tdep->ppc_xer_regnum != -1)
    store_register (regcache, tid, tdep->ppc_xer_regnum);
  if (tdep->ppc_mq_regnum != -1)
    store_register (regcache, tid, tdep->ppc_mq_regnum);
  if (tdep->ppc_fpscr_regnum != -1)
    store_register (regcache, tid, tdep->ppc_fpscr_regnum);
  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)
      store_altivec_registers (regcache, tid, -1);
  if (have_ptrace_getsetvsxregs)
    if (tdep->ppc_vsr0_upper_regnum != -1)
      store_vsx_registers (regcache, tid, -1);
  if (tdep->ppc_ev0_upper_regnum >= 0)
    store_spe_register (regcache, tid, -1);
  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);
  if (tdep->ppc_tar_regnum != -1)
    store_regset (regcache, tid, -1, NT_PPC_TAR,
		  PPC_LINUX_SIZEOF_TARREGSET,
		  &ppc32_linux_tarregset);

  if (tdep->ppc_mmcr0_regnum != -1)
    store_regset (regcache, tid, -1, NT_PPC_PMU,
		  PPC_LINUX_SIZEOF_PMUREGSET,
		  &ppc32_linux_pmuregset);

  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 (const gdb_byte **readptr,
				  const gdb_byte *endptr, CORE_ADDR *typep,
				  CORE_ADDR *valp)
{
  gdb_assert (inferior_ptid != null_ptid);

  int tid = inferior_ptid.lwp ();
  if (tid == 0)
    tid = inferior_ptid.pid ();

  int sizeof_auxv_field = ppc_linux_target_wordsize (tid);

  bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
  const 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 ()
{
  if (inferior_ptid == null_ptid)
    return this->beneath ()->read_description ();

  int 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 ();
  CORE_ADDR hwcap2 = linux_get_hwcap2 ();

  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);
}

/* 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.  */

int
ppc_linux_nat_target::can_use_hw_breakpoint (enum bptype type, int cnt,
					     int ot)
{
  int total_hw_wp, total_hw_bp;

  m_dreg_interface.detect (inferior_ptid);

  if (m_dreg_interface.unavailable_p ())
    return 0;

  if (m_dreg_interface.hwdebug_p ())
    {
      /* When PowerPC HWDEBUG ptrace interface is available, the number of
	 available hardware watchpoints and breakpoints is stored at the
	 hwdebug_info struct.  */
      total_hw_bp = m_dreg_interface.hwdebug_info ().num_instruction_bps;
      total_hw_wp = m_dreg_interface.hwdebug_info ().num_data_bps;
    }
  else
    {
      gdb_assert (m_dreg_interface.debugreg_p ());

      /* With the DEBUGREG ptrace interface, we should consider having 1
	 hardware watchpoint and no hardware breakpoints.  */
      total_hw_bp = 0;
      total_hw_wp = 1;
    }

  if (type == bp_hardware_watchpoint || type == bp_read_watchpoint
      || type == bp_access_watchpoint || type == bp_watchpoint)
    {
      if (total_hw_wp == 0)
	return 0;
      else if (cnt + ot > total_hw_wp)
	return -1;
      else
	return 1;
    }
  else if (type == bp_hardware_breakpoint)
    {
      if (total_hw_bp == 0)
	return 0;
      else if (cnt > total_hw_bp)
	return -1;
      else
	return 1;
    }

  return 0;
}

/* Returns 1 if we can watch LEN bytes at address ADDR, 0 otherwise.  */

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;

  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.  */
  if (m_dreg_interface.hwdebug_p ())
    {
      const struct ppc_debug_info &hwdebug_info = (m_dreg_interface
						   .hwdebug_info ());
      int region_size = hwdebug_info.data_bp_alignment;
      int region_align = region_size;

      /* 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.  */
      if (len > 1
	  && hwdebug_info.features & PPC_DEBUG_FEATURE_DATA_BP_RANGE
	  && (linux_get_hwcap () & PPC_FEATURE_BOOKE))
	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.  */
	  region_size = 512;
	  /* DAWR interface allows to watch up to 512 byte wide ranges which
	     can't cross a 512 byte boundary on machines that don't have a
	     second DAWR (P9 or less).  */
	  if (!(hwdebug_info.features & PPC_DEBUG_FEATURE_DATA_BP_ARCH_31))
	    region_align = 512;
	}
      /* Server processors provide one hardware watchpoint and addr+len should
	 fall in the watchable region provided by the ptrace interface.  */
      if (region_align
	  && (addr + len > (addr & ~(region_align - 1)) + region_size))
	return 0;
    }
  /* 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
     passed in the old ptrace interface.  */
  else
    {
      gdb_assert (m_dreg_interface.debugreg_p ());

      if (((linux_get_hwcap () & PPC_FEATURE_BOOKE)
	   && (addr + len) > (addr & ~3) + 4)
	  || (addr + len) > (addr & ~7) + 8)
	return 0;
    }

  return 1;
}

/* This function compares two ppc_hw_breakpoint structs
   field-by-field.  */

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);
}

/* Return the number of registers needed for a ranged breakpoint.  */

int
ppc_linux_nat_target::ranged_break_num_registers ()
{
  m_dreg_interface.detect (inferior_ptid);

  return ((m_dreg_interface.hwdebug_p ()
	   && (m_dreg_interface.hwdebug_info ().features
	       & PPC_DEBUG_FEATURE_INSN_BP_RANGE))?
	  2 : -1);
}

/* 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.  */

int
ppc_linux_nat_target::insert_hw_breakpoint (struct gdbarch *gdbarch,
					    struct bp_target_info *bp_tgt)
{
  struct ppc_hw_breakpoint p;

  m_dreg_interface.detect (inferior_ptid);

  if (!m_dreg_interface.hwdebug_p ())
    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 = bp_tgt->reqstd_address);
  p.condition_value = 0;

  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;
    }

  register_hw_breakpoint (inferior_ptid.pid (), p);

  return 0;
}

/* 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.  */

int
ppc_linux_nat_target::remove_hw_breakpoint (struct gdbarch *gdbarch,
					    struct bp_target_info *bp_tgt)
{
  struct ppc_hw_breakpoint p;

  m_dreg_interface.detect (inferior_ptid);

  if (!m_dreg_interface.hwdebug_p ())
    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;
  p.condition_value = 0;

  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;
    }

  clear_hw_breakpoint (inferior_ptid.pid (), p);

  return 0;
}

/* 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)
{
  int t;

  if (type == hw_read)
    t = PPC_BREAKPOINT_TRIGGER_READ;
  else if (type == hw_write)
    t = PPC_BREAKPOINT_TRIGGER_WRITE;
  else
    t = PPC_BREAKPOINT_TRIGGER_READ | PPC_BREAKPOINT_TRIGGER_WRITE;

  return t;
}

/* 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.  */

int
ppc_linux_nat_target::insert_mask_watchpoint (CORE_ADDR addr,  CORE_ADDR mask,
					      target_hw_bp_type rw)
{
  struct ppc_hw_breakpoint p;

  gdb_assert (m_dreg_interface.hwdebug_p ());

  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;

  register_hw_breakpoint (inferior_ptid.pid (), p);

  return 0;
}

/* 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.  */

int
ppc_linux_nat_target::remove_mask_watchpoint (CORE_ADDR addr, CORE_ADDR mask,
					      target_hw_bp_type rw)
{
  struct ppc_hw_breakpoint p;

  gdb_assert (m_dreg_interface.hwdebug_p ());

  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;

  clear_hw_breakpoint (inferior_ptid.pid (), p);

  return 0;
}

/* 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)
{
  m_dreg_interface.detect (inferior_ptid);

  if (!m_dreg_interface.hwdebug_p ())
    return false;

  int cnt = m_dreg_interface.hwdebug_info ().num_condition_regs;

  if (cnt == 0)
    return false;

  auto process_it = m_process_info.find (inferior_ptid.pid ());

  /* No breakpoints, watchpoints, tracepoints, or catchpoints 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;
}

/* 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.  */

void
ppc_linux_nat_target::calculate_dvc (CORE_ADDR addr, int len,
				     CORE_ADDR data_value,
				     uint32_t *condition_mode,
				     uint64_t *condition_value)
{
  const struct ppc_debug_info &hwdebug_info = (m_dreg_interface.
					       hwdebug_info ());

  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;
  addr_end_data = addr + len;
  addr_end_dvc = (addr - align_offset
		  + hwdebug_info.sizeof_condition);
  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);

  /* 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).  */

int
ppc_linux_nat_target::num_memory_accesses (const std::vector<value_ref_ptr>
					   &chain)
{
  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)
    {
      struct value *v = iter.get ();

      /* Constants and values from the history are fine.  */
      if (v->lval () == not_lval || !v->deprecated_modifiable ())
	continue;
      else if (v->lval () == 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 (!v->lazy ())
	    found_memory_cnt++;
	}
      /* Other kinds of values are not fine.  */
      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.  */

int
ppc_linux_nat_target::check_condition (CORE_ADDR watch_addr,
				       struct expression *cond,
				       CORE_ADDR *data_value, int *len)
{
  int num_accesses_left, num_accesses_right;
  struct value *left_val, *right_val;
  std::vector<value_ref_ptr> left_chain, right_chain;

  expr::equal_operation *eqop
    = dynamic_cast<expr::equal_operation *> (cond->op.get ());
  if (eqop == nullptr)
    return 0;
  expr::operation *lhs = eqop->get_lhs ();
  expr::operation *rhs = eqop->get_rhs ();

  fetch_subexp_value (cond, lhs, &left_val, NULL, &left_chain, false);
  num_accesses_left = num_memory_accesses (left_chain);

  if (left_val == NULL || num_accesses_left < 0)
    return 0;

  fetch_subexp_value (cond, rhs, &right_val, NULL, &right_chain, false);
  num_accesses_right = num_memory_accesses (right_chain);

  if (right_val == NULL || num_accesses_right < 0)
    return 0;

  if (num_accesses_left == 1 && num_accesses_right == 0
      && left_val->lval () == lval_memory
      && left_val->address () == 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 = check_typedef (left_val->type ())->length ();
    }
  else if (num_accesses_left == 0 && num_accesses_right == 1
	   && right_val->lval () == lval_memory
	   && right_val->address () == 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 = check_typedef (right_val->type ())->length ();
    }
  else
    return 0;

  return 1;
}

/* Return true if the target is capable of using hardware to evaluate the
   condition expression, thus only triggering the watchpoint when it is
   true.  */

bool
ppc_linux_nat_target::can_accel_watchpoint_condition (CORE_ADDR addr,
						      int len, int rw,
						      struct expression *cond)
{
  CORE_ADDR data_value;

  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));
}

/* 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.  */

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)
{
  const struct ppc_debug_info &hwdebug_info = (m_dreg_interface
					       .hwdebug_info ());

  if (len == 1
      || !(hwdebug_info.features & PPC_DEBUG_FEATURE_DATA_BP_RANGE))
    {
      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))
	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);
  p->addr = (uint64_t) addr;
}

/* 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.  */

int
ppc_linux_nat_target::insert_watchpoint (CORE_ADDR addr, int len,
					 enum target_hw_bp_type type,
					 struct expression *cond)
{
  m_dreg_interface.detect (inferior_ptid);

  if (m_dreg_interface.unavailable_p ())
    return -1;

  if (m_dreg_interface.hwdebug_p ())
    {
      struct ppc_hw_breakpoint p;

      create_watchpoint_request (&p, addr, len, type, cond, 1);

      register_hw_breakpoint (inferior_ptid.pid (), p);
    }
  else
    {
      gdb_assert (m_dreg_interface.debugreg_p ());

      long wp_value;
      long read_mode, write_mode;

      if (linux_get_hwcap () & PPC_FEATURE_BOOKE)
	{
	  /* PowerPC 440 requires only the read/write flags to be passed
	     to the kernel.  */
	  read_mode = 1;
	  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;
	  write_mode = 6;
	}

      wp_value = addr & ~(read_mode | write_mode);
      switch (type)
	{
	  case hw_read:
	    /* Set read and translate bits.  */
	    wp_value |= read_mode;
	    break;
	  case hw_write:
	    /* Set write and translate bits.  */
	    wp_value |= write_mode;
	    break;
	  case hw_access:
	    /* Set read, write and translate bits.  */
	    wp_value |= read_mode | write_mode;
	    break;
	}

      register_wp (inferior_ptid.pid (), wp_value);
    }

  return 0;
}

/* 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.  */

int
ppc_linux_nat_target::remove_watchpoint (CORE_ADDR addr, int len,
					 enum target_hw_bp_type type,
					 struct expression *cond)
{
  gdb_assert (!m_dreg_interface.unavailable_p ());

  if (m_dreg_interface.hwdebug_p ())
    {
      struct ppc_hw_breakpoint p;

      create_watchpoint_request (&p, addr, len, type, cond, 0);

      clear_hw_breakpoint (inferior_ptid.pid (), p);
    }
  else
    {
      gdb_assert (m_dreg_interface.debugreg_p ());

      clear_wp (inferior_ptid.pid ());
    }

  return 0;
}

/* 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.  */

void
ppc_linux_nat_target::low_forget_process (pid_t pid)
{
  if ((!m_dreg_interface.detected_p ())
      || (m_dreg_interface.unavailable_p ()))
    return;

  ptid_t pid_ptid (pid, 0, 0);

  m_process_info.erase (pid);

  if (m_dreg_interface.hwdebug_p ())
    {
      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++;
	}
    }
}

/* Copy the per-process state associated with the pid of PARENT to the
   state of CHILD_PID.  GDB expects that a forked process will have the
   same hardware breakpoints and watchpoints as the parent.

   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.

   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.

   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.  */

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);
    }
}

/* 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)
{
  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);

  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)
    return;

  gdb_assert (lp->ptid.lwp_p ());

  auto process_it = m_process_info.find (lp->ptid.pid ());

  if (m_dreg_interface.hwdebug_p ())
    {
      /* 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 ())
	{
	  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) < 0)
		if (errno != ENOENT)
		  perror_with_name (_("Error deleting hardware "
				      "breakpoint or watchpoint"));

	      /* We erase the entries one at a time after successfully
		 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);
	    }
	}
    }
  else
    {
      gdb_assert (m_dreg_interface.debugreg_p ());

      /* Passing 0 to PTRACE_SET_DEBUGREG will clear the watchpoint.  We
	 always clear the watchpoint instead of just overwriting it, in
	 case there is a request for a new watchpoint, because on some
	 older kernel versions and configurations simply overwriting the
	 watchpoint after it was hit would not re-enable it.  */
      if (ptrace (PTRACE_SET_DEBUGREG, lp->ptid.lwp (), 0, 0) < 0)
	perror_with_name (_("Error clearing hardware watchpoint"));

      /* GDB requested a watchpoint to be installed.  */
      if (process_it != m_process_info.end ()
	  && process_it->second.requested_wp_val.has_value ())
	{
	  long wp = *(process_it->second.requested_wp_val);

	  if (ptrace (PTRACE_SET_DEBUGREG, lp->ptid.lwp (), 0, wp) < 0)
	    perror_with_name (_("Error setting hardware watchpoint"));
	}
    }

  lp_arch_info->debug_regs_stale = false;
}

/* 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.  */

bool
ppc_linux_nat_target::low_stopped_data_address (CORE_ADDR *addr_p)
{
  siginfo_t siginfo;

  if (!linux_nat_get_siginfo (inferior_ptid, &siginfo))
    return false;

  if (siginfo.si_signo != SIGTRAP
      || (siginfo.si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */)
    return false;

  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 ())
    {
      /* 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;

      auto installed_it = m_installed_hw_bps.find (inferior_ptid);

      /* 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;
    }

  *addr_p = (CORE_ADDR) (uintptr_t) siginfo.si_addr;
  return true;
}

/* Return true if INFERIOR_PTID is known to have been stopped by a
   hardware watchpoint, false otherwise.  */

bool
ppc_linux_nat_target::low_stopped_by_watchpoint ()
{
  CORE_ADDR addr;
  return low_stopped_data_address (&addr);
}

bool
ppc_linux_nat_target::watchpoint_addr_within_range (CORE_ADDR addr,
						    CORE_ADDR start,
						    int length)
{
  gdb_assert (!m_dreg_interface.unavailable_p ());

  int mask;

  if (m_dreg_interface.hwdebug_p ()
      && (linux_get_hwcap () & PPC_FEATURE_BOOKE))
    return start <= addr && start + length >= addr;
  else if (linux_get_hwcap () & 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;
}

/* Return the number of registers needed for a masked hardware watchpoint.  */

int
ppc_linux_nat_target::masked_watch_num_registers (CORE_ADDR addr,
						  CORE_ADDR mask)
{
  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)
    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;
}

/* 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);
}

void _initialize_ppc_linux_nat ();
void
_initialize_ppc_linux_nat ()
{
  linux_target = &the_ppc_linux_nat_target;

  /* Register the target.  */
  add_inf_child_target (linux_target);
}
