/* Native support code for PPC AIX, for GDB the GNU debugger.

   Copyright (C) 2006-2022 Free Software Foundation, Inc.

   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 "osabi.h"
#include "regcache.h"
#include "regset.h"
#include "gdbtypes.h"
#include "gdbcore.h"
#include "target.h"
#include "value.h"
#include "infcall.h"
#include "objfiles.h"
#include "breakpoint.h"
#include "ppc-tdep.h"
#include "rs6000-aix-tdep.h"
#include "xcoffread.h"
#include "solib.h"
#include "solib-aix.h"
#include "target-float.h"
#include "gdbsupport/xml-utils.h"
#include "trad-frame.h"
#include "frame-unwind.h"

/* If the kernel has to deliver a signal, it pushes a sigcontext
   structure on the stack and then calls the signal handler, passing
   the address of the sigcontext in an argument register.  Usually
   the signal handler doesn't save this register, so we have to
   access the sigcontext structure via an offset from the signal handler
   frame.
   The following constants were determined by experimentation on AIX 3.2.

   sigcontext structure have the mstsave saved under the
   sc_jmpbuf.jmp_context. STKMIN(minimum stack size) is 56 for 32-bit
   processes, and iar offset under sc_jmpbuf.jmp_context is 40.
   ie offsetof(struct sigcontext, sc_jmpbuf.jmp_context.iar).
   so PC offset in this case is STKMIN+iar offset, which is 96. */

#define SIG_FRAME_PC_OFFSET 96
#define SIG_FRAME_LR_OFFSET 108
/* STKMIN+grp1 offset, which is 56+228=284 */
#define SIG_FRAME_FP_OFFSET 284

/* 64 bit process.
   STKMIN64  is 112 and iar offset is 312. So 112+312=424 */
#define SIG_FRAME_LR_OFFSET64 424
/* STKMIN64+grp1 offset. 112+56=168 */
#define SIG_FRAME_FP_OFFSET64 168

/* Minimum possible text address in AIX.  */
#define AIX_TEXT_SEGMENT_BASE 0x10000000

static struct trad_frame_cache *
aix_sighandle_frame_cache (struct frame_info *this_frame,
			   void **this_cache)
{
  LONGEST backchain;
  CORE_ADDR base, base_orig, func;
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct trad_frame_cache *this_trad_cache;

  if ((*this_cache) != NULL)
    return (struct trad_frame_cache *) (*this_cache);

  this_trad_cache = trad_frame_cache_zalloc (this_frame);
  (*this_cache) = this_trad_cache;

  base = get_frame_register_unsigned (this_frame,
				      gdbarch_sp_regnum (gdbarch));
  base_orig = base;

  if (tdep->wordsize == 4)
    {
      func = read_memory_unsigned_integer (base_orig +
					   SIG_FRAME_PC_OFFSET + 8,
					   tdep->wordsize, byte_order);
      safe_read_memory_integer (base_orig + SIG_FRAME_FP_OFFSET + 8,
				tdep->wordsize, byte_order, &backchain);
      base = (CORE_ADDR)backchain;
    }
  else
    {
      func = read_memory_unsigned_integer (base_orig +
					   SIG_FRAME_LR_OFFSET64,
					   tdep->wordsize, byte_order);
      safe_read_memory_integer (base_orig + SIG_FRAME_FP_OFFSET64,
				tdep->wordsize, byte_order, &backchain);
      base = (CORE_ADDR)backchain;
    }

  trad_frame_set_reg_value (this_trad_cache, gdbarch_pc_regnum (gdbarch), func);
  trad_frame_set_reg_value (this_trad_cache, gdbarch_sp_regnum (gdbarch), base);

  if (tdep->wordsize == 4)
    trad_frame_set_reg_addr (this_trad_cache, tdep->ppc_lr_regnum,
			     base_orig + 0x38 + 52 + 8);
  else
    trad_frame_set_reg_addr (this_trad_cache, tdep->ppc_lr_regnum,
			     base_orig + 0x70 + 320);

  trad_frame_set_id (this_trad_cache, frame_id_build (base, func));
  trad_frame_set_this_base (this_trad_cache, base);

  return this_trad_cache;
}

static void
aix_sighandle_frame_this_id (struct frame_info *this_frame,
			     void **this_prologue_cache,
			     struct frame_id *this_id)
{
  struct trad_frame_cache *this_trad_cache
    = aix_sighandle_frame_cache (this_frame, this_prologue_cache);
  trad_frame_get_id (this_trad_cache, this_id);
}

static struct value *
aix_sighandle_frame_prev_register (struct frame_info *this_frame,
				   void **this_prologue_cache, int regnum)
{
  struct trad_frame_cache *this_trad_cache
    = aix_sighandle_frame_cache (this_frame, this_prologue_cache);
  return trad_frame_get_register (this_trad_cache, this_frame, regnum);
}

static int
aix_sighandle_frame_sniffer (const struct frame_unwind *self,
			     struct frame_info *this_frame,
			     void **this_prologue_cache)
{
  CORE_ADDR pc = get_frame_pc (this_frame);
  if (pc && pc < AIX_TEXT_SEGMENT_BASE)
    return 1;

  return 0;
}

