/* Target-dependent code for GNU/Linux on Alpha.
   Copyright (C) 2002-2023 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 "frame.h"
#include "osabi.h"
#include "solib-svr4.h"
#include "symtab.h"
#include "regset.h"
#include "regcache.h"
#include "linux-tdep.h"
#include "alpha-tdep.h"
#include "gdbarch.h"

/* This enum represents the signals' numbers on the Alpha
   architecture.  It just contains the signal definitions which are
   different from the generic implementation.

   It is derived from the file <arch/alpha/include/uapi/asm/signal.h>,
   from the Linux kernel tree.  */

enum
  {
    /* SIGABRT is the same as in the generic implementation, but is
       defined here because SIGIOT depends on it.  */
    ALPHA_LINUX_SIGABRT = 6,
    ALPHA_LINUX_SIGEMT = 7,
    ALPHA_LINUX_SIGBUS = 10,
    ALPHA_LINUX_SIGSYS = 12,
    ALPHA_LINUX_SIGURG = 16,
    ALPHA_LINUX_SIGSTOP = 17,
    ALPHA_LINUX_SIGTSTP = 18,
    ALPHA_LINUX_SIGCONT = 19,
    ALPHA_LINUX_SIGCHLD = 20,
    ALPHA_LINUX_SIGIO = 23,
    ALPHA_LINUX_SIGINFO = 29,
    ALPHA_LINUX_SIGUSR1 = 30,
    ALPHA_LINUX_SIGUSR2 = 31,
    ALPHA_LINUX_SIGPOLL = ALPHA_LINUX_SIGIO,
    ALPHA_LINUX_SIGPWR = ALPHA_LINUX_SIGINFO,
    ALPHA_LINUX_SIGIOT = ALPHA_LINUX_SIGABRT,
  };

/* Under GNU/Linux, signal handler invocations can be identified by
   the designated code sequence that is used to return from a signal
   handler.  In particular, the return address of a signal handler
   points to a sequence that copies $sp to $16, loads $0 with the
   appropriate syscall number, and finally enters the kernel.

   This is somewhat complicated in that:
     (1) the expansion of the "mov" assembler macro has changed over
	 time, from "bis src,src,dst" to "bis zero,src,dst",
     (2) the kernel has changed from using "addq" to "lda" to load the
	 syscall number,
     (3) there is a "normal" sigreturn and an "rt" sigreturn which
	 has a different stack layout.  */

static long
alpha_linux_sigtramp_offset_1 (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  switch (alpha_read_insn (gdbarch, pc))
    {
    case 0x47de0410:		/* bis $30,$30,$16 */
    case 0x47fe0410:		/* bis $31,$30,$16 */
      return 0;

    case 0x43ecf400:		/* addq $31,103,$0 */
    case 0x201f0067:		/* lda $0,103($31) */
    case 0x201f015f:		/* lda $0,351($31) */
      return 4;

    case 0x00000083:		/* call_pal callsys */
      return 8;

    default:
      return -1;
    }
}

static LONGEST
alpha_linux_sigtramp_offset (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  long i, off;

  if (pc & 3)
    return -1;

  /* Guess where we might be in the sequence.  */
  off = alpha_linux_sigtramp_offset_1 (gdbarch, pc);
  if (off < 0)
    return -1;

  /* Verify that the other two insns of the sequence are as we expect.  */
  pc -= off;
  for (i = 0; i < 12; i += 4)
    {
      if (i == off)
	continue;
      if (alpha_linux_sigtramp_offset_1 (gdbarch, pc + i) != i)
	return -1;
    }

  return off;
}

static int
alpha_linux_pc_in_sigtramp (struct gdbarch *gdbarch,
			    CORE_ADDR pc, const char *func_name)
{
  return alpha_linux_sigtramp_offset (gdbarch, pc) >= 0;
}

