/* PPC GNU/Linux native support.

   Copyright (C) 1988-2020 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "frame.h"
#include "inferior.h"
#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"

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

/* The version of the PowerPC HWDEBUG kernel interface that we will use, if
   available.  */
#define PPC_DEBUG_CURRENT_VERSION 1

/* Similarly for the general-purpose (gp0 -- gp31)
   and floating-point registers (fp0 -- fp31).  */
#ifndef PTRACE_GETREGS
#define PTRACE_GETREGS 12
#endif
#ifndef PTRACE_SETREGS
#define PTRACE_SETREGS 13
#endif
#ifndef PTRACE_GETFPREGS
#define PTRACE_GETFPREGS 14
#endif
#ifndef PTRACE_SETFPREGS
#define PTRACE_SETFPREGS 15
#endif

/* This oddity is because the Linux kernel defines elf_vrregset_t as
   an array of 33 16 bytes long elements.  I.e. it leaves out vrsave.
   However the PTRACE_GETVRREGS and PTRACE_SETVRREGS requests return
   the vrsave as an extra 4 bytes at the end.  I opted for creating a
   flat array of chars, so that it is easier to manipulate for gdb.

   There are 32 vector registers 16 bytes longs, plus a VSCR register
   which is only 4 bytes long, but is fetched as a 16 bytes
   quantity.  Up to here we have the elf_vrregset_t structure.
   Appended to this there is space for the VRSAVE register: 4 bytes.
   Even though this vrsave register is not included in the regset
   typedef, it is handled by the ptrace requests.

   The layout is like this (where x is the actual value of the vscr reg): */

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

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

  bool hwdebug_p ()
  {
    gdb_assert (detected_p ());
    return *m_interface == HWDEBUG;
  }

  bool debugreg_p ()
  {
    gdb_assert (detected_p ());
    return *m_interface == DEBUGREG;
  }

  bool unavailable_p ()
  {
    gdb_assert (detected_p ());
    return *m_interface == UNAVAILABLE;
  }

  /* Returns the debug register capabilities of the target.  Should only
     be called if the interface is HWDEBUG.  */
  const struct ppc_debug_info &hwdebug_info ()
  {
    gdb_assert (hwdebug_p ());

    return m_hwdebug_info;
  }

  /* Returns true if the interface has already been detected.  This is
     useful for cases when we know there is no work to be done if the
     interface hasn't been detected yet.  */
  bool detected_p ()
  {
    return m_interface.has_value ();
  }

  /* Detect the available interface, if any, if it hasn't been detected
     before, using PTID for the necessary ptrace calls.  */

  void detect (const ptid_t &ptid)
  {
    if (m_interface.has_value ())
      return;

    gdb_assert (ptid.lwp_p ());

    bool no_features = false;

    if (ptrace (PPC_PTRACE_GETHWDBGINFO, ptid.lwp (), 0, &m_hwdebug_info)
	!= -1)
      {
	/* If there are no advertised features, we don't use the
	   HWDEBUG interface and try the DEBUGREG interface instead.
	   It shouldn't be necessary to do this, however, when the
	   kernel is configured without CONFIG_HW_BREAKPOINTS (selected
	   by CONFIG_PERF_EVENTS), there is a bug that causes
	   watchpoints installed with the HWDEBUG interface not to
	   trigger.  When this is the case, features will be zero,
	   which we use as an indicator to fall back to the DEBUGREG
	   interface.  */
	if (m_hwdebug_info.features != 0)
	  {
	    m_interface.emplace (HWDEBUG);
	    return;
	  }
	else
	  no_features = true;
      }

    /* EIO indicates that the request is invalid, so we try DEBUGREG
       next.  Technically, it can also indicate other failures, but we
       can't differentiate those.

       Other errors could happen for various reasons.  We could get an
       ESRCH if the traced thread was killed by a signal.  Trying to
       detect the interface with another thread in the future would be
       complicated, as callers would have to handle an "unknown
       interface" case.  It's also unclear if raising an exception
       here would be safe.

       Other errors, such as ENODEV, could be more permanent and cause
       a failure for any thread.

       For simplicity, with all errors other than EIO, we set the
       interface to UNAVAILABLE and don't try DEBUGREG.  If DEBUGREG
       fails too, we'll also set the interface to UNAVAILABLE.  It's
       unlikely that trying the DEBUGREG interface with this same thread
       would work, for errors other than EIO.  This means that these
       errors will cause hardware watchpoints and breakpoints to become
       unavailable throughout a GDB session.  */

    if (no_features || errno == EIO)
      {
	unsigned long wp;

	if (ptrace (PTRACE_GET_DEBUGREG, ptid.lwp (), 0, &wp) != -1)
	  {
	    m_interface.emplace (DEBUGREG);
	    return;
	  }
      }

    if (errno != EIO)
      warning (_("Error when detecting the debug register interface. "
		 "Debug registers will be unavailable."));

    m_interface.emplace (UNAVAILABLE);
    return;
  }

