/* IBM RS/6000 native-dependent code for GDB, the GNU debugger.

   Copyright (C) 1986-2024 Free Software Foundation, Inc.

   This file is part of GDB.

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

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

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

#include "inferior.h"
#include "target.h"
#include "gdbcore.h"
#include "symfile.h"
#include "objfiles.h"
#include "bfd.h"
#include "gdb-stabs.h"
#include "regcache.h"
#include "arch-utils.h"
#include "inf-child.h"
#include "inf-ptrace.h"
#include "ppc-tdep.h"
#include "rs6000-aix-tdep.h"
#include "exec.h"
#include "observable.h"
#include "xcoffread.h"

#include <sys/ptrace.h>
#include <sys/reg.h>

#include <sys/dir.h>
#include <sys/user.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include "gdbsupport/eintr.h"

#include <a.out.h>
#include <sys/file.h>
#include <sys/stat.h>
#include "gdb_bfd.h"
#include <sys/core.h>
#define __LDINFO_PTRACE32__	/* for __ld_info32 */
#define __LDINFO_PTRACE64__	/* for __ld_info64 */
#include <sys/ldr.h>
#include <sys/systemcfg.h>

/* Header files for getting ppid in AIX of a child process.  */
#include <procinfo.h>
#include <sys/types.h>

/* Header files for alti-vec reg.  */
#include <sys/context.h>

/* On AIX4.3+, sys/ldr.h provides different versions of struct ld_info for
   debugging 32-bit and 64-bit processes.  Define a typedef and macros for
   accessing fields in the appropriate structures.  */

/* In 32-bit compilation mode (which is the only mode from which ptrace()
   works on 4.3), __ld_info32 is #defined as equivalent to ld_info.  */

#if defined (__ld_info32) || defined (__ld_info64)
# define ARCH3264
#endif

/* Return whether the current architecture is 64-bit.  */

#ifndef ARCH3264
# define ARCH64() 0
#else
# define ARCH64() (register_size (current_inferior ()->arch (), 0) == 8)
#endif

class rs6000_nat_target final : public inf_ptrace_target
{
public:
  void fetch_registers (struct regcache *, int) override;
  void store_registers (struct regcache *, int) override;

  enum target_xfer_status xfer_partial (enum target_object object,
					const char *annex,
					gdb_byte *readbuf,
					const gdb_byte *writebuf,
					ULONGEST offset, ULONGEST len,
					ULONGEST *xfered_len) override;

  void create_inferior (const char *, const std::string &,
			char **, int) override;

  ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override;

  /* Fork detection related functions, For adding multi process debugging
     support.  */
  void follow_fork (inferior *, ptid_t, target_waitkind, bool, bool) override;

  const struct target_desc *read_description ()  override;

  int insert_fork_catchpoint (int) override;
  int remove_fork_catchpoint (int) override;

protected:

  void post_startup_inferior (ptid_t ptid) override;

private:
  enum target_xfer_status
    xfer_shared_libraries (enum target_object object,
			   const char *annex, gdb_byte *readbuf,
			   const gdb_byte *writebuf,
			   ULONGEST offset, ULONGEST len,
			   ULONGEST *xfered_len);
};

static rs6000_nat_target the_rs6000_nat_target;

/* The below declaration is to track number of times, parent has
   reported fork event before its children.  */

static std::list<pid_t> aix_pending_parent;

/* The below declaration is for a child process event that
   is reported before its corresponding parent process in
   the event of a fork ().  */

static std::list<pid_t> aix_pending_children;

static void
aix_remember_child (pid_t pid)
{
  aix_pending_children.push_front (pid);
}

static void
aix_remember_parent (pid_t pid)
{
  aix_pending_parent.push_front (pid);
}

/* This function returns a parent of a child process.  */

static pid_t
find_my_aix_parent (pid_t child_pid)
{
  struct procsinfo ProcessBuffer1;

  if (getprocs (&ProcessBuffer1, sizeof (ProcessBuffer1),
		NULL, 0, &child_pid, 1) != 1)
    return 0;
  else
    return ProcessBuffer1.pi_ppid;
}

/* In the below function we check if there was any child
   process pending.  If it exists we return it from the
   list, otherwise we return a null.  */

