/* Target-dependent code for SuperH running NetBSD, for GDB.
   Copyright 2002, 2003 Free Software Foundation, Inc.
   Contributed by Wasabi Systems, 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 2 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, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

#include "defs.h"
#include "gdbcore.h"
#include "regcache.h"
#include "value.h"
#include "osabi.h"

#include "solib-svr4.h"

#include "nbsd-tdep.h"
#include "sh-tdep.h"
#include "shnbsd-tdep.h"

/* Convert an r0-r15 register number into an offset into a ptrace
   register structure.  */
static const int regmap[] =
{
  (20 * 4),	/* r0 */
  (19 * 4),	/* r1 */
  (18 * 4),	/* r2 */ 
  (17 * 4),	/* r3 */ 
  (16 * 4),	/* r4 */
  (15 * 4),	/* r5 */
  (14 * 4),	/* r6 */
  (13 * 4),	/* r7 */
  (12 * 4),	/* r8 */ 
  (11 * 4),	/* r9 */
  (10 * 4),	/* r10 */
  ( 9 * 4),	/* r11 */
  ( 8 * 4),	/* r12 */
  ( 7 * 4),	/* r13 */
  ( 6 * 4),	/* r14 */
  ( 5 * 4),	/* r15 */
};

#define SIZEOF_STRUCT_REG (21 * 4)

void
shnbsd_supply_reg (char *regs, int regno)
{
  int i;

  if (regno == PC_REGNUM || regno == -1)
    supply_register (PC_REGNUM, regs + (0 * 4));

  if (regno == SR_REGNUM || regno == -1)
    supply_register (SR_REGNUM, regs + (1 * 4));

  if (regno == PR_REGNUM || regno == -1)
    supply_register (PR_REGNUM, regs + (2 * 4));

  if (regno == MACH_REGNUM || regno == -1)
    supply_register (MACH_REGNUM, regs + (3 * 4));

  if (regno == MACL_REGNUM || regno == -1)
    supply_register (MACL_REGNUM, regs + (4 * 4));

  if ((regno >= R0_REGNUM && regno <= (R0_REGNUM + 15)) || regno == -1)
    {
      for (i = R0_REGNUM; i <= (R0_REGNUM + 15); i++)
	if (regno == i || regno == -1)
          supply_register (i, regs + regmap[i - R0_REGNUM]);
    }
}

void
shnbsd_fill_reg (char *regs, int regno)
{
  int i;

  if (regno == PC_REGNUM || regno == -1)
    regcache_collect (PC_REGNUM, regs + (0 * 4));

  if (regno == SR_REGNUM || regno == -1)
    regcache_collect (SR_REGNUM, regs + (1 * 4));

  if (regno == PR_REGNUM || regno == -1)
    regcache_collect (PR_REGNUM, regs + (2 * 4));

  if (regno == MACH_REGNUM || regno == -1)
    regcache_collect (MACH_REGNUM, regs + (3 * 4));

  if (regno == MACL_REGNUM || regno == -1)
    regcache_collect (MACL_REGNUM, regs + (4 * 4));

  if ((regno >= R0_REGNUM && regno <= (R0_REGNUM + 15)) || regno == -1)
    {
      for (i = R0_REGNUM; i <= (R0_REGNUM + 15); i++)
	if (regno == i || regno == -1)
          regcache_collect (i, regs + regmap[i - R0_REGNUM]);
    }
}

static void
fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
                      int which, CORE_ADDR ignore)
{
  /* We get everything from the .reg section.  */
  if (which != 0)
    return;

  if (core_reg_size < SIZEOF_STRUCT_REG)
    {
      warning ("Wrong size register set in core file.");
      return;
    }

  /* Integer registers.  */
  shnbsd_supply_reg (core_reg_sect, -1);
}

static void
fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size,
                         int which, CORE_ADDR ignore)
{
  switch (which)
    {
    case 0:  /* Integer registers.  */
      if (core_reg_size != SIZEOF_STRUCT_REG)
	warning ("Wrong size register set in core file.");
      else
	shnbsd_supply_reg (core_reg_sect, -1);
      break;

    default:
      /* Don't know what kind of register request this is; just ignore it.  */
      break;
    }
}

static struct core_fns shnbsd_core_fns =
{
  bfd_target_unknown_flavour,		/* core_flavour */
  default_check_format,			/* check_format */
  default_core_sniffer,			/* core_sniffer */
  fetch_core_registers,			/* core_read_registers */
  NULL					/* next */
};

static struct core_fns shnbsd_elfcore_fns =
{
  bfd_target_elf_flavour,		/* core_flavour */
  default_check_format,			/* check_format */
  default_core_sniffer,			/* core_sniffer */
  fetch_elfcore_registers,		/* core_read_registers */
  NULL					/* next */
};

static int
shnbsd_pc_in_sigtramp (CORE_ADDR pc, char *func_name)
{
  /* FIXME: Need to add support for kernel-provided signal trampolines.  */
  return (nbsd_pc_in_sigtramp (pc, func_name));
}

static void
shnbsd_init_abi (struct gdbarch_info info,
                  struct gdbarch *gdbarch)
{
  set_gdbarch_pc_in_sigtramp (gdbarch, shnbsd_pc_in_sigtramp);

  set_solib_svr4_fetch_link_map_offsets (gdbarch,
		                nbsd_ilp32_solib_svr4_fetch_link_map_offsets);
}

void
_initialize_shnbsd_tdep (void)
{
  add_core_fns (&shnbsd_core_fns);
  add_core_fns (&shnbsd_elfcore_fns);

  gdbarch_register_osabi (bfd_arch_sh, 0, GDB_OSABI_NETBSD_ELF,
			  shnbsd_init_abi);
}