private:

  /* HWDEBUG represents the set of calls PPC_PTRACE_GETHWDBGINFO,
     PPC_PTRACE_SETHWDEBUG and PPC_PTRACE_DELHWDEBUG.

     DEBUGREG represents the set of calls PTRACE_SET_DEBUGREG and
     PTRACE_GET_DEBUGREG.

     UNAVAILABLE can indicate that the kernel doesn't support any of the
     two sets of requests or that there was an error when we tried to
     detect wich interface is available.  */

  enum debug_reg_interface
    {
     UNAVAILABLE,
     HWDEBUG,
     DEBUGREG
    };

  /* The interface option.  Initialized if has_value () returns true.  */
  gdb::optional<enum debug_reg_interface> m_interface;

  /* The info returned by the kernel with PPC_PTRACE_GETHWDBGINFO.  Only
     valid if we determined that the interface is HWDEBUG.  */
  struct ppc_debug_info m_hwdebug_info;
};

/* Per-process information.  This includes the hardware watchpoints and
   breakpoints that GDB requested to this target.  */

struct ppc_linux_process_info
{
  /* The list of hardware watchpoints and breakpoints that GDB requested
     for this process.

     Only used when the interface is HWDEBUG.  */
  std::list<struct ppc_hw_breakpoint> requested_hw_bps;