static pid_t
has_my_aix_child_reported (pid_t parent_pid)
{
  pid_t child = 0;
  auto it = std::find_if (aix_pending_children.begin (),
			  aix_pending_children.end (),
			  [=] (pid_t child_pid)
			  {
			    return find_my_aix_parent (child_pid) == parent_pid;
			  });
  if (it != aix_pending_children.end ())
    {
      child = *it;
      aix_pending_children.erase (it);
    }
  return child;
}

/* In the below function we check if there was any parent
   process pending.  If it exists we return it from the
   list, otherwise we return a null.  */

static pid_t
has_my_aix_parent_reported (pid_t child_pid)
{
  pid_t my_parent = find_my_aix_parent (child_pid);
  auto it = std::find (aix_pending_parent.begin (),
		       aix_pending_parent.end (),
		       my_parent);
  if (it != aix_pending_parent.end ())
    {
      aix_pending_parent.erase (it);
      return my_parent;
    }
  return 0;
}

/* Given REGNO, a gdb register number, return the corresponding
   number suitable for use as a ptrace() parameter.  Return -1 if
   there's no suitable mapping.  Also, set the int pointed to by
   ISFLOAT to indicate whether REGNO is a floating point register.  */

static int
regmap (struct gdbarch *gdbarch, int regno, int *isfloat)
{
  ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);

  *isfloat = 0;
  if (tdep->ppc_gp0_regnum <= regno
      && regno < tdep->ppc_gp0_regnum + ppc_num_gprs)
    return regno;
  else if (tdep->ppc_fp0_regnum >= 0
	   && tdep->ppc_fp0_regnum <= regno
	   && regno < tdep->ppc_fp0_regnum + ppc_num_fprs)
    {
      *isfloat = 1;
      return regno - tdep->ppc_fp0_regnum + FPR0;
    }
  else if (regno == gdbarch_pc_regnum (gdbarch))
    return IAR;
  else if (regno == tdep->ppc_ps_regnum)
    return MSR;
  else if (regno == tdep->ppc_cr_regnum)
    return CR;
  else if (regno == tdep->ppc_lr_regnum)
    return LR;
  else if (regno == tdep->ppc_ctr_regnum)
    return CTR;
  else if (regno == tdep->ppc_xer_regnum)
    return XER;
  else if (tdep->ppc_fpscr_regnum >= 0
	   && regno == tdep->ppc_fpscr_regnum)
    return FPSCR;
  else if (tdep->ppc_mq_regnum >= 0 && regno == tdep->ppc_mq_regnum)
    return MQ;
  else
    return -1;
}

/* Call ptrace(REQ, ID, ADDR, DATA, BUF).  */

static int
rs6000_ptrace32 (int req, int id, int *addr, int data, int *buf)
{
#ifdef HAVE_PTRACE64
  int ret = ptrace64 (req, id, (uintptr_t) addr, data, buf);
#else
  int ret = ptrace (req, id, (int *)addr, data, buf);
#endif
#if 0
  printf ("rs6000_ptrace32 (%d, %d, 0x%x, %08x, 0x%x) = 0x%x\n",
	  req, id, (unsigned int)addr, data, (unsigned int)buf, ret);
#endif
  return ret;
}

/* Call ptracex(REQ, ID, ADDR, DATA, BUF).  */

static int
rs6000_ptrace64 (int req, int id, long long addr, int data, void *buf)
{
#ifdef ARCH3264
#  ifdef HAVE_PTRACE64
  int ret = ptrace64 (req, id, addr, data, (PTRACE_TYPE_ARG5) buf);
#  else
  int ret = ptracex (req, id, addr, data, (PTRACE_TYPE_ARG5) buf);
#  endif
#else
  int ret = 0;
#endif
#if 0
  printf ("rs6000_ptrace64 (%d, %d, %s, %08x, 0x%x) = 0x%x\n",
	  req, id, hex_string (addr), data, (unsigned int)buf, ret);
#endif
  return ret;
}

/* Store the vsx registers.  */