/* AIX signal handler frame unwinder */

static const struct frame_unwind aix_sighandle_frame_unwind = {
  "rs6000 aix sighandle",
  SIGTRAMP_FRAME,
  default_frame_unwind_stop_reason,
  aix_sighandle_frame_this_id,
  aix_sighandle_frame_prev_register,
  NULL,
  aix_sighandle_frame_sniffer
};

/* Core file support.  */

static struct ppc_reg_offsets rs6000_aix32_reg_offsets =
{
  /* General-purpose registers.  */
  208, /* r0_offset */
  4,  /* gpr_size */
  4,  /* xr_size */
  24, /* pc_offset */
  28, /* ps_offset */
  32, /* cr_offset */
  36, /* lr_offset */
  40, /* ctr_offset */
  44, /* xer_offset */
  48, /* mq_offset */

  /* Floating-point registers.  */
  336, /* f0_offset */
  56, /* fpscr_offset */
  4  /* fpscr_size */
};

static struct ppc_reg_offsets rs6000_aix64_reg_offsets =
{
  /* General-purpose registers.  */
  0, /* r0_offset */
  8,  /* gpr_size */
  4,  /* xr_size */
  264, /* pc_offset */
  256, /* ps_offset */
  288, /* cr_offset */
  272, /* lr_offset */
  280, /* ctr_offset */
  292, /* xer_offset */
  -1, /* mq_offset */

  /* Floating-point registers.  */
  312, /* f0_offset */
  296, /* fpscr_offset */
  4  /* fpscr_size */
};


/* Supply register REGNUM in the general-purpose register set REGSET
   from the buffer specified by GREGS and LEN to register cache
   REGCACHE.  If REGNUM is -1, do this for all registers in REGSET.  */

static void
rs6000_aix_supply_regset (const struct regset *regset,
			  struct regcache *regcache, int regnum,
			  const void *gregs, size_t len)
{
  ppc_supply_gregset (regset, regcache, regnum, gregs, len);
  ppc_supply_fpregset (regset, regcache, regnum, gregs, len);
}

/* Collect register REGNUM in the general-purpose register set
   REGSET, from register cache REGCACHE into the buffer specified by
   GREGS and LEN.  If REGNUM is -1, do this for all registers in
   REGSET.  */

static void
rs6000_aix_collect_regset (const struct regset *regset,
			   const struct regcache *regcache, int regnum,
			   void *gregs, size_t len)
{
  ppc_collect_gregset (regset, regcache, regnum, gregs, len);
  ppc_collect_fpregset (regset, regcache, regnum, gregs, len);
}

/* AIX register set.  */

static const struct regset rs6000_aix32_regset =
{
  &rs6000_aix32_reg_offsets,
  rs6000_aix_supply_regset,
  rs6000_aix_collect_regset,
};

static const struct regset rs6000_aix64_regset =
{
  &rs6000_aix64_reg_offsets,
  rs6000_aix_supply_regset,
  rs6000_aix_collect_regset,
};

/* Iterate over core file register note sections.  */

static void
rs6000_aix_iterate_over_regset_sections (struct gdbarch *gdbarch,
					 iterate_over_regset_sections_cb *cb,
					 void *cb_data,
					 const struct regcache *regcache)
{
  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
  if (tdep->wordsize == 4)
    cb (".reg", 592, 592, &rs6000_aix32_regset, NULL, cb_data);
  else
    cb (".reg", 576, 576, &rs6000_aix64_regset, NULL, cb_data);
}


/* Pass the arguments in either registers, or in the stack.  In RS/6000,
   the first eight words of the argument list (that might be less than
   eight parameters if some parameters occupy more than one word) are
   passed in r3..r10 registers.  Float and double parameters are
   passed in fpr's, in addition to that.  Rest of the parameters if any
   are passed in user stack.  There might be cases in which half of the
   parameter is copied into registers, the other half is pushed into
   stack.

   Stack must be aligned on 64-bit boundaries when synthesizing
   function calls.

   If the function is returning a structure, then the return address is passed
   in r3, then the first 7 words of the parameters can be passed in registers,
   starting from r4.  */