static CORE_ADDR
alpha_linux_sigcontext_addr (frame_info_ptr this_frame)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  CORE_ADDR pc;
  ULONGEST sp;
  long off;

  pc = get_frame_pc (this_frame);
  sp = get_frame_register_unsigned (this_frame, ALPHA_SP_REGNUM);

  off = alpha_linux_sigtramp_offset (gdbarch, pc);
  gdb_assert (off >= 0);

  /* __NR_rt_sigreturn has a couple of structures on the stack.  This is:

	struct rt_sigframe {
	  struct siginfo info;
	  struct ucontext uc;
	};

	offsetof (struct rt_sigframe, uc.uc_mcontext);  */

  if (alpha_read_insn (gdbarch, pc - off + 4) == 0x201f015f)
    return sp + 176;

  /* __NR_sigreturn has the sigcontext structure at the top of the stack.  */
  return sp;
}

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

static void
alpha_linux_supply_gregset (const struct regset *regset,
			    struct regcache *regcache,
			    int regnum, const void *gregs, size_t len)
{
  const gdb_byte *regs = (const gdb_byte *) gregs;

  gdb_assert (len >= 32 * 8);
  alpha_supply_int_regs (regcache, regnum, regs, regs + 31 * 8,
			 len >= 33 * 8 ? regs + 32 * 8 : NULL);
}

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

static void
alpha_linux_collect_gregset (const struct regset *regset,
			     const struct regcache *regcache,
			     int regnum, void *gregs, size_t len)
{
  gdb_byte *regs = (gdb_byte *) gregs;

  gdb_assert (len >= 32 * 8);
  alpha_fill_int_regs (regcache, regnum, regs, regs + 31 * 8,
		       len >= 33 * 8 ? regs + 32 * 8 : NULL);
}

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

static void
alpha_linux_supply_fpregset (const struct regset *regset,
			     struct regcache *regcache,
			     int regnum, const void *fpregs, size_t len)
{
  const gdb_byte *regs = (const gdb_byte *) fpregs;

  gdb_assert (len >= 32 * 8);
  alpha_supply_fp_regs (regcache, regnum, regs, regs + 31 * 8);
}

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

static void
alpha_linux_collect_fpregset (const struct regset *regset,
			      const struct regcache *regcache,
			      int regnum, void *fpregs, size_t len)
{
  gdb_byte *regs = (gdb_byte *) fpregs;

  gdb_assert (len >= 32 * 8);
  alpha_fill_fp_regs (regcache, regnum, regs, regs + 31 * 8);
}

static const struct regset alpha_linux_gregset =
{
  NULL,
  alpha_linux_supply_gregset, alpha_linux_collect_gregset
};

static const struct regset alpha_linux_fpregset =
{
  NULL,
  alpha_linux_supply_fpregset, alpha_linux_collect_fpregset
};

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

static void
alpha_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
					  iterate_over_regset_sections_cb *cb,
					  void *cb_data,
					  const struct regcache *regcache)
{
  cb (".reg", 32 * 8, 32 * 8, &alpha_linux_gregset, NULL, cb_data);
  cb (".reg2", 32 * 8, 32 * 8, &alpha_linux_fpregset, NULL, cb_data);
}

/* Implementation of `gdbarch_gdb_signal_from_target', as defined in
   gdbarch.h.  */

static enum gdb_signal
alpha_linux_gdb_signal_from_target (struct gdbarch *gdbarch,
				    int signal)
{
  switch (signal)
    {
    case ALPHA_LINUX_SIGEMT:
      return GDB_SIGNAL_EMT;

    case ALPHA_LINUX_SIGBUS:
      return GDB_SIGNAL_BUS;

    case ALPHA_LINUX_SIGSYS:
      return GDB_SIGNAL_SYS;

    case ALPHA_LINUX_SIGURG:
      return GDB_SIGNAL_URG;

    case ALPHA_LINUX_SIGSTOP:
      return GDB_SIGNAL_STOP;

    case ALPHA_LINUX_SIGTSTP:
      return GDB_SIGNAL_TSTP;

    case ALPHA_LINUX_SIGCONT:
      return GDB_SIGNAL_CONT;

    case ALPHA_LINUX_SIGCHLD:
      return GDB_SIGNAL_CHLD;

    /* No way to differentiate between SIGIO and SIGPOLL.
       Therefore, we just handle the first one.  */
    case ALPHA_LINUX_SIGIO:
      return GDB_SIGNAL_IO;

    /* No way to differentiate between SIGINFO and SIGPWR.
       Therefore, we just handle the first one.  */
    case ALPHA_LINUX_SIGINFO:
      return GDB_SIGNAL_INFO;

    case ALPHA_LINUX_SIGUSR1:
      return GDB_SIGNAL_USR1;

    case ALPHA_LINUX_SIGUSR2:
      return GDB_SIGNAL_USR2;
    }

  return linux_gdb_signal_from_target (gdbarch, signal);
}