static void
store_vsx_register_aix (struct regcache *regcache, int regno)
{
  int ret;
  struct gdbarch *gdbarch = regcache->arch ();
  ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
  struct thrdentry64 thrdentry;
  __vsx_context_t vsx;
  pid_t pid = inferior_ptid.pid ();
  tid64_t thrd_i = 0;

  if (getthrds64(pid, &thrdentry, sizeof(struct thrdentry64),
		 &thrd_i, 1) == 1)
    thrd_i = thrdentry.ti_tid;

  memset(&vsx, 0, sizeof(__vsx_context_t));
  if (__power_vsx() && thrd_i > 0)
    {
      if (ARCH64 ())
	ret = rs6000_ptrace64 (PTT_READ_VSX, thrd_i, (long long) &vsx, 0, 0);
      else
	ret = rs6000_ptrace32 (PTT_READ_VSX, thrd_i, (int *)&vsx, 0, 0);
      if (ret < 0)
	return;

      regcache->raw_collect (regno, &(vsx.__vsr_dw1[0])+
			     regno - tdep->ppc_vsr0_upper_regnum);

      if (ARCH64 ())
	ret = rs6000_ptrace64 (PTT_WRITE_VSX, thrd_i, (long long) &vsx, 0, 0);
      else
	ret = rs6000_ptrace32 (PTT_WRITE_VSX, thrd_i, (int *) &vsx, 0, 0);

      if (ret < 0)
	perror_with_name (_("Unable to write VSX registers after reading it"));
    }
}

/* Store Altivec registers.  */

static void
store_altivec_register_aix (struct regcache *regcache, int regno)
{
  int ret;
  struct gdbarch *gdbarch = regcache->arch ();
  ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
  struct thrdentry64 thrdentry;
  __vmx_context_t vmx;
  pid_t pid = inferior_ptid.pid ();
  tid64_t  thrd_i = 0;

  if (getthrds64(pid, &thrdentry, sizeof(struct thrdentry64),
		 &thrd_i, 1) == 1)
    thrd_i = thrdentry.ti_tid;

  memset(&vmx, 0, sizeof(__vmx_context_t));
  if (__power_vmx() && thrd_i > 0)
    {
      if (ARCH64 ())
	ret = rs6000_ptrace64 (PTT_READ_VEC, thrd_i, (long long) &vmx, 0, 0);
      else
	ret = rs6000_ptrace32 (PTT_READ_VEC, thrd_i, (int *) &vmx, 0, 0);
      if (ret < 0)
	return;

      regcache->raw_collect (regno, &(vmx.__vr[0]) + regno
			     - tdep->ppc_vr0_regnum);

      if (ARCH64 ())
	ret = rs6000_ptrace64 (PTT_WRITE_VEC, thrd_i, (long long) &vmx, 0, 0);
      else
	ret = rs6000_ptrace32 (PTT_WRITE_VEC, thrd_i, (int *) &vmx, 0, 0);
      if (ret < 0)
	perror_with_name (_("Unable to store AltiVec register after reading it"));
    }
}

/* Supply altivec registers.  */

static void
supply_vrregset_aix (struct regcache *regcache, __vmx_context_t *vmx)
{
  int i;
  struct gdbarch *gdbarch = regcache->arch ();
  ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
  int num_of_vrregs = tdep->ppc_vrsave_regnum - tdep->ppc_vr0_regnum + 1;

  for (i = 0; i < num_of_vrregs; i++)
    regcache->raw_supply (tdep->ppc_vr0_regnum + i,
			  &(vmx->__vr[i]));
  regcache->raw_supply (tdep->ppc_vrsave_regnum, &(vmx->__vrsave));
  regcache->raw_supply (tdep->ppc_vrsave_regnum - 1, &(vmx->__vscr));
}

/* Fetch altivec register.  */

static void
fetch_altivec_registers_aix (struct regcache *regcache)
{
  struct thrdentry64 thrdentry;
  __vmx_context_t vmx;
  pid_t pid = current_inferior ()->pid;
  tid64_t  thrd_i = 0;

  if (getthrds64(pid, &thrdentry, sizeof(struct thrdentry64),
		 &thrd_i, 1) == 1)
    thrd_i = thrdentry.ti_tid;

  memset(&vmx, 0, sizeof(__vmx_context_t));
  if (__power_vmx() && thrd_i > 0)
    {
      if (ARCH64 ())
	rs6000_ptrace64 (PTT_READ_VEC, thrd_i, (long long) &vmx, 0, 0);
      else
	rs6000_ptrace32 (PTT_READ_VEC, thrd_i, (int *) &vmx, 0, 0);
      supply_vrregset_aix (regcache, &vmx);
    }
}

