/* Target-dependent code for PowerPC systems running FreeBSD.

   Copyright (C) 2013-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 "arch-utils.h"
#include "extract-store-integer.h"
#include "frame.h"
#include "gdbcore.h"
#include "frame-unwind.h"
#include "gdbtypes.h"
#include "osabi.h"
#include "regcache.h"
#include "regset.h"
#include "symtab.h"
#include "target.h"
#include "trad-frame.h"

#include "ppc-tdep.h"
#include "ppc64-tdep.h"
#include "ppc-fbsd-tdep.h"
#include "fbsd-tdep.h"
#include "solib-svr4.h"
#include "inferior.h"


/* 32-bit regset descriptions.  */

static const struct ppc_reg_offsets ppc32_fbsd_reg_offsets =
  {
	/* General-purpose registers.  */
	/* .r0_offset = */     0,
	/* .gpr_size = */      4,
	/* .xr_size = */       4,
	/* .pc_offset = */     144,
	/* .ps_offset = */     -1,
	/* .cr_offset = */     132,
	/* .lr_offset = */     128,
	/* .ctr_offset = */    140,
	/* .xer_offset = */    136,
	/* .mq_offset = */     -1,

	/* Floating-point registers.  */
	/* .f0_offset = */     0,
	/* .fpscr_offset = */  256,
	/* .fpscr_size = */    8
  };

/* 64-bit regset descriptions.  */

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

	/* Floating-point registers.  */
	/* .f0_offset = */     0,
	/* .fpscr_offset = */  256,
	/* .fpscr_size = */    8
  };

/* 32-bit general-purpose register set.  */

static const struct regset ppc32_fbsd_gregset = {
  &ppc32_fbsd_reg_offsets,
  ppc_supply_gregset,
  ppc_collect_gregset
};

/* 64-bit general-purpose register set.  */

static const struct regset ppc64_fbsd_gregset = {
  &ppc64_fbsd_reg_offsets,
  ppc_supply_gregset,
  ppc_collect_gregset
};

/* 32-/64-bit floating-point register set.  */

static const struct regset ppc32_fbsd_fpregset = {
  &ppc32_fbsd_reg_offsets,
  ppc_supply_fpregset,
  ppc_collect_fpregset
};

const struct regset *
ppc_fbsd_gregset (int wordsize)
{
  return wordsize == 8 ? &ppc64_fbsd_gregset : &ppc32_fbsd_gregset;
}

const struct regset *
ppc_fbsd_fpregset (void)
{
  return &ppc32_fbsd_fpregset;
}

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

static void
ppcfbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
				      iterate_over_regset_sections_cb *cb,
				      void *cb_data,
				      const struct regcache *regcache)
{
  ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);

  if (tdep->wordsize == 4)
    cb (".reg", 148, 148, &ppc32_fbsd_gregset, NULL, cb_data);
  else
    cb (".reg", 296, 296, &ppc64_fbsd_gregset, NULL, cb_data);
  cb (".reg2", 264, 264, &ppc32_fbsd_fpregset, NULL, cb_data);
}

/* Default page size.  */

static const int ppcfbsd_page_size = 4096;

/* Offset for sigreturn(2).  */

static const int ppcfbsd_sigreturn_offset[] = {
  0xc,				/* FreeBSD 32-bit  */
  -1
};

/* Signal trampolines.  */

static int
ppcfbsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
				const frame_info_ptr &this_frame,
				void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR pc = get_frame_pc (this_frame);
  CORE_ADDR start_pc = (pc & ~(ppcfbsd_page_size - 1));
  const int *offset;
  const char *name;

  /* A stack trampoline is detected if no name is associated
   to the current pc and if it points inside a trampoline
   sequence.  */

  find_pc_partial_function (pc, &name, NULL, NULL);

  /* If we have a name, we have no trampoline, return.  */
  if (name)
    return 0;

  for (offset = ppcfbsd_sigreturn_offset; *offset != -1; offset++)
    {
      gdb_byte buf[2 * PPC_INSN_SIZE];
      unsigned long insn;

      if (!safe_frame_unwind_memory (this_frame, start_pc + *offset,
				     {buf, sizeof buf}))
	continue;

      /* Check for "li r0,SYS_sigreturn".  */
      insn = extract_unsigned_integer (buf, PPC_INSN_SIZE, byte_order);
      if (insn != 0x380001a1)
	continue;

      /* Check for "sc".  */
      insn = extract_unsigned_integer (buf + PPC_INSN_SIZE,
				       PPC_INSN_SIZE, byte_order);
      if (insn != 0x44000002)
	continue;

      return 1;
    }

  return 0;
}

static struct trad_frame_cache *
ppcfbsd_sigtramp_frame_cache (const frame_info_ptr &this_frame, void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
  struct trad_frame_cache *cache;
  CORE_ADDR addr, base, func;
  gdb_byte buf[PPC_INSN_SIZE];
  int i;

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

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

  func = get_frame_pc (this_frame);
  func &= ~(ppcfbsd_page_size - 1);
  if (!safe_frame_unwind_memory (this_frame, func, {buf, sizeof buf}))
    return cache;

  base = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch));
  addr = base + 0x10 + 2 * tdep->wordsize;
  for (i = 0; i < ppc_num_gprs; i++, addr += tdep->wordsize)
    {
      int regnum = i + tdep->ppc_gp0_regnum;
      trad_frame_set_reg_addr (cache, regnum, addr);
    }
  trad_frame_set_reg_addr (cache, tdep->ppc_lr_regnum, addr);
  addr += tdep->wordsize;
  trad_frame_set_reg_addr (cache, tdep->ppc_cr_regnum, addr);
  addr += tdep->wordsize;
  trad_frame_set_reg_addr (cache, tdep->ppc_xer_regnum, addr);
  addr += tdep->wordsize;
  trad_frame_set_reg_addr (cache, tdep->ppc_ctr_regnum, addr);
  addr += tdep->wordsize;
  trad_frame_set_reg_addr (cache, gdbarch_pc_regnum (gdbarch), addr);
  /* SRR0?  */
  addr += tdep->wordsize;

  /* Construct the frame ID using the function start.  */
  trad_frame_set_id (cache, frame_id_build (base, func));

  return cache;
}

