/* Target-dependent code for GNU/Linux running on PA-RISC, for GDB.

   Copyright (C) 2004-2021 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 "gdbcore.h"
#include "osabi.h"
#include "target.h"
#include "objfiles.h"
#include "solib-svr4.h"
#include "glibc-tdep.h"
#include "frame-unwind.h"
#include "trad-frame.h"
#include "dwarf2/frame.h"
#include "value.h"
#include "regset.h"
#include "regcache.h"
#include "hppa-tdep.h"
#include "linux-tdep.h"
#include "elf/common.h"

/* Map DWARF DBX register numbers to GDB register numbers.  */
static int
hppa_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
{
  /* The general registers and the sar are the same in both sets.  */
  if (reg >= 0 && reg <= 32)
    return reg;

  /* fr4-fr31 (left and right halves) are mapped from 72.  */
  if (reg >= 72 && reg <= 72 + 28 * 2)
    return HPPA_FP4_REGNUM + (reg - 72);

  return -1;
}

static void
hppa_linux_target_write_pc (struct regcache *regcache, CORE_ADDR v)
{
  /* Probably this should be done by the kernel, but it isn't.  */
  regcache_cooked_write_unsigned (regcache, HPPA_PCOQ_HEAD_REGNUM, v | 0x3);
  regcache_cooked_write_unsigned (regcache,
				  HPPA_PCOQ_TAIL_REGNUM, (v + 4) | 0x3);
}

/* An instruction to match.  */
struct insn_pattern
{
  unsigned int data;            /* See if it matches this....  */
  unsigned int mask;            /* ... with this mask.  */
};

static struct insn_pattern hppa_sigtramp[] = {
  /* ldi 0, %r25 or ldi 1, %r25 */
  { 0x34190000, 0xfffffffd },
  /* ldi __NR_rt_sigreturn, %r20 */
  { 0x3414015a, 0xffffffff },
  /* be,l 0x100(%sr2, %r0), %sr0, %r31 */
  { 0xe4008200, 0xffffffff },
  /* nop */
  { 0x08000240, 0xffffffff },
  { 0, 0 }
};

#define HPPA_MAX_INSN_PATTERN_LEN (4)

/* Return non-zero if the instructions at PC match the series
   described in PATTERN, or zero otherwise.  PATTERN is an array of
   'struct insn_pattern' objects, terminated by an entry whose mask is
   zero.

   When the match is successful, fill INSN[i] with what PATTERN[i]
   matched.  */
static int
insns_match_pattern (struct gdbarch *gdbarch, CORE_ADDR pc,
		     struct insn_pattern *pattern,
		     unsigned int *insn)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  int i;
  CORE_ADDR npc = pc;

  for (i = 0; pattern[i].mask; i++)
    {
      gdb_byte buf[4];

      target_read_memory (npc, buf, 4);
      insn[i] = extract_unsigned_integer (buf, 4, byte_order);
      if ((insn[i] & pattern[i].mask) == pattern[i].data)
	npc += 4;
      else
	return 0;
    }
  return 1;
}

/* Signal frames.  */

/* (This is derived from MD_FALLBACK_FRAME_STATE_FOR in gcc.)
 
   Unfortunately, because of various bugs and changes to the kernel,
   we have several cases to deal with.

   In 2.4, the signal trampoline is 4 bytes, and pc should point directly at 
   the beginning of the trampoline and struct rt_sigframe.

   In <= 2.6.5-rc2-pa3, the signal trampoline is 9 bytes, and pc points at
   the 4th word in the trampoline structure.  This is wrong, it should point 
   at the 5th word.  This is fixed in 2.6.5-rc2-pa4.

   To detect these cases, we first take pc, align it to 64-bytes
   to get the beginning of the signal frame, and then check offsets 0, 4
   and 5 to see if we found the beginning of the trampoline.  This will
   tell us how to locate the sigcontext structure.

   Note that with a 2.4 64-bit kernel, the signal context is not properly
   passed back to userspace so the unwind will not work correctly.  */