/* supply vsx register.  */

static void
supply_vsxregset_aix (struct regcache *regcache, __vsx_context_t *vsx)
{
  int i;
  struct gdbarch *gdbarch = regcache->arch ();
  ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);

  for (i = 0; i < ppc_num_vshrs; i++)
   regcache->raw_supply (tdep->ppc_vsr0_upper_regnum + i,
			 &(vsx->__vsr_dw1[i]));
}

/* Fetch vsx registers.  */
static void
fetch_vsx_registers_aix (struct regcache *regcache)
{
  struct thrdentry64 thrdentry;
  __vsx_context_t vsx;
  pid_t pid = current_inferior ()->pid;
  tid64_t  thrd_i = 0;

  if (getthrds64(pid, &thrdentry, sizeof(struct thrdentry64),
		 &thrd_i, 1) == 1)
    thrd_i = thrdentry.ti_tid;

  memset(&vsx, 0, sizeof(__vsx_context_t));
  if (__power_vsx() && thrd_i > 0)
    {
      if (ARCH64 ())
	rs6000_ptrace64 (PTT_READ_VSX, thrd_i, (long long) &vsx, 0, 0);
      else
	rs6000_ptrace32 (PTT_READ_VSX, thrd_i, (int *) &vsx, 0, 0);
      supply_vsxregset_aix (regcache, &vsx);
    }
}

void rs6000_nat_target::post_startup_inferior (ptid_t ptid)
{

  /* In AIX to turn on multi process debugging in ptrace
     PT_MULTI is the option to be passed,
     with the process ID which can fork () and
     the data parameter [fourth parameter] must be 1.  */

  if (!ARCH64 ())
    rs6000_ptrace32 (PT_MULTI, ptid.pid(), 0, 1, 0);
  else
    rs6000_ptrace64 (PT_MULTI, ptid.pid(), 0, 1, 0);
}

void
rs6000_nat_target::follow_fork (inferior *child_inf, ptid_t child_ptid,
				target_waitkind fork_kind, bool follow_child,
				bool detach_fork)
{

  /* Once the fork event is detected the infrun.c code
     calls the target_follow_fork to take care of
     follow child and detach the child activity which is
     done using the function below.  */

  inf_ptrace_target::follow_fork (child_inf, child_ptid, fork_kind,
				  follow_child, detach_fork);

  /* If we detach fork and follow child we do not want the child
     process to generate events that ptrace can trace.  Hence we
     detach it.  */

  if (detach_fork && !follow_child)
  {
    if (ARCH64 ())
      rs6000_ptrace64 (PT_DETACH, child_ptid.pid (), 0, 0, 0);
    else
      rs6000_ptrace32 (PT_DETACH, child_ptid.pid (), 0, 0, 0);
  }
}

/* Functions for catchpoint in AIX.  */
int
rs6000_nat_target::insert_fork_catchpoint (int pid)
{
  return 0;
}

int
rs6000_nat_target::remove_fork_catchpoint (int pid)
{
  return 0;
}

/* Fetch register REGNO from the inferior.  */