static CORE_ADDR
rs6000_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
			struct regcache *regcache, CORE_ADDR bp_addr,
			int nargs, struct value **args, CORE_ADDR sp,
			function_call_return_method return_method,
			CORE_ADDR struct_addr)
{
  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  int ii;
  int len = 0;
  int argno;			/* current argument number */
  int argbytes;			/* current argument byte */
  gdb_byte tmp_buffer[50];
  int f_argno = 0;		/* current floating point argno */
  int wordsize = tdep->wordsize;
  CORE_ADDR func_addr = find_function_addr (function, NULL);

  struct value *arg = 0;
  struct type *type;

  ULONGEST saved_sp;

  /* The calling convention this function implements assumes the
     processor has floating-point registers.  We shouldn't be using it
     on PPC variants that lack them.  */
  gdb_assert (ppc_floating_point_unit_p (gdbarch));

  /* The first eight words of ther arguments are passed in registers.
     Copy them appropriately.  */
  ii = 0;

  /* If the function is returning a `struct', then the first word
     (which will be passed in r3) is used for struct return address.
     In that case we should advance one word and start from r4
     register to copy parameters.  */
  if (return_method == return_method_struct)
    {
      regcache_raw_write_unsigned (regcache, tdep->ppc_gp0_regnum + 3,
				   struct_addr);
      ii++;
    }

/* effectively indirect call... gcc does...

   return_val example( float, int);

   eabi: 
   float in fp0, int in r3
   offset of stack on overflow 8/16
   for varargs, must go by type.
   power open:
   float in r3&r4, int in r5
   offset of stack on overflow different 
   both: 
   return in r3 or f0.  If no float, must study how gcc emulates floats;
   pay attention to arg promotion.
   User may have to cast\args to handle promotion correctly 
   since gdb won't know if prototype supplied or not.  */

  for (argno = 0, argbytes = 0; argno < nargs && ii < 8; ++ii)
    {
      int reg_size = register_size (gdbarch, ii + 3);

      arg = args[argno];
      type = check_typedef (value_type (arg));
      len = TYPE_LENGTH (type);

      if (type->code () == TYPE_CODE_FLT)
	{
	  /* Floating point arguments are passed in fpr's, as well as gpr's.
	     There are 13 fpr's reserved for passing parameters.  At this point
	     there is no way we would run out of them.

	     Always store the floating point value using the register's
	     floating-point format.  */
	  const int fp_regnum = tdep->ppc_fp0_regnum + 1 + f_argno;
	  gdb_byte reg_val[PPC_MAX_REGISTER_SIZE];
	  struct type *reg_type = register_type (gdbarch, fp_regnum);

	  gdb_assert (len <= 8);

	  target_float_convert (value_contents (arg).data (), type, reg_val,
				reg_type);
	  regcache->cooked_write (fp_regnum, reg_val);
	  ++f_argno;
	}

      if (len > reg_size)
	{

	  /* Argument takes more than one register.  */
	  while (argbytes < len)
	    {
	      gdb_byte word[PPC_MAX_REGISTER_SIZE];
	      memset (word, 0, reg_size);
	      memcpy (word,
		      ((char *) value_contents (arg).data ()) + argbytes,
		      (len - argbytes) > reg_size
			? reg_size : len - argbytes);
	      regcache->cooked_write (tdep->ppc_gp0_regnum + 3 + ii, word);
	      ++ii, argbytes += reg_size;

	      if (ii >= 8)
		goto ran_out_of_registers_for_arguments;
	    }
	  argbytes = 0;
	  --ii;
	}
      else
	{
	  /* Argument can fit in one register.  No problem.  */
	  gdb_byte word[PPC_MAX_REGISTER_SIZE];

	  memset (word, 0, reg_size);
	  memcpy (word, value_contents (arg).data (), len);
	  regcache->cooked_write (tdep->ppc_gp0_regnum + 3 +ii, word);
	}
      ++argno;
    }

ran_out_of_registers_for_arguments:

  regcache_cooked_read_unsigned (regcache,
				 gdbarch_sp_regnum (gdbarch),
				 &saved_sp);

  /* Location for 8 parameters are always reserved.  */
  sp -= wordsize * 8;

  /* Another six words for back chain, TOC register, link register, etc.  */
  sp -= wordsize * 6;

  /* Stack pointer must be quadword aligned.  */
  sp &= -16;

  /* If there are more arguments, allocate space for them in 
     the stack, then push them starting from the ninth one.  */

  if ((argno < nargs) || argbytes)
    {
      int space = 0, jj;

      if (argbytes)
	{
	  space += ((len - argbytes + 3) & -4);
	  jj = argno + 1;
	}
      else
	jj = argno;

      for (; jj < nargs; ++jj)
	{
	  struct value *val = args[jj];
	  space += ((TYPE_LENGTH (value_type (val))) + 3) & -4;
	}

      /* Add location required for the rest of the parameters.  */
      space = (space + 15) & -16;
      sp -= space;

      /* This is another instance we need to be concerned about
	 securing our stack space.  If we write anything underneath %sp
	 (r1), we might conflict with the kernel who thinks he is free
	 to use this area.  So, update %sp first before doing anything
	 else.  */

      regcache_raw_write_signed (regcache,
				 gdbarch_sp_regnum (gdbarch), sp);

      /* If the last argument copied into the registers didn't fit there 
	 completely, push the rest of it into stack.  */

      if (argbytes)
	{
	  write_memory (sp + 24 + (ii * 4),
			value_contents (arg).data () + argbytes,
			len - argbytes);
	  ++argno;
	  ii += ((len - argbytes + 3) & -4) / 4;
	}

      /* Push the rest of the arguments into stack.  */
      for (; argno < nargs; ++argno)
	{

	  arg = args[argno];
	  type = check_typedef (value_type (arg));
	  len = TYPE_LENGTH (type);


	  /* Float types should be passed in fpr's, as well as in the
	     stack.  */
	  if (type->code () == TYPE_CODE_FLT && f_argno < 13)
	    {

	      gdb_assert (len <= 8);

	      regcache->cooked_write (tdep->ppc_fp0_regnum + 1 + f_argno,
				      value_contents (arg).data ());
	      ++f_argno;
	    }

	  write_memory (sp + 24 + (ii * 4), value_contents (arg).data (), len);
	  ii += ((len + 3) & -4) / 4;
	}
    }

  /* Set the stack pointer.  According to the ABI, the SP is meant to
     be set _before_ the corresponding stack space is used.  On AIX,
     this even applies when the target has been completely stopped!
     Not doing this can lead to conflicts with the kernel which thinks
     that it still has control over this not-yet-allocated stack
     region.  */
  regcache_raw_write_signed (regcache, gdbarch_sp_regnum (gdbarch), sp);

  /* Set back chain properly.  */
  store_unsigned_integer (tmp_buffer, wordsize, byte_order, saved_sp);
  write_memory (sp, tmp_buffer, wordsize);

  /* Point the inferior function call's return address at the dummy's
     breakpoint.  */
  regcache_raw_write_signed (regcache, tdep->ppc_lr_regnum, bp_addr);

  /* Set the TOC register value.  */
  regcache_raw_write_signed (regcache, tdep->ppc_toc_regnum,
			     solib_aix_get_toc_value (func_addr));

  target_store_registers (regcache, -1);
  return sp;
}