static CORE_ADDR
hppa_linux_sigtramp_find_sigcontext (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  unsigned int dummy[HPPA_MAX_INSN_PATTERN_LEN];
  int offs = 0;
  int attempt;
  /* offsets to try to find the trampoline */
  static int pcoffs[] = { 0, 4*4, 5*4 };
  /* offsets to the rt_sigframe structure */
  static int sfoffs[] = { 4*4, 10*4, 10*4 };
  CORE_ADDR sp;

  /* Most of the time, this will be correct.  The one case when this will
     fail is if the user defined an alternate stack, in which case the
     beginning of the stack will not be align_down (pc, 64).  */
  sp = align_down (pc, 64);

  /* rt_sigreturn trampoline:
     3419000x ldi 0, %r25 or ldi 1, %r25   (x = 0 or 2)
     3414015a ldi __NR_rt_sigreturn, %r20 
     e4008200 be,l 0x100(%sr2, %r0), %sr0, %r31
     08000240 nop  */

  for (attempt = 0; attempt < ARRAY_SIZE (pcoffs); attempt++)
    {
      if (insns_match_pattern (gdbarch, sp + pcoffs[attempt],
			       hppa_sigtramp, dummy))
	{
	  offs = sfoffs[attempt];
	  break;
	}
    }

  if (offs == 0)
    {
      if (insns_match_pattern (gdbarch, pc, hppa_sigtramp, dummy))
	{
	  /* sigaltstack case: we have no way of knowing which offset to 
	     use in this case; default to new kernel handling.  If this is
	     wrong the unwinding will fail.  */
	  attempt = 2;
	  sp = pc - pcoffs[attempt];
	}
      else
      {
	return 0;
      }
    }

  /* sp + sfoffs[try] points to a struct rt_sigframe, which contains
     a struct siginfo and a struct ucontext.  struct ucontext contains
     a struct sigcontext.  Return an offset to this sigcontext here.  Too 
     bad we cannot include system specific headers :-(.
     sizeof(struct siginfo) == 128
     offsetof(struct ucontext, uc_mcontext) == 24.  */
  return sp + sfoffs[attempt] + 128 + 24;
}

struct hppa_linux_sigtramp_unwind_cache
{
  CORE_ADDR base;
  trad_frame_saved_reg *saved_regs;
};

static struct hppa_linux_sigtramp_unwind_cache *
hppa_linux_sigtramp_frame_unwind_cache (struct frame_info *this_frame,
					void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  struct hppa_linux_sigtramp_unwind_cache *info;
  CORE_ADDR pc, scptr;
  int i;

  if (*this_cache)
    return (struct hppa_linux_sigtramp_unwind_cache *) *this_cache;

  info = FRAME_OBSTACK_ZALLOC (struct hppa_linux_sigtramp_unwind_cache);
  *this_cache = info;
  info->saved_regs = trad_frame_alloc_saved_regs (this_frame);

  pc = get_frame_pc (this_frame);
  scptr = hppa_linux_sigtramp_find_sigcontext (gdbarch, pc);

  /* structure of struct sigcontext:
   
     struct sigcontext {
	unsigned long sc_flags;
	unsigned long sc_gr[32]; 
	unsigned long long sc_fr[32];
	unsigned long sc_iasq[2];
	unsigned long sc_iaoq[2];
	unsigned long sc_sar;           */

  /* Skip sc_flags.  */
  scptr += 4;

  /* GR[0] is the psw.  */
  info->saved_regs[HPPA_IPSW_REGNUM].set_addr (scptr);
  scptr += 4;

  /* General registers.  */
  for (i = 1; i < 32; i++)
    {
      info->saved_regs[HPPA_R0_REGNUM + i].set_addr (scptr);
      scptr += 4;
    }

  /* Pad to long long boundary.  */
  scptr += 4;

  /* FP regs; FP0-3 are not restored.  */
  scptr += (8 * 4);

  for (i = 4; i < 32; i++)
    {
      info->saved_regs[HPPA_FP0_REGNUM + (i * 2)].set_addr (scptr);
      scptr += 4;
      info->saved_regs[HPPA_FP0_REGNUM + (i * 2) + 1].set_addr (scptr);
      scptr += 4;
    }

  /* IASQ/IAOQ.  */
  info->saved_regs[HPPA_PCSQ_HEAD_REGNUM].set_addr (scptr);
  scptr += 4;
  info->saved_regs[HPPA_PCSQ_TAIL_REGNUM].set_addr (scptr);
  scptr += 4;

  info->saved_regs[HPPA_PCOQ_HEAD_REGNUM].set_addr (scptr);
  scptr += 4;
  info->saved_regs[HPPA_PCOQ_TAIL_REGNUM].set_addr (scptr);
  scptr += 4;

  info->saved_regs[HPPA_SAR_REGNUM].set_addr (scptr);

  info->base = get_frame_register_unsigned (this_frame, HPPA_SP_REGNUM);

  return info;
}