static void
fetch_register (struct regcache *regcache, int regno)
{
  struct gdbarch *gdbarch = regcache->arch ();
  int addr[PPC_MAX_REGISTER_SIZE];
  int nr, isfloat;
  pid_t pid = regcache->ptid ().pid ();

  /* Retrieved values may be -1, so infer errors from errno.  */
  errno = 0;

  /* Alti-vec register.  */
  if (altivec_register_p (gdbarch, regno))
    {
      fetch_altivec_registers_aix (regcache);
      return;
    }

  /* VSX register.  */
  if (vsx_register_p (gdbarch, regno))
    {
      fetch_vsx_registers_aix (regcache);
      return;
    }

  nr = regmap (gdbarch, regno, &isfloat);

  /* Floating-point registers.  */
  if (isfloat)
    rs6000_ptrace32 (PT_READ_FPR, pid, addr, nr, 0);

  /* Bogus register number.  */
  else if (nr < 0)
    {
      if (regno >= gdbarch_num_regs (gdbarch))
	gdb_printf (gdb_stderr,
		    "gdb error: register no %d not implemented.\n",
		    regno);
      return;
    }

  /* Fixed-point registers.  */
  else
    {
      if (!ARCH64 ())
	*addr = rs6000_ptrace32 (PT_READ_GPR, pid, (int *) nr, 0, 0);
      else
	{
	  /* PT_READ_GPR requires the buffer parameter to point to long long,
	     even if the register is really only 32 bits.  */
	  long long buf;
	  rs6000_ptrace64 (PT_READ_GPR, pid, nr, 0, &buf);
	  if (register_size (gdbarch, regno) == 8)
	    memcpy (addr, &buf, 8);
	  else
	    *addr = buf;
	}
    }

  if (!errno)
    regcache->raw_supply (regno, (char *) addr);
  else
    {
#if 0
      /* FIXME: this happens 3 times at the start of each 64-bit program.  */
      perror (_("ptrace read"));
#endif
      errno = 0;
    }
}

/* Store register REGNO back into the inferior.  */

static void
store_register (struct regcache *regcache, int regno)
{
  struct gdbarch *gdbarch = regcache->arch ();
  int addr[PPC_MAX_REGISTER_SIZE];
  int nr, isfloat;
  pid_t pid = regcache->ptid ().pid ();

  /* Fetch the register's value from the register cache.  */
  regcache->raw_collect (regno, addr);

  /* -1 can be a successful return value, so infer errors from errno.  */
  errno = 0;

  if (altivec_register_p (gdbarch, regno))
    {
      store_altivec_register_aix (regcache, regno);
      return;
    }

  if (vsx_register_p (gdbarch, regno))
    {
      store_vsx_register_aix (regcache, regno);
      return;
    }

  nr = regmap (gdbarch, regno, &isfloat);

  /* Floating-point registers.  */
  if (isfloat)
    rs6000_ptrace32 (PT_WRITE_FPR, pid, addr, nr, 0);

  /* Bogus register number.  */
  else if (nr < 0)
    {
      if (regno >= gdbarch_num_regs (gdbarch))
	gdb_printf (gdb_stderr,
		    "gdb error: register no %d not implemented.\n",
		    regno);
    }

  /* Fixed-point registers.  */
  else
    {
      /* The PT_WRITE_GPR operation is rather odd.  For 32-bit inferiors,
	 the register's value is passed by value, but for 64-bit inferiors,
	 the address of a buffer containing the value is passed.  */
      if (!ARCH64 ())
	rs6000_ptrace32 (PT_WRITE_GPR, pid, (int *) nr, *addr, 0);
      else
	{
	  /* PT_WRITE_GPR requires the buffer parameter to point to an 8-byte
	     area, even if the register is really only 32 bits.  */
	  long long buf;
	  if (register_size (gdbarch, regno) == 8)
	    memcpy (&buf, addr, 8);
	  else
	    buf = *addr;
	  rs6000_ptrace64 (PT_WRITE_GPR, pid, nr, 0, &buf);
	}
    }

  if (errno)
    {
      perror (_("ptrace write"));
      errno = 0;
    }
}

/* Read from the inferior all registers if REGNO == -1 and just register
   REGNO otherwise.  */

void
rs6000_nat_target::fetch_registers (struct regcache *regcache, int regno)
{
  struct gdbarch *gdbarch = regcache->arch ();
  if (regno != -1)
    fetch_register (regcache, regno);

  else
    {
      ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);

      /* Read 32 general purpose registers.  */
      for (regno = tdep->ppc_gp0_regnum;
	   regno < tdep->ppc_gp0_regnum + ppc_num_gprs;
	   regno++)
	{
	  fetch_register (regcache, regno);
	}

      /* Read general purpose floating point registers.  */
      if (tdep->ppc_fp0_regnum >= 0)
	for (regno = 0; regno < ppc_num_fprs; regno++)
	  fetch_register (regcache, tdep->ppc_fp0_regnum + regno);

      if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1)
	fetch_altivec_registers_aix (regcache);

      if (tdep->ppc_vsr0_upper_regnum != -1)
	fetch_vsx_registers_aix (regcache);

      /* Read special registers.  */
      fetch_register (regcache, gdbarch_pc_regnum (gdbarch));
      fetch_register (regcache, tdep->ppc_ps_regnum);
      fetch_register (regcache, tdep->ppc_cr_regnum);
      fetch_register (regcache, tdep->ppc_lr_regnum);
      fetch_register (regcache, tdep->ppc_ctr_regnum);
      fetch_register (regcache, tdep->ppc_xer_regnum);
      if (tdep->ppc_fpscr_regnum >= 0)
	fetch_register (regcache, tdep->ppc_fpscr_regnum);
      if (tdep->ppc_mq_regnum >= 0)
	fetch_register (regcache, tdep->ppc_mq_regnum);
    }
}