static enum return_value_convention
rs6000_return_value (struct gdbarch *gdbarch, struct value *function,
		     struct type *valtype, struct regcache *regcache,
		     gdb_byte *readbuf, const gdb_byte *writebuf)
{
  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  /* The calling convention this function implements assumes the
     processor has floating-point registers.  We shouldn't be using it
     on PowerPC variants that lack them.  */
  gdb_assert (ppc_floating_point_unit_p (gdbarch));

  /* AltiVec extension: Functions that declare a vector data type as a
     return value place that return value in VR2.  */
  if (valtype->code () == TYPE_CODE_ARRAY && valtype->is_vector ()
      && TYPE_LENGTH (valtype) == 16)
    {
      if (readbuf)
	regcache->cooked_read (tdep->ppc_vr0_regnum + 2, readbuf);
      if (writebuf)
	regcache->cooked_write (tdep->ppc_vr0_regnum + 2, writebuf);

      return RETURN_VALUE_REGISTER_CONVENTION;
    }

  /* If the called subprogram returns an aggregate, there exists an
     implicit first argument, whose value is the address of a caller-
     allocated buffer into which the callee is assumed to store its
     return value.  All explicit parameters are appropriately
     relabeled.  */
  if (valtype->code () == TYPE_CODE_STRUCT
      || valtype->code () == TYPE_CODE_UNION
      || valtype->code () == TYPE_CODE_ARRAY)
    return RETURN_VALUE_STRUCT_CONVENTION;

  /* Scalar floating-point values are returned in FPR1 for float or
     double, and in FPR1:FPR2 for quadword precision.  Fortran
     complex*8 and complex*16 are returned in FPR1:FPR2, and
     complex*32 is returned in FPR1:FPR4.  */
  if (valtype->code () == TYPE_CODE_FLT
      && (TYPE_LENGTH (valtype) == 4 || TYPE_LENGTH (valtype) == 8))
    {
      struct type *regtype = register_type (gdbarch, tdep->ppc_fp0_regnum);
      gdb_byte regval[8];

      /* FIXME: kettenis/2007-01-01: Add support for quadword
	 precision and complex.  */

      if (readbuf)
	{
	  regcache->cooked_read (tdep->ppc_fp0_regnum + 1, regval);
	  target_float_convert (regval, regtype, readbuf, valtype);
	}
      if (writebuf)
	{
	  target_float_convert (writebuf, valtype, regval, regtype);
	  regcache->cooked_write (tdep->ppc_fp0_regnum + 1, regval);
	}

      return RETURN_VALUE_REGISTER_CONVENTION;
  }

  /* Values of the types int, long, short, pointer, and char (length
     is less than or equal to four bytes), as well as bit values of
     lengths less than or equal to 32 bits, must be returned right
     justified in GPR3 with signed values sign extended and unsigned
     values zero extended, as necessary.  */
  if (TYPE_LENGTH (valtype) <= tdep->wordsize)
    {
      if (readbuf)
	{
	  ULONGEST regval;

	  /* For reading we don't have to worry about sign extension.  */
	  regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum + 3,
					 &regval);
	  store_unsigned_integer (readbuf, TYPE_LENGTH (valtype), byte_order,
				  regval);
	}
      if (writebuf)
	{
	  /* For writing, use unpack_long since that should handle any
	     required sign extension.  */
	  regcache_cooked_write_unsigned (regcache, tdep->ppc_gp0_regnum + 3,
					  unpack_long (valtype, writebuf));
	}

      return RETURN_VALUE_REGISTER_CONVENTION;
    }

  /* Eight-byte non-floating-point scalar values must be returned in
     GPR3:GPR4.  */

  if (TYPE_LENGTH (valtype) == 8)
    {
      gdb_assert (valtype->code () != TYPE_CODE_FLT);
      gdb_assert (tdep->wordsize == 4);

      if (readbuf)
	{
	  gdb_byte regval[8];

	  regcache->cooked_read (tdep->ppc_gp0_regnum + 3, regval);
	  regcache->cooked_read (tdep->ppc_gp0_regnum + 4, regval + 4);
	  memcpy (readbuf, regval, 8);
	}
      if (writebuf)
	{
	  regcache->cooked_write (tdep->ppc_gp0_regnum + 3, writebuf);
	  regcache->cooked_write (tdep->ppc_gp0_regnum + 4, writebuf + 4);
	}

      return RETURN_VALUE_REGISTER_CONVENTION;
    }

  return RETURN_VALUE_STRUCT_CONVENTION;
}