static void
hppa_linux_sigtramp_frame_this_id (struct frame_info *this_frame,
				   void **this_prologue_cache,
				   struct frame_id *this_id)
{
  struct hppa_linux_sigtramp_unwind_cache *info
    = hppa_linux_sigtramp_frame_unwind_cache (this_frame, this_prologue_cache);
  *this_id = frame_id_build (info->base, get_frame_pc (this_frame));
}

static struct value *
hppa_linux_sigtramp_frame_prev_register (struct frame_info *this_frame,
					 void **this_prologue_cache,
					 int regnum)
{
  struct hppa_linux_sigtramp_unwind_cache *info
    = hppa_linux_sigtramp_frame_unwind_cache (this_frame, this_prologue_cache);
  return hppa_frame_prev_register_helper (this_frame,
					  info->saved_regs, regnum);
}

/* hppa-linux always uses "new-style" rt-signals.  The signal handler's return
   address should point to a signal trampoline on the stack.  The signal
   trampoline is embedded in a rt_sigframe structure that is aligned on
   the stack.  We take advantage of the fact that sp must be 64-byte aligned,
   and the trampoline is small, so by rounding down the trampoline address
   we can find the beginning of the struct rt_sigframe.  */
static int
hppa_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
				   struct frame_info *this_frame,
				   void **this_prologue_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  CORE_ADDR pc = get_frame_pc (this_frame);

  if (hppa_linux_sigtramp_find_sigcontext (gdbarch, pc))
    return 1;

  return 0;
}

static const struct frame_unwind hppa_linux_sigtramp_frame_unwind = {
  "hppa linux sigtramp",
  SIGTRAMP_FRAME,
  default_frame_unwind_stop_reason,
  hppa_linux_sigtramp_frame_this_id,
  hppa_linux_sigtramp_frame_prev_register,
  NULL,
  hppa_linux_sigtramp_frame_sniffer
};

/* Attempt to find (and return) the global pointer for the given
   function.

   This is a rather nasty bit of code searchs for the .dynamic section
   in the objfile corresponding to the pc of the function we're trying
   to call.  Once it finds the addresses at which the .dynamic section
   lives in the child process, it scans the Elf32_Dyn entries for a
   DT_PLTGOT tag.  If it finds one of these, the corresponding
   d_un.d_ptr value is the global pointer.  */

static CORE_ADDR
hppa_linux_find_global_pointer (struct gdbarch *gdbarch,
				struct value *function)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct obj_section *faddr_sect;
  CORE_ADDR faddr;
  
  faddr = value_as_address (function);

  /* Is this a plabel? If so, dereference it to get the gp value.  */
  if (faddr & 2)
    {
      int status;
      gdb_byte buf[4];

      faddr &= ~3;

      status = target_read_memory (faddr + 4, buf, sizeof (buf));
      if (status == 0)
	return extract_unsigned_integer (buf, sizeof (buf), byte_order);
    }

  /* If the address is in the plt section, then the real function hasn't 
     yet been fixed up by the linker so we cannot determine the gp of 
     that function.  */
  if (in_plt_section (faddr))
    return 0;

  faddr_sect = find_pc_section (faddr);
  if (faddr_sect != NULL)
    {
      struct obj_section *osect;

      ALL_OBJFILE_OSECTIONS (faddr_sect->objfile, osect)
	{
	  if (strcmp (osect->the_bfd_section->name, ".dynamic") == 0)
	    break;
	}

      if (osect < faddr_sect->objfile->sections_end)
	{
	  CORE_ADDR addr, endaddr;

	  addr = obj_section_addr (osect);
	  endaddr = obj_section_endaddr (osect);

	  while (addr < endaddr)
	    {
	      int status;
	      LONGEST tag;
	      gdb_byte buf[4];

	      status = target_read_memory (addr, buf, sizeof (buf));
	      if (status != 0)
		break;
	      tag = extract_signed_integer (buf, sizeof (buf), byte_order);

	      if (tag == DT_PLTGOT)
		{
		  CORE_ADDR global_pointer;

		  status = target_read_memory (addr + 4, buf, sizeof (buf));
		  if (status != 0)
		    break;
		  global_pointer = extract_unsigned_integer (buf, sizeof (buf),
							     byte_order);
		  /* The payoff...  */
		  return global_pointer;
		}

	      if (tag == DT_NULL)
		break;

	      addr += 8;
	    }
	}
    }
  return 0;
}