const struct target_desc *
rs6000_nat_target::read_description ()
{
   if (ARCH64())
     {
       if (__power_vsx ())
	 return tdesc_powerpc_vsx64;
       else if (__power_vmx ())
	 return tdesc_powerpc_altivec64;
     }
   else
     {
       if (__power_vsx ())
	 return tdesc_powerpc_vsx32;
       else if (__power_vmx ())
	 return tdesc_powerpc_altivec32;
     }
   return NULL;
}

/* Store our register values back into the inferior.
   If REGNO is -1, do this for all registers.
   Otherwise, REGNO specifies which register (so we can save time).  */

void
rs6000_nat_target::store_registers (struct regcache *regcache, int regno)
{
  struct gdbarch *gdbarch = regcache->arch ();
  if (regno != -1)
    store_register (regcache, regno);

  else
    {
      ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);

      /* Write general purpose registers first.  */
      for (regno = tdep->ppc_gp0_regnum;
	   regno < tdep->ppc_gp0_regnum + ppc_num_gprs;
	   regno++)
	{
	  store_register (regcache, regno);
	}

      /* Write floating point registers.  */
      if (tdep->ppc_fp0_regnum >= 0)
	for (regno = 0; regno < ppc_num_fprs; regno++)
	  store_register (regcache, tdep->ppc_fp0_regnum + regno);

      /* Write special registers.  */
      store_register (regcache, gdbarch_pc_regnum (gdbarch));
      store_register (regcache, tdep->ppc_ps_regnum);
      store_register (regcache, tdep->ppc_cr_regnum);
      store_register (regcache, tdep->ppc_lr_regnum);
      store_register (regcache, tdep->ppc_ctr_regnum);
      store_register (regcache, tdep->ppc_xer_regnum);
      if (tdep->ppc_fpscr_regnum >= 0)
	store_register (regcache, tdep->ppc_fpscr_regnum);
      if (tdep->ppc_mq_regnum >= 0)
	store_register (regcache, tdep->ppc_mq_regnum);
    }
}

/* Implement the to_xfer_partial target_ops method.  */