/* Support for CONVERT_FROM_FUNC_PTR_ADDR (ARCH, ADDR, TARG).

   Usually a function pointer's representation is simply the address
   of the function.  On the RS/6000 however, a function pointer is
   represented by a pointer to an OPD entry.  This OPD entry contains
   three words, the first word is the address of the function, the
   second word is the TOC pointer (r2), and the third word is the
   static chain value.  Throughout GDB it is currently assumed that a
   function pointer contains the address of the function, which is not
   easy to fix.  In addition, the conversion of a function address to
   a function pointer would require allocation of an OPD entry in the
   inferior's memory space, with all its drawbacks.  To be able to
   call C++ virtual methods in the inferior (which are called via
   function pointers), find_function_addr uses this function to get the
   function address from a function pointer.  */

/* Return real function address if ADDR (a function pointer) is in the data
   space and is therefore a special function pointer.  */

static CORE_ADDR
rs6000_convert_from_func_ptr_addr (struct gdbarch *gdbarch,
				   CORE_ADDR addr,
				   struct target_ops *targ)
{
  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct obj_section *s;

  s = find_pc_section (addr);

  /* Normally, functions live inside a section that is executable.
     So, if ADDR points to a non-executable section, then treat it
     as a function descriptor and return the target address iff
     the target address itself points to a section that is executable.  */
  if (s && (s->the_bfd_section->flags & SEC_CODE) == 0)
    {
      CORE_ADDR pc = 0;
      struct obj_section *pc_section;

      try
	{
	  pc = read_memory_unsigned_integer (addr, tdep->wordsize, byte_order);
	}
      catch (const gdb_exception_error &e)
	{
	  /* An error occured during reading.  Probably a memory error
	     due to the section not being loaded yet.  This address
	     cannot be a function descriptor.  */
	  return addr;
	}

      pc_section = find_pc_section (pc);

      if (pc_section && (pc_section->the_bfd_section->flags & SEC_CODE))
	return pc;
    }

  return addr;
}


/* Calculate the destination of a branch/jump.  Return -1 if not a branch.  */

static CORE_ADDR
branch_dest (struct regcache *regcache, int opcode, int instr,
	     CORE_ADDR pc, CORE_ADDR safety)
{
  struct gdbarch *gdbarch = regcache->arch ();
  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR dest;
  int immediate;
  int absolute;
  int ext_op;

  absolute = (int) ((instr >> 1) & 1);

  switch (opcode)
    {
    case 18:
      immediate = ((instr & ~3) << 6) >> 6;	/* br unconditional */
      if (absolute)
	dest = immediate;
      else
	dest = pc + immediate;
      break;

    case 16:
      immediate = ((instr & ~3) << 16) >> 16;	/* br conditional */
      if (absolute)
	dest = immediate;
      else
	dest = pc + immediate;
      break;

    case 19:
      ext_op = (instr >> 1) & 0x3ff;

      if (ext_op == 16)		/* br conditional register */
	{
	  dest = regcache_raw_get_unsigned (regcache, tdep->ppc_lr_regnum) & ~3;

	  /* If we are about to return from a signal handler, dest is
	     something like 0x3c90.  The current frame is a signal handler
	     caller frame, upon completion of the sigreturn system call
	     execution will return to the saved PC in the frame.  */
	  if (dest < AIX_TEXT_SEGMENT_BASE)
	    {
	      struct frame_info *frame = get_current_frame ();

	      dest = read_memory_unsigned_integer
		(get_frame_base (frame) + SIG_FRAME_PC_OFFSET,
		 tdep->wordsize, byte_order);
	    }
	}

      else if (ext_op == 528)	/* br cond to count reg */
	{
	  dest = regcache_raw_get_unsigned (regcache,
					    tdep->ppc_ctr_regnum) & ~3;

	  /* If we are about to execute a system call, dest is something
	     like 0x22fc or 0x3b00.  Upon completion the system call
	     will return to the address in the link register.  */
	  if (dest < AIX_TEXT_SEGMENT_BASE)
	    dest = regcache_raw_get_unsigned (regcache,
					      tdep->ppc_lr_regnum) & ~3;
	}
      else
	return -1;
      break;

    default:
      return -1;
    }
  return (dest < AIX_TEXT_SEGMENT_BASE) ? safety : dest;
}