/* Implementation of `gdbarch_gdb_signal_to_target', as defined in
   gdbarch.h.  */

static int
alpha_linux_gdb_signal_to_target (struct gdbarch *gdbarch,
				  enum gdb_signal signal)
{
  switch (signal)
    {
    case GDB_SIGNAL_EMT:
      return ALPHA_LINUX_SIGEMT;

    case GDB_SIGNAL_BUS:
      return ALPHA_LINUX_SIGBUS;

    case GDB_SIGNAL_SYS:
      return ALPHA_LINUX_SIGSYS;

    case GDB_SIGNAL_URG:
      return ALPHA_LINUX_SIGURG;

    case GDB_SIGNAL_STOP:
      return ALPHA_LINUX_SIGSTOP;

    case GDB_SIGNAL_TSTP:
      return ALPHA_LINUX_SIGTSTP;

    case GDB_SIGNAL_CONT:
      return ALPHA_LINUX_SIGCONT;

    case GDB_SIGNAL_CHLD:
      return ALPHA_LINUX_SIGCHLD;

    case GDB_SIGNAL_IO:
      return ALPHA_LINUX_SIGIO;

    case GDB_SIGNAL_INFO:
      return ALPHA_LINUX_SIGINFO;

    case GDB_SIGNAL_USR1:
      return ALPHA_LINUX_SIGUSR1;

    case GDB_SIGNAL_USR2:
      return ALPHA_LINUX_SIGUSR2;

    case GDB_SIGNAL_POLL:
      return ALPHA_LINUX_SIGPOLL;

    case GDB_SIGNAL_PWR:
      return ALPHA_LINUX_SIGPWR;
    }

  return linux_gdb_signal_to_target (gdbarch, signal);
}

static void
alpha_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
  linux_init_abi (info, gdbarch, 0);

  /* Hook into the DWARF CFI frame unwinder.  */
  alpha_dwarf2_init_abi (info, gdbarch);

  /* Hook into the MDEBUG frame unwinder.  */
  alpha_mdebug_init_abi (info, gdbarch);

  alpha_gdbarch_tdep *tdep = gdbarch_tdep<alpha_gdbarch_tdep> (gdbarch);
  tdep->dynamic_sigtramp_offset = alpha_linux_sigtramp_offset;
  tdep->sigcontext_addr = alpha_linux_sigcontext_addr;
  tdep->pc_in_sigtramp = alpha_linux_pc_in_sigtramp;
  tdep->jb_pc = 2;
  tdep->jb_elt_size = 8;

  set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);

  set_solib_svr4_fetch_link_map_offsets
    (gdbarch, linux_lp64_fetch_link_map_offsets);

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

  set_gdbarch_iterate_over_regset_sections
    (gdbarch, alpha_linux_iterate_over_regset_sections);

  set_gdbarch_gdb_signal_from_target (gdbarch,
				      alpha_linux_gdb_signal_from_target);
  set_gdbarch_gdb_signal_to_target (gdbarch,
				    alpha_linux_gdb_signal_to_target);
}

void _initialize_alpha_linux_tdep ();
void
_initialize_alpha_linux_tdep ()
{
  gdbarch_register_osabi (bfd_arch_alpha, 0, GDB_OSABI_LINUX,
			  alpha_linux_init_abi);
}