enum target_xfer_status
rs6000_nat_target::xfer_partial (enum target_object object,
				 const char *annex, gdb_byte *readbuf,
				 const gdb_byte *writebuf,
				 ULONGEST offset, ULONGEST len,
				 ULONGEST *xfered_len)
{
  pid_t pid = inferior_ptid.pid ();
  int arch64 = ARCH64 ();

  switch (object)
    {
    case TARGET_OBJECT_LIBRARIES_AIX:
      return xfer_shared_libraries (object, annex,
				    readbuf, writebuf,
				    offset, len, xfered_len);
    case TARGET_OBJECT_MEMORY:
      {
	union
	{
	  PTRACE_TYPE_RET word;
	  gdb_byte byte[sizeof (PTRACE_TYPE_RET)];
	} buffer;
	ULONGEST rounded_offset;
	LONGEST partial_len;

	/* Round the start offset down to the next long word
	   boundary.  */
	rounded_offset = offset & -(ULONGEST) sizeof (PTRACE_TYPE_RET);

	/* Since ptrace will transfer a single word starting at that
	   rounded_offset the partial_len needs to be adjusted down to
	   that (remember this function only does a single transfer).
	   Should the required length be even less, adjust it down
	   again.  */
	partial_len = (rounded_offset + sizeof (PTRACE_TYPE_RET)) - offset;
	if (partial_len > len)
	  partial_len = len;

	if (writebuf)
	  {
	    /* If OFFSET:PARTIAL_LEN is smaller than
	       ROUNDED_OFFSET:WORDSIZE then a read/modify write will
	       be needed.  Read in the entire word.  */
	    if (rounded_offset < offset
		|| (offset + partial_len
		    < rounded_offset + sizeof (PTRACE_TYPE_RET)))
	      {
		/* Need part of initial word -- fetch it.  */
		if (arch64)
		  buffer.word = rs6000_ptrace64 (PT_READ_I, pid,
						 rounded_offset, 0, NULL);
		else
		  buffer.word = rs6000_ptrace32 (PT_READ_I, pid,
						 (int *) (uintptr_t)
						 rounded_offset,
						 0, NULL);
	      }

	    /* Copy data to be written over corresponding part of
	       buffer.  */
	    memcpy (buffer.byte + (offset - rounded_offset),
		    writebuf, partial_len);

	    errno = 0;
	    if (arch64)
	      rs6000_ptrace64 (PT_WRITE_D, pid,
			       rounded_offset, buffer.word, NULL);
	    else
	      rs6000_ptrace32 (PT_WRITE_D, pid,
			       (int *) (uintptr_t) rounded_offset,
			       buffer.word, NULL);
	    if (errno)
	      return TARGET_XFER_EOF;
	  }

	if (readbuf)
	  {
	    errno = 0;
	    if (arch64)
	      buffer.word = rs6000_ptrace64 (PT_READ_I, pid,
					     rounded_offset, 0, NULL);
	    else
	      buffer.word = rs6000_ptrace32 (PT_READ_I, pid,
					     (int *)(uintptr_t)rounded_offset,
					     0, NULL);
	    if (errno)
	      return TARGET_XFER_EOF;

	    /* Copy appropriate bytes out of the buffer.  */
	    memcpy (readbuf, buffer.byte + (offset - rounded_offset),
		    partial_len);
	  }

	*xfered_len = (ULONGEST) partial_len;
	return TARGET_XFER_OK;
      }

    default:
      return TARGET_XFER_E_IO;
    }
}

/* Wait for the child specified by PTID to do something.  Return the
   process ID of the child, or MINUS_ONE_PTID in case of error; store
   the status in *OURSTATUS.  */

ptid_t
rs6000_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
			 target_wait_flags options)
{
  pid_t pid;
  int status, save_errno;

  while (1)
    {
      set_sigint_trap ();

      pid = gdb::waitpid (ptid.pid (), &status, 0);
      save_errno = errno;

      clear_sigint_trap ();

      if (pid == -1)
	{
	  gdb_printf (gdb_stderr,
		      _("Child process unexpectedly missing: %s.\n"),
		      safe_strerror (save_errno));

	  ourstatus->set_ignore ();
	  return minus_one_ptid;
	}

      /* Ignore terminated detached child processes.  */
      if (!WIFSTOPPED (status) && find_inferior_pid (this, pid) == nullptr)
	continue;

      /* Check for a fork () event.  */
      if ((status & 0xff) == W_SFWTED)
	{
	  /* Checking whether it is a parent or a child event.  */

	  /* If the event is a child we check if there was a parent
	     event recorded before.  If yes we got the parent child
	     relationship.  If not we push this child and wait for
	     the next fork () event.  */
	  if (find_inferior_pid (this, pid) == nullptr)
	    {
	      pid_t parent_pid = has_my_aix_parent_reported (pid);
	      if (parent_pid > 0)
		{
		  ourstatus->set_forked (ptid_t (pid));
		  return ptid_t (parent_pid);
		}
	      aix_remember_child (pid);
	    }

	  /* If the event is a parent we check if there was a child
	     event recorded before.  If yes we got the parent child
	     relationship.  If not we push this parent and wait for
	     the next fork () event.  */
	  else
	    {
	      pid_t child_pid = has_my_aix_child_reported (pid);
	      if (child_pid > 0)
		{
		  ourstatus->set_forked (ptid_t (child_pid));
		  return ptid_t (pid);
		}
	      aix_remember_parent (pid);
	    }
	  continue;
	}

      break;
    }

  /* AIX has a couple of strange returns from wait().  */

  /* stop after load" status.  */
  if (status == 0x57c)
    ourstatus->set_loaded ();
  /* 0x7f is signal 0.  */
  else if (status == 0x7f)
    ourstatus->set_spurious ();
  /* A normal waitstatus.  Let the usual macros deal with it.  */
  else
    *ourstatus = host_status_to_waitstatus (status);

  return ptid_t (pid);
}