static void
ppcfbsd_sigtramp_frame_this_id (const frame_info_ptr &this_frame,
				void **this_cache, struct frame_id *this_id)
{
  struct trad_frame_cache *cache =
    ppcfbsd_sigtramp_frame_cache (this_frame, this_cache);

  trad_frame_get_id (cache, this_id);
}

static struct value *
ppcfbsd_sigtramp_frame_prev_register (const frame_info_ptr &this_frame,
				      void **this_cache, int regnum)
{
  struct trad_frame_cache *cache =
    ppcfbsd_sigtramp_frame_cache (this_frame, this_cache);

  return trad_frame_get_register (cache, this_frame, regnum);
}

static const struct frame_unwind ppcfbsd_sigtramp_frame_unwind = {
  "ppc freebsd sigtramp",
  SIGTRAMP_FRAME,
  default_frame_unwind_stop_reason,
  ppcfbsd_sigtramp_frame_this_id,
  ppcfbsd_sigtramp_frame_prev_register,
  NULL,
  ppcfbsd_sigtramp_frame_sniffer
};

static enum return_value_convention
ppcfbsd_return_value (struct gdbarch *gdbarch, struct value *function,
		      struct type *valtype, struct regcache *regcache,
		      gdb_byte *readbuf, const gdb_byte *writebuf)
{
  return ppc_sysv_abi_broken_return_value (gdbarch, function, valtype,
					   regcache, readbuf, writebuf);
}

/* Implement the "get_thread_local_address" gdbarch method.  */

static CORE_ADDR
ppcfbsd_get_thread_local_address (struct gdbarch *gdbarch, ptid_t ptid,
				  CORE_ADDR lm_addr, CORE_ADDR offset)
{
  ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
  int tp_offset, tp_regnum;
  regcache *regcache
    = get_thread_arch_regcache (current_inferior (), ptid, gdbarch);

  if (tdep->wordsize == 4)
    {
      tp_offset = 0x7008;
      tp_regnum = PPC_R0_REGNUM + 2;
    }
  else
    {
      tp_offset = 0x7010;
      tp_regnum = PPC_R0_REGNUM + 13;
    }
  target_fetch_registers (regcache, tp_regnum);

  ULONGEST tp;
  if (regcache->cooked_read (tp_regnum, &tp) != REG_VALID)
    error (_("Unable to fetch tcb pointer"));

  /* tp points to the end of the TCB block.  The first member of the
     TCB is the pointer to the DTV array.  */
  CORE_ADDR dtv_addr = tp - tp_offset;
  return fbsd_get_thread_local_address (gdbarch, dtv_addr, lm_addr, offset);
}

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

  /* Generic FreeBSD support. */
  fbsd_init_abi (info, gdbarch);

  /* FreeBSD doesn't support the 128-bit `long double' from the psABI.  */
  set_gdbarch_long_double_bit (gdbarch, 64);
  set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);

  if (tdep->wordsize == 4)
    {
      set_gdbarch_return_value (gdbarch, ppcfbsd_return_value);

      set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
      set_solib_svr4_fetch_link_map_offsets (gdbarch,
					     svr4_ilp32_fetch_link_map_offsets);

      frame_unwind_append_unwinder (gdbarch, &ppcfbsd_sigtramp_frame_unwind);
      set_gdbarch_gcore_bfd_target (gdbarch, "elf32-powerpc");
    }

  if (tdep->wordsize == 8)
    {
      set_gdbarch_convert_from_func_ptr_addr
	(gdbarch, ppc64_convert_from_func_ptr_addr);
      set_gdbarch_elf_make_msymbol_special (gdbarch,
					    ppc64_elf_make_msymbol_special);

      set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code);
      set_solib_svr4_fetch_link_map_offsets (gdbarch,
					     svr4_lp64_fetch_link_map_offsets);
      set_gdbarch_gcore_bfd_target (gdbarch, "elf64-powerpc");
    }

  set_gdbarch_iterate_over_regset_sections
    (gdbarch, ppcfbsd_iterate_over_regset_sections);

  set_gdbarch_fetch_tls_load_module_address (gdbarch,
					     svr4_fetch_objfile_link_map);
  set_gdbarch_get_thread_local_address (gdbarch,
					ppcfbsd_get_thread_local_address);
}

void _initialize_ppcfbsd_tdep ();
void
_initialize_ppcfbsd_tdep ()
{
  gdbarch_register_osabi (bfd_arch_powerpc, bfd_mach_ppc, GDB_OSABI_FREEBSD,
			  ppcfbsd_init_abi);
  gdbarch_register_osabi (bfd_arch_powerpc, bfd_mach_ppc64, GDB_OSABI_FREEBSD,
			  ppcfbsd_init_abi);
  gdbarch_register_osabi (bfd_arch_rs6000, 0, GDB_OSABI_FREEBSD,
			  ppcfbsd_init_abi);
}