/* AIX does not support PT_STEP.  Simulate it.  */

static std::vector<CORE_ADDR>
rs6000_software_single_step (struct regcache *regcache)
{
  struct gdbarch *gdbarch = regcache->arch ();
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  int ii, insn;
  CORE_ADDR loc;
  CORE_ADDR breaks[2];
  int opcode;

  loc = regcache_read_pc (regcache);

  insn = read_memory_integer (loc, 4, byte_order);

  std::vector<CORE_ADDR> next_pcs = ppc_deal_with_atomic_sequence (regcache);
  if (!next_pcs.empty ())
    return next_pcs;
  
  breaks[0] = loc + PPC_INSN_SIZE;
  opcode = insn >> 26;
  breaks[1] = branch_dest (regcache, opcode, insn, loc, breaks[0]);

  /* Don't put two breakpoints on the same address.  */
  if (breaks[1] == breaks[0])
    breaks[1] = -1;

  for (ii = 0; ii < 2; ++ii)
    {
      /* ignore invalid breakpoint.  */
      if (breaks[ii] == -1)
	continue;

      next_pcs.push_back (breaks[ii]);
    }

  errno = 0;			/* FIXME, don't ignore errors!  */
  /* What errors?  {read,write}_memory call error().  */
  return next_pcs;
}

/* Implement the "auto_wide_charset" gdbarch method for this platform.  */

static const char *
rs6000_aix_auto_wide_charset (void)
{
  return "UTF-16";
}

/* Implement an osabi sniffer for RS6000/AIX.

   This function assumes that ABFD's flavour is XCOFF.  In other words,
   it should be registered as a sniffer for bfd_target_xcoff_flavour
   objfiles only.  A failed assertion will be raised if this condition
   is not met.  */

static enum gdb_osabi
rs6000_aix_osabi_sniffer (bfd *abfd)
{
  gdb_assert (bfd_get_flavour (abfd) == bfd_target_xcoff_flavour);

  /* The only noticeable difference between Lynx178 XCOFF files and
     AIX XCOFF files comes from the fact that there are no shared
     libraries on Lynx178.  On AIX, we are betting that an executable
     linked with no shared library will never exist.  */
  if (xcoff_get_n_import_files (abfd) <= 0)
    return GDB_OSABI_UNKNOWN;

  return GDB_OSABI_AIX;
}

/* A structure encoding the offset and size of a field within
   a struct.  */

struct field_info
{
  int offset;
  int size;
};

/* A structure describing the layout of all the fields of interest
   in AIX's struct ld_info.  Each field in this struct corresponds
   to the field of the same name in struct ld_info.  */

struct ld_info_desc
{
  struct field_info ldinfo_next;
  struct field_info ldinfo_fd;
  struct field_info ldinfo_textorg;
  struct field_info ldinfo_textsize;
  struct field_info ldinfo_dataorg;
  struct field_info ldinfo_datasize;
  struct field_info ldinfo_filename;
};

/* The following data has been generated by compiling and running
   the following program on AIX 5.3.  */

#if 0
#include <stddef.h>
#include <stdio.h>
#define __LDINFO_PTRACE32__
#define __LDINFO_PTRACE64__
#include <sys/ldr.h>