/*
 * Registers saved in a coredump:
 * gr0..gr31
 * sr0..sr7
 * iaoq0..iaoq1
 * iasq0..iasq1
 * sar, iir, isr, ior, ipsw
 * cr0, cr24..cr31
 * cr8,9,12,13
 * cr10, cr15
 */

static const struct regcache_map_entry hppa_linux_gregmap[] =
  {
    { 32, HPPA_R0_REGNUM },
    { 1, HPPA_SR4_REGNUM+1 },
    { 1, HPPA_SR4_REGNUM+2 },
    { 1, HPPA_SR4_REGNUM+3 },
    { 1, HPPA_SR4_REGNUM+4 },
    { 1, HPPA_SR4_REGNUM },
    { 1, HPPA_SR4_REGNUM+5 },
    { 1, HPPA_SR4_REGNUM+6 },
    { 1, HPPA_SR4_REGNUM+7 },
    { 1, HPPA_PCOQ_HEAD_REGNUM },
    { 1, HPPA_PCOQ_TAIL_REGNUM },
    { 1, HPPA_PCSQ_HEAD_REGNUM },
    { 1, HPPA_PCSQ_TAIL_REGNUM },
    { 1, HPPA_SAR_REGNUM },
    { 1, HPPA_IIR_REGNUM },
    { 1, HPPA_ISR_REGNUM },
    { 1, HPPA_IOR_REGNUM },
    { 1, HPPA_IPSW_REGNUM },
    { 1, HPPA_RCR_REGNUM },
    { 8, HPPA_TR0_REGNUM },
    { 4, HPPA_PID0_REGNUM },
    { 1, HPPA_CCR_REGNUM },
    { 1, HPPA_EIEM_REGNUM },
    { 0 }
  };

static const struct regcache_map_entry hppa_linux_fpregmap[] =
  {
    /* FIXME: Only works for 32-bit mode.  In 64-bit mode there should
       be 32 fpregs, 8 bytes each.  */
    { 64, HPPA_FP0_REGNUM, 4 },
    { 0 }
  };

/* HPPA Linux kernel register set.  */
static const struct regset hppa_linux_regset =
{
  hppa_linux_gregmap,
  regcache_supply_regset, regcache_collect_regset
};

static const struct regset hppa_linux_fpregset =
{
  hppa_linux_fpregmap,
  regcache_supply_regset, regcache_collect_regset
};

static void
hppa_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
					 iterate_over_regset_sections_cb *cb,
					 void *cb_data,
					 const struct regcache *regcache)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  cb (".reg", 80 * tdep->bytes_per_address, 80 * tdep->bytes_per_address,
      &hppa_linux_regset, NULL, cb_data);
  cb (".reg2", 64 * 4, 64 * 4, &hppa_linux_fpregset, NULL, cb_data);
}

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

  linux_init_abi (info, gdbarch, 0);

  /* GNU/Linux is always ELF.  */
  tdep->is_elf = 1;

  tdep->find_global_pointer = hppa_linux_find_global_pointer;

  set_gdbarch_write_pc (gdbarch, hppa_linux_target_write_pc);

  frame_unwind_append_unwinder (gdbarch, &hppa_linux_sigtramp_frame_unwind);

  /* GNU/Linux uses SVR4-style shared libraries.  */
  set_solib_svr4_fetch_link_map_offsets
    (gdbarch, svr4_ilp32_fetch_link_map_offsets);

  tdep->in_solib_call_trampoline = hppa_in_solib_call_trampoline;
  set_gdbarch_skip_trampoline_code (gdbarch, hppa_skip_trampoline_code);

  /* GNU/Linux uses the dynamic linker included in the GNU C Library.  */
  set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);

  /* On hppa-linux, currently, sizeof(long double) == 8.  There has been
     some discussions to support 128-bit long double, but it requires some
     more work in gcc and glibc first.  */
  set_gdbarch_long_double_bit (gdbarch, 64);
  set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);

  set_gdbarch_iterate_over_regset_sections
    (gdbarch, hppa_linux_iterate_over_regset_sections);

  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, hppa_dwarf_reg_to_regnum);

  /* Enable TLS support.  */
  set_gdbarch_fetch_tls_load_module_address (gdbarch,
					     svr4_fetch_objfile_link_map);
}

void _initialize_hppa_linux_tdep ();
void
_initialize_hppa_linux_tdep ()
{
  gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_LINUX,
			  hppa_linux_init_abi);
  gdbarch_register_osabi (bfd_arch_hppa, bfd_mach_hppa20w,
			  GDB_OSABI_LINUX, hppa_linux_init_abi);
}