/* Set the current architecture from the host running GDB.  Called when
   starting a child process.  */

void
rs6000_nat_target::create_inferior (const char *exec_file,
				    const std::string &allargs,
				    char **env, int from_tty)
{
  enum bfd_architecture arch;
  unsigned long mach;
  bfd abfd;

  inf_ptrace_target::create_inferior (exec_file, allargs, env, from_tty);

  if (__power_rs ())
    {
      arch = bfd_arch_rs6000;
      mach = bfd_mach_rs6k;
    }
  else
    {
      arch = bfd_arch_powerpc;
      mach = bfd_mach_ppc;
    }

  /* FIXME: schauer/2002-02-25:
     We don't know if we are executing a 32 or 64 bit executable,
     and have no way to pass the proper word size to rs6000_gdbarch_init.
     So we have to avoid switching to a new architecture, if the architecture
     matches already.
     Blindly calling rs6000_gdbarch_init used to work in older versions of
     GDB, as rs6000_gdbarch_init incorrectly used the previous tdep to
     determine the wordsize.  */
  if (current_program_space->exec_bfd ())
    {
      const struct bfd_arch_info *exec_bfd_arch_info;

      exec_bfd_arch_info
	= bfd_get_arch_info (current_program_space->exec_bfd ());
      if (arch == exec_bfd_arch_info->arch)
	return;
    }

  bfd_default_set_arch_mach (&abfd, arch, mach);

  gdbarch_info info;
  info.bfd_arch_info = bfd_get_arch_info (&abfd);
  info.abfd = current_program_space->exec_bfd ();

  if (!gdbarch_update_p (current_inferior (), info))
    internal_error (_("rs6000_create_inferior: failed "
		      "to select architecture"));
}


/* Shared Object support.  */

/* Return the LdInfo data for the given process.  Raises an error
   if the data could not be obtained.  */

static gdb::byte_vector
rs6000_ptrace_ldinfo (ptid_t ptid)
{
  const int pid = ptid.pid ();
  gdb::byte_vector ldi (1024);
  int rc = -1;

  while (1)
    {
      if (ARCH64 ())
	rc = rs6000_ptrace64 (PT_LDINFO, pid, (unsigned long) ldi.data (),
			      ldi.size (), NULL);
      else
	rc = rs6000_ptrace32 (PT_LDINFO, pid, (int *) ldi.data (),
			      ldi.size (), NULL);

      if (rc != -1)
	break; /* Success, we got the entire ld_info data.  */

      if (errno != ENOMEM)
	perror_with_name (_("ptrace ldinfo"));

      /* ldi is not big enough.  Double it and try again.  */
      ldi.resize (ldi.size () * 2);
    }

  return ldi;
}

/* Implement the to_xfer_partial target_ops method for
   TARGET_OBJECT_LIBRARIES_AIX objects.  */

enum target_xfer_status
rs6000_nat_target::xfer_shared_libraries
  (enum target_object object,
   const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf,
   ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
{
  ULONGEST result;

  /* This function assumes that it is being run with a live process.
     Core files are handled via gdbarch.  */
  gdb_assert (target_has_execution ());

  if (writebuf)
    return TARGET_XFER_E_IO;

  gdb::byte_vector ldi_buf = rs6000_ptrace_ldinfo (inferior_ptid);
  result = rs6000_aix_ld_info_to_xml (current_inferior ()->arch (),
				      ldi_buf.data (),
				      readbuf, offset, len, 1);

  if (result == 0)
    return TARGET_XFER_EOF;
  else
    {
      *xfered_len = result;
      return TARGET_XFER_OK;
    }
}

void _initialize_rs6000_nat ();
void
_initialize_rs6000_nat ()
{
  add_inf_child_target (&the_rs6000_nat_target);
}