#define pinfo(type,member)                  \
  {                                         \
    struct type ldi = {0};                  \
					    \
    printf ("  {%d, %d},\t/* %s */\n",      \
	    offsetof (struct type, member), \
	    sizeof (ldi.member),            \
	    #member);                       \
  }                                         \
  while (0)

int
main (void)
{
  printf ("static const struct ld_info_desc ld_info32_desc =\n{\n");
  pinfo (__ld_info32, ldinfo_next);
  pinfo (__ld_info32, ldinfo_fd);
  pinfo (__ld_info32, ldinfo_textorg);
  pinfo (__ld_info32, ldinfo_textsize);
  pinfo (__ld_info32, ldinfo_dataorg);
  pinfo (__ld_info32, ldinfo_datasize);
  pinfo (__ld_info32, ldinfo_filename);
  printf ("};\n");

  printf ("\n");

  printf ("static const struct ld_info_desc ld_info64_desc =\n{\n");
  pinfo (__ld_info64, ldinfo_next);
  pinfo (__ld_info64, ldinfo_fd);
  pinfo (__ld_info64, ldinfo_textorg);
  pinfo (__ld_info64, ldinfo_textsize);
  pinfo (__ld_info64, ldinfo_dataorg);
  pinfo (__ld_info64, ldinfo_datasize);
  pinfo (__ld_info64, ldinfo_filename);
  printf ("};\n");

  return 0;
}
#endif /* 0 */

/* Layout of the 32bit version of struct ld_info.  */

static const struct ld_info_desc ld_info32_desc =
{
  {0, 4},       /* ldinfo_next */
  {4, 4},       /* ldinfo_fd */
  {8, 4},       /* ldinfo_textorg */
  {12, 4},      /* ldinfo_textsize */
  {16, 4},      /* ldinfo_dataorg */
  {20, 4},      /* ldinfo_datasize */
  {24, 2},      /* ldinfo_filename */
};

/* Layout of the 64bit version of struct ld_info.  */

static const struct ld_info_desc ld_info64_desc =
{
  {0, 4},       /* ldinfo_next */
  {8, 4},       /* ldinfo_fd */
  {16, 8},      /* ldinfo_textorg */
  {24, 8},      /* ldinfo_textsize */
  {32, 8},      /* ldinfo_dataorg */
  {40, 8},      /* ldinfo_datasize */
  {48, 2},      /* ldinfo_filename */
};

/* A structured representation of one entry read from the ld_info
   binary data provided by the AIX loader.  */

struct ld_info
{
  ULONGEST next;
  int fd;
  CORE_ADDR textorg;
  ULONGEST textsize;
  CORE_ADDR dataorg;
  ULONGEST datasize;
  char *filename;
  char *member_name;
};

/* Return a struct ld_info object corresponding to the entry at
   LDI_BUF.

   Note that the filename and member_name strings still point
   to the data in LDI_BUF.  So LDI_BUF must not be deallocated
   while the struct ld_info object returned is in use.  */

static struct ld_info
rs6000_aix_extract_ld_info (struct gdbarch *gdbarch,
			    const gdb_byte *ldi_buf)
{
  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
  const struct ld_info_desc desc
    = tdep->wordsize == 8 ? ld_info64_desc : ld_info32_desc;
  struct ld_info info;

  info.next = extract_unsigned_integer (ldi_buf + desc.ldinfo_next.offset,
					desc.ldinfo_next.size,
					byte_order);
  info.fd = extract_signed_integer (ldi_buf + desc.ldinfo_fd.offset,
				    desc.ldinfo_fd.size,
				    byte_order);
  info.textorg = extract_typed_address (ldi_buf + desc.ldinfo_textorg.offset,
					ptr_type);
  info.textsize
    = extract_unsigned_integer (ldi_buf + desc.ldinfo_textsize.offset,
				desc.ldinfo_textsize.size,
				byte_order);
  info.dataorg = extract_typed_address (ldi_buf + desc.ldinfo_dataorg.offset,
					ptr_type);
  info.datasize
    = extract_unsigned_integer (ldi_buf + desc.ldinfo_datasize.offset,
				desc.ldinfo_datasize.size,
				byte_order);
  info.filename = (char *) ldi_buf + desc.ldinfo_filename.offset;
  info.member_name = info.filename + strlen (info.filename) + 1;

  return info;
}

/* Append to OBJSTACK an XML string description of the shared library
   corresponding to LDI, following the TARGET_OBJECT_LIBRARIES_AIX
   format.  */

static void
rs6000_aix_shared_library_to_xml (struct ld_info *ldi,
				  struct obstack *obstack)
{
  obstack_grow_str (obstack, "<library name=\"");
  std::string p = xml_escape_text (ldi->filename);
  obstack_grow_str (obstack, p.c_str ());
  obstack_grow_str (obstack, "\"");

  if (ldi->member_name[0] != '\0')
    {
      obstack_grow_str (obstack, " member=\"");
      p = xml_escape_text (ldi->member_name);
      obstack_grow_str (obstack, p.c_str ());
      obstack_grow_str (obstack, "\"");
    }

  obstack_grow_str (obstack, " text_addr=\"");
  obstack_grow_str (obstack, core_addr_to_string (ldi->textorg));
  obstack_grow_str (obstack, "\"");

  obstack_grow_str (obstack, " text_size=\"");
  obstack_grow_str (obstack, pulongest (ldi->textsize));
  obstack_grow_str (obstack, "\"");

  obstack_grow_str (obstack, " data_addr=\"");
  obstack_grow_str (obstack, core_addr_to_string (ldi->dataorg));
  obstack_grow_str (obstack, "\"");

  obstack_grow_str (obstack, " data_size=\"");
  obstack_grow_str (obstack, pulongest (ldi->datasize));
  obstack_grow_str (obstack, "\"");

  obstack_grow_str (obstack, "></library>");
}

/* Convert the ld_info binary data provided by the AIX loader into
   an XML representation following the TARGET_OBJECT_LIBRARIES_AIX
   format.

   LDI_BUF is a buffer containing the ld_info data.
   READBUF, OFFSET and LEN follow the same semantics as target_ops'
   to_xfer_partial target_ops method.

   If CLOSE_LDINFO_FD is nonzero, then this routine also closes
   the ldinfo_fd file descriptor.  This is useful when the ldinfo
   data is obtained via ptrace, as ptrace opens a file descriptor
   for each and every entry; but we cannot use this descriptor
   as the consumer of the XML library list might live in a different
   process.  */

ULONGEST
rs6000_aix_ld_info_to_xml (struct gdbarch *gdbarch, const gdb_byte *ldi_buf,
			   gdb_byte *readbuf, ULONGEST offset, ULONGEST len,
			   int close_ldinfo_fd)
{
  struct obstack obstack;
  const char *buf;
  ULONGEST len_avail;

  obstack_init (&obstack);
  obstack_grow_str (&obstack, "<library-list-aix version=\"1.0\">\n");

  while (1)
    {
      struct ld_info ldi = rs6000_aix_extract_ld_info (gdbarch, ldi_buf);

      rs6000_aix_shared_library_to_xml (&ldi, &obstack);
      if (close_ldinfo_fd)
	close (ldi.fd);

      if (!ldi.next)
	break;
      ldi_buf = ldi_buf + ldi.next;
    }

  obstack_grow_str0 (&obstack, "</library-list-aix>\n");

  buf = (const char *) obstack_finish (&obstack);
  len_avail = strlen (buf);
  if (offset >= len_avail)
    len= 0;
  else
    {
      if (len > len_avail - offset)
	len = len_avail - offset;
      memcpy (readbuf, buf + offset, len);
    }

  obstack_free (&obstack, NULL);
  return len;
}

/* Implement the core_xfer_shared_libraries_aix gdbarch method.  */

static ULONGEST
rs6000_aix_core_xfer_shared_libraries_aix (struct gdbarch *gdbarch,
					   gdb_byte *readbuf,
					   ULONGEST offset,
					   ULONGEST len)
{
  struct bfd_section *ldinfo_sec;
  int ldinfo_size;

  ldinfo_sec = bfd_get_section_by_name (core_bfd, ".ldinfo");
  if (ldinfo_sec == NULL)
    error (_("cannot find .ldinfo section from core file: %s"),
	   bfd_errmsg (bfd_get_error ()));
  ldinfo_size = bfd_section_size (ldinfo_sec);

  gdb::byte_vector ldinfo_buf (ldinfo_size);

  if (! bfd_get_section_contents (core_bfd, ldinfo_sec,
				  ldinfo_buf.data (), 0, ldinfo_size))
    error (_("unable to read .ldinfo section from core file: %s"),
	  bfd_errmsg (bfd_get_error ()));

  return rs6000_aix_ld_info_to_xml (gdbarch, ldinfo_buf.data (), readbuf,
				    offset, len, 0);
}

static void
rs6000_aix_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  /* RS6000/AIX does not support PT_STEP.  Has to be simulated.  */
  set_gdbarch_software_single_step (gdbarch, rs6000_software_single_step);

  /* Displaced stepping is currently not supported in combination with
     software single-stepping.  These override the values set by
     rs6000_gdbarch_init.  */
  set_gdbarch_displaced_step_copy_insn (gdbarch, NULL);
  set_gdbarch_displaced_step_fixup (gdbarch, NULL);
  set_gdbarch_displaced_step_prepare (gdbarch, NULL);
  set_gdbarch_displaced_step_finish (gdbarch, NULL);

  set_gdbarch_push_dummy_call (gdbarch, rs6000_push_dummy_call);
  set_gdbarch_return_value (gdbarch, rs6000_return_value);
  set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);

  /* Handle RS/6000 function pointers (which are really function
     descriptors).  */
  set_gdbarch_convert_from_func_ptr_addr
    (gdbarch, rs6000_convert_from_func_ptr_addr);

  /* Core file support.  */
  set_gdbarch_iterate_over_regset_sections
    (gdbarch, rs6000_aix_iterate_over_regset_sections);
  set_gdbarch_core_xfer_shared_libraries_aix
    (gdbarch, rs6000_aix_core_xfer_shared_libraries_aix);

  if (tdep->wordsize == 8)
    tdep->lr_frame_offset = 16;
  else
    tdep->lr_frame_offset = 8;

  if (tdep->wordsize == 4)
    /* PowerOpen / AIX 32 bit.  The saved area or red zone consists of
       19 4 byte GPRS + 18 8 byte FPRs giving a total of 220 bytes.
       Problem is, 220 isn't frame (16 byte) aligned.  Round it up to
       224.  */
    set_gdbarch_frame_red_zone_size (gdbarch, 224);
  else
    set_gdbarch_frame_red_zone_size (gdbarch, 0);

  if (tdep->wordsize == 8)
    set_gdbarch_wchar_bit (gdbarch, 32);
  else
    set_gdbarch_wchar_bit (gdbarch, 16);
  set_gdbarch_wchar_signed (gdbarch, 0);
  set_gdbarch_auto_wide_charset (gdbarch, rs6000_aix_auto_wide_charset);

  set_solib_ops (gdbarch, &solib_aix_so_ops);
  frame_unwind_append_unwinder (gdbarch, &aix_sighandle_frame_unwind);
}

void _initialize_rs6000_aix_tdep ();
void
_initialize_rs6000_aix_tdep ()
{
  gdbarch_register_osabi_sniffer (bfd_arch_rs6000,
				  bfd_target_xcoff_flavour,
				  rs6000_aix_osabi_sniffer);
  gdbarch_register_osabi_sniffer (bfd_arch_powerpc,
				  bfd_target_xcoff_flavour,
				  rs6000_aix_osabi_sniffer);

  gdbarch_register_osabi (bfd_arch_rs6000, 0, GDB_OSABI_AIX,
			  rs6000_aix_init_osabi);
  gdbarch_register_osabi (bfd_arch_powerpc, 0, GDB_OSABI_AIX,
			  rs6000_aix_init_osabi);
}

