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

   Copyright (C) 2004-2025 Free Software Foundation, Inc.

   This file is part of GDB.

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

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

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

#include "extract-store-integer.h"
#include "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 "solib-svr4-linux.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 (const frame_info_ptr &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 (const frame_info_ptr &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 (const frame_info_ptr &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,
				   const frame_info_ptr &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_legacy hppa_linux_sigtramp_frame_unwind (
  "hppa linux sigtramp",
  SIGTRAMP_FRAME,
  FRAME_UNWIND_ARCH,
  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 rather nasty bit of code searches 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)
    {
      for (obj_section *osect : faddr_sect->objfile->sections ())
	{
	  if (strcmp (osect->the_bfd_section->name, ".dynamic") == 0)
	    {
	      CORE_ADDR addr, endaddr;

	      addr = osect->addr ();
	      endaddr = osect->endaddr ();

	      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, 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;
		}
	      break;
	    }
	}
    }
  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)
{
  hppa_gdbarch_tdep *tdep = gdbarch_tdep<hppa_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)
{
  hppa_gdbarch_tdep *tdep = gdbarch_tdep<hppa_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_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);

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

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