  /* The watchpoint value that GDB requested for this process.

     Only used when the interface is DEBUGREG.  */
  gdb::optional<long> requested_wp_val;
};

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 (gdb_byte **readptr,
		  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;

/* *INDENT-OFF* */
/* registers layout, as presented by the ptrace interface:
PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5, PT_R6, PT_R7,
PT_R8, PT_R9, PT_R10, PT_R11, PT_R12, PT_R13, PT_R14, PT_R15,
PT_R16, PT_R17, PT_R18, PT_R19, PT_R20, PT_R21, PT_R22, PT_R23,
PT_R24, PT_R25, PT_R26, PT_R27, PT_R28, PT_R29, PT_R30, PT_R31,
PT_FPR0, PT_FPR0 + 2, PT_FPR0 + 4, PT_FPR0 + 6,
PT_FPR0 + 8, PT_FPR0 + 10, PT_FPR0 + 12, PT_FPR0 + 14,
PT_FPR0 + 16, PT_FPR0 + 18, PT_FPR0 + 20, PT_FPR0 + 22,
PT_FPR0 + 24, PT_FPR0 + 26, PT_FPR0 + 28, PT_FPR0 + 30,
PT_FPR0 + 32, PT_FPR0 + 34, PT_FPR0 + 36, PT_FPR0 + 38,
PT_FPR0 + 40, PT_FPR0 + 42, PT_FPR0 + 44, PT_FPR0 + 46,
PT_FPR0 + 48, PT_FPR0 + 50, PT_FPR0 + 52, PT_FPR0 + 54,
PT_FPR0 + 56, PT_FPR0 + 58, PT_FPR0 + 60, PT_FPR0 + 62,
PT_NIP, PT_MSR, PT_CCR, PT_LNK, PT_CTR, PT_XER, PT_MQ */
/* *INDENT_ON * */

static int
ppc_register_u_addr (struct gdbarch *gdbarch, int regno)
{
  int u_addr = -1;
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  /* NOTE: cagney/2003-11-25: This is the word size used by the ptrace
     interface, and not the wordsize of the program's ABI.  */
  int wordsize = sizeof (long);

  /* General purpose registers occupy 1 slot each in the buffer.  */
  if (regno >= tdep->ppc_gp0_regnum 
      && regno < tdep->ppc_gp0_regnum + ppc_num_gprs)
    u_addr = ((regno - tdep->ppc_gp0_regnum + PT_R0) * wordsize);

  /* Floating point regs: eight bytes each in both 32- and 64-bit
     ptrace interfaces.  Thus, two slots each in 32-bit interface, one
     slot each in 64-bit interface.  */
  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 ();
  struct gdbarch_tdep *tdep = 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 ();
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  /* This isn't really an address.  But ptrace thinks of it as one.  */
  CORE_ADDR regaddr = ppc_register_u_addr (gdbarch, regno);
  int bytes_transferred;
  gdb_byte buf[PPC_MAX_REGISTER_SIZE];

  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 (__FILE__, __LINE__,
                    _("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 ();
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  int i;

  if (have_ptrace_getsetregs)
    if (fetch_all_gp_regs (regcache, tid))
      return;

  /* If we've hit this point, it doesn't really matter which
     architecture we are using.  We just need to read the
     registers in the "old-fashioned way".  */
  for (i = 0; i < ppc_num_gprs; i++)
    fetch_register (regcache, tid, tdep->ppc_gp0_regnum + i);
}

/* This function actually issues the request to ptrace, telling
   it to get all floating-point registers and put them into the
   specified regset.
   
   If the ptrace request does not exist, this function returns 0
   and properly sets the have_ptrace_* flag.  If the request fails,
   this function calls perror_with_name.  Otherwise, if the request
   succeeds, then the regcache gets filled and 1 is returned.  */
static int
fetch_all_fp_regs (struct regcache *regcache, int tid)
{
  gdb_fpregset_t fpregs;

  if (ptrace (PTRACE_GETFPREGS, tid, 0, (void *) &fpregs) < 0)
    {
      if (errno == EIO)
        {
          have_ptrace_getsetfpregs = 0;
          return 0;
        }
      perror_with_name (_("Couldn't get floating-point registers."));
    }

  supply_fpregset (regcache, (const gdb_fpregset_t *) &fpregs);

  return 1;
}

/* This is a wrapper for the fetch_all_fp_regs function.  It is
   responsible for verifying if this target has the ptrace request
   that can be used to fetch all floating-point registers at one
   shot.  If it doesn't, then we should fetch them using the
   old-fashioned way, which is to iterate over the registers and
   request them one by one.  */
static void
fetch_fp_regs (struct regcache *regcache, int tid)
{
  struct gdbarch *gdbarch = regcache->arch ();
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  int i;

  if (have_ptrace_getsetfpregs)
    if (fetch_all_fp_regs (regcache, tid))
      return;
 
  /* If we've hit this point, it doesn't really matter which
     architecture we are using.  We just need to read the
     registers in the "old-fashioned way".  */
  for (i = 0; i < ppc_num_fprs; i++)
    fetch_register (regcache, tid, tdep->ppc_fp0_regnum + i);
}

static void 
fetch_ppc_registers (struct regcache *regcache, int tid)
{
  struct gdbarch *gdbarch = regcache->arch ();
  struct gdbarch_tdep *tdep = 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 ();
  struct gdbarch_tdep *tdep = 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 ();
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  /* This isn't really an address.  But ptrace thinks of it as one.  */
  CORE_ADDR regaddr = ppc_register_u_addr (gdbarch, regno);
  int i;
  size_t bytes_to_transfer;
  gdb_byte buf[PPC_MAX_REGISTER_SIZE];

  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 ();
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  int i;

  if (have_ptrace_getsetregs)
    if (store_all_gp_regs (regcache, tid, regno))
      return;

  /* If we hit this point, it doesn't really matter which
     architecture we are using.  We just need to store the
     registers in the "old-fashioned way".  */
  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 ();
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  int i;

  if (have_ptrace_getsetfpregs)
    if (store_all_fp_regs (regcache, tid, regno))
      return;

  /* If we hit this point, it doesn't really matter which
     architecture we are using.  We just need to store the
     registers in the "old-fashioned way".  */
  for (i = 0; i < ppc_num_fprs; i++)
    store_register (regcache, tid, tdep->ppc_fp0_regnum + i);
}

static void
store_ppc_registers (const struct regcache *regcache, int tid)
{
  struct gdbarch *gdbarch = regcache->arch ();
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
  store_gp_regs (regcache, tid, -1);
  if (tdep->ppc_fp0_regnum >= 0)
    store_fp_regs (regcache, tid, -1);
  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 (gdb_byte **readptr,
				  gdb_byte *endptr, CORE_ADDR *typep,
				  CORE_ADDR *valp)
{
  int tid = inferior_ptid.lwp ();
  if (tid == 0)
    tid = inferior_ptid.pid ();

  int sizeof_auxv_field = ppc_linux_target_wordsize (tid);

  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
  gdb_byte *ptr = *readptr;

  if (endptr == ptr)
    return 0;

  if (endptr - ptr < sizeof_auxv_field * 2)
    return -1;

  *typep = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order);
  ptr += sizeof_auxv_field;
  *valp = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order);
  ptr += sizeof_auxv_field;

  *readptr = ptr;
  return 1;
}

const struct target_desc *
ppc_linux_nat_target::read_description ()
{
  int tid = inferior_ptid.lwp ();
  if (tid == 0)
    tid = inferior_ptid.pid ();

  if (have_ptrace_getsetevrregs)
    {
      struct gdb_evrregset_t evrregset;

      if (ptrace (PTRACE_GETEVRREGS, tid, 0, &evrregset) >= 0)
        return tdesc_powerpc_e500l;

      /* EIO means that the PTRACE_GETEVRREGS request isn't supported.
	 Anything else needs to be reported.  */
      else if (errno != EIO)
	perror_with_name (_("Unable to fetch SPE registers"));
    }

  struct ppc_linux_features features = ppc_linux_no_features;

  features.wordsize = ppc_linux_target_wordsize (tid);

  CORE_ADDR hwcap = linux_get_hwcap (current_top_target ());
  CORE_ADDR hwcap2 = linux_get_hwcap2 (current_top_target ());

  if (have_ptrace_getsetvsxregs
      && (hwcap & PPC_FEATURE_HAS_VSX))
    {
      gdb_vsxregset_t vsxregset;

      if (ptrace (PTRACE_GETVSXREGS, tid, 0, &vsxregset) >= 0)
	features.vsx = true;

      /* EIO means that the PTRACE_GETVSXREGS request isn't supported.
	 Anything else needs to be reported.  */
      else if (errno != EIO)
	perror_with_name (_("Unable to fetch VSX registers"));
    }

  if (have_ptrace_getvrregs
      && (hwcap & PPC_FEATURE_HAS_ALTIVEC))
    {
      gdb_vrregset_t vrregset;

      if (ptrace (PTRACE_GETVRREGS, tid, 0, &vrregset) >= 0)
        features.altivec = true;

      /* EIO means that the PTRACE_GETVRREGS request isn't supported.
	 Anything else needs to be reported.  */
      else if (errno != EIO)
	perror_with_name (_("Unable to fetch AltiVec registers"));
    }

  features.isa205 = ppc_linux_has_isa205 (hwcap);

  if ((hwcap2 & PPC_FEATURE2_DSCR)
      && check_regset (tid, NT_PPC_PPR, PPC_LINUX_SIZEOF_PPRREGSET)
      && check_regset (tid, NT_PPC_DSCR, PPC_LINUX_SIZEOF_DSCRREGSET))
    {
      features.ppr_dscr = true;
      if ((hwcap2 & PPC_FEATURE2_ARCH_2_07)
	  && (hwcap2 & PPC_FEATURE2_TAR)
	  && (hwcap2 & PPC_FEATURE2_EBB)
	  && check_regset (tid, NT_PPC_TAR, PPC_LINUX_SIZEOF_TARREGSET)
	  && check_regset (tid, NT_PPC_EBB, PPC_LINUX_SIZEOF_EBBREGSET)
	  && check_regset (tid, NT_PPC_PMU, PPC_LINUX_SIZEOF_PMUREGSET))
	{
	  features.isa207 = true;
	  if ((hwcap2 & PPC_FEATURE2_HTM)
	      && check_regset (tid, NT_PPC_TM_SPR,
			       PPC_LINUX_SIZEOF_TM_SPRREGSET))
	    features.htm = true;
	}
    }

  return ppc_linux_match_description (features);
}

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

      /* Embedded DAC-based processors, like the PowerPC 440 have ranged
	 watchpoints and can watch any access within an arbitrary memory
	 region. This is useful to watch arrays and structs, for instance.  It
         takes two hardware watchpoints though.  */
      if (len > 1
	  && hwdebug_info.features & PPC_DEBUG_FEATURE_DATA_BP_RANGE
	  && linux_get_hwcap (current_top_target ()) & 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 which
	   can't cross a 512 byte boundary.  */
	region_size = 512;
      else
	region_size = hwdebug_info.data_bp_alignment;
      /* Server processors provide one hardware watchpoint and addr+len should
         fall in the watchable region provided by the ptrace interface.  */
      if (region_size
	  && (addr + len > (addr & ~(region_size - 1)) + region_size))
	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 (current_top_target ()) & 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 or watchpoints have been requested for this process,
     we have at least one free DVC register.  */
  if (process_it == m_process_info.end ())
    return true;

  for (const ppc_hw_breakpoint &bp : process_it->second.requested_hw_bps)
    if (bp.condition_mode != PPC_BREAKPOINT_CONDITION_NONE)
      cnt--;

  if (cnt <= 0)
    return false;

  return true;
}

/* 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 (VALUE_LVAL (v) == not_lval || deprecated_value_modifiable (v) == 0)
	continue;
      else if (VALUE_LVAL (v) == lval_memory)
	{
	  /* A lazy memory lvalue is one that GDB never needed to fetch;
	     we either just used its address (e.g., `a' in `a.b') or
	     we never needed it at all (e.g., `a' in `a,b').  */
	  if (!value_lazy (v))
	    found_memory_cnt++;
	}
      /* Other kinds of values are not fine.  */
      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 pc = 1, num_accesses_left, num_accesses_right;
  struct value *left_val, *right_val;
  std::vector<value_ref_ptr> left_chain, right_chain;

  if (cond->elts[0].opcode != BINOP_EQUAL)
    return 0;

  fetch_subexp_value (cond, &pc, &left_val, NULL, &left_chain, 0);
  num_accesses_left = num_memory_accesses (left_chain);

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

  fetch_subexp_value (cond, &pc, &right_val, NULL, &right_chain, 0);
  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
      && VALUE_LVAL (left_val) == lval_memory
      && value_address (left_val) == watch_addr)
    {
      *data_value = value_as_long (right_val);

      /* DATA_VALUE is the constant in RIGHT_VAL, but actually has
	 the same type as the memory region referenced by LEFT_VAL.  */
      *len = TYPE_LENGTH (check_typedef (value_type (left_val)));
    }
  else if (num_accesses_left == 0 && num_accesses_right == 1
	   && VALUE_LVAL (right_val) == lval_memory
	   && value_address (right_val) == watch_addr)
    {
      *data_value = value_as_long (left_val);

      /* DATA_VALUE is the constant in LEFT_VAL, but actually has
	 the same type as the memory region referenced by RIGHT_VAL.  */
      *len = TYPE_LENGTH (check_typedef (value_type (right_val)));
    }
  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 (current_top_target ()) & 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
   sate 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) == -1)
		if (errno != ENOENT)
		  perror_with_name (_("Error deleting hardware "
				      "breakpoint or watchpoint"));

	      /* We erase the entries one at a time after successfuly
		 removing the corresponding slot form the thread so that
		 if we throw an exception above in a future iteration the
		 map remains consistent.  */
	      bp_it = bp_list.erase (bp_it);
	    }

	  gdb_assert (bp_list.empty ());
	}

      /* Now we install all the requested hardware breakpoints and
	 watchpoints and update the thread state.  */

      if (process_it != m_process_info.end ())
	{
	  auto &bp_list = m_installed_hw_bps[lp->ptid];

	  for (ppc_hw_breakpoint bp
		 : process_it->second.requested_hw_bps)
	    {
	      long slot = ptrace (PPC_PTRACE_SETHWDEBUG, lp->ptid.lwp (),
				  0, &bp);

	      if (slot < 0)
		perror_with_name (_("Error setting hardware "
				    "breakpoint or watchpoint"));

	      /* Keep track of which slots we installed in this
		 thread.  */
	      bp_list.emplace (bp_list.begin (), slot, bp);
	    }
	}
    }
  else
    {
      gdb_assert (m_dreg_interface.debugreg_p ());

      /* Passing 0 to PTRACE_SET_DEBUGREG will clear the
	 watchpoint.  */
      long wp = 0;

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

      long ret = ptrace (PTRACE_SET_DEBUGREG, lp->ptid.lwp (),
			 0, wp);

      if (ret == -1)
	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 (current_top_target ()) & PPC_FEATURE_BOOKE)
    return start <= addr && start + length >= addr;
  else if (linux_get_hwcap (current_top_target ()) & PPC_FEATURE_BOOKE)
    mask = 3;
  else
    mask = 7;

  addr &= ~mask;

  /* Check whether [start, start+length-1] intersects [addr, addr+mask].  */
  return start <= addr + mask && start + length - 1 >= addr;
}

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