/* Target-dependent code for QNX Neutrino x86.

   Copyright 2003, 2004 Free Software Foundation, Inc.

   Contributed by QNX Software Systems Ltd.

   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 "gdb_string.h"
#include "gdb_assert.h"
#include "defs.h"
#include "frame.h"
#include "target.h"
#include "regcache.h"
#include "solib-svr4.h"
#include "i386-tdep.h"
#include "nto-tdep.h"
#include "osabi.h"
#include "i387-tdep.h"

#ifndef X86_CPU_FXSR
#define X86_CPU_FXSR (1L << 12)
#endif

/* Why 13?  Look in our /usr/include/x86/context.h header at the
   x86_cpu_registers structure and you'll see an 'exx' junk register
   that is just filler.  Don't ask me, ask the kernel guys.  */
#define NUM_GPREGS 13

/* Map a GDB register number to an offset in the reg structure.  */
static int regmap[] = {
  (7 * 4),			/* eax */
  (6 * 4),			/* ecx */
  (5 * 4),			/* edx */
  (4 * 4),			/* ebx */
  (11 * 4),			/* esp */
  (2 * 4),			/* epb */
  (1 * 4),			/* esi */
  (0 * 4),			/* edi */
  (8 * 4),			/* eip */
  (10 * 4),			/* eflags */
  (9 * 4),			/* cs */
  (12 * 4),			/* ss */
  (-1 * 4)			/* filler */
};

/* Given a gdb regno, return the offset into Neutrino's register structure
   or -1 if register is unknown.  */
static int
nto_reg_offset (int regno)
{
  return (regno >= 0 && regno < NUM_GPREGS) ? regmap[regno] : -1;
}

static void
i386nto_supply_gregset (char *gpregs)
{
  unsigned regno;
  int empty = 0;

  for (regno = 0; regno < I386_NUM_GREGS; regno++)
    {
      int offset = nto_reg_offset (regno);
      if (offset == -1)
	regcache_raw_supply (current_regcache, regno, (char *) &empty);
      else
	regcache_raw_supply (current_regcache, regno, gpregs + offset);
    }
}

static void
i386nto_supply_fpregset (char *fpregs)
{
  if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR)
    i387_supply_fxsave (current_regcache, -1, fpregs);
  else
    i387_supply_fsave (current_regcache, -1, fpregs);
}

static void
i386nto_supply_regset (int regset, char *data)
{
  switch (regset)
    {
    case NTO_REG_GENERAL:	/* QNX has different ordering of GP regs than GDB.  */
      i386nto_supply_gregset (data);
      break;
    case NTO_REG_FLOAT:
      i386nto_supply_fpregset (data);
      break;
    }
}

static int
i386nto_regset_id (int regno)
{
  if (regno == -1)
    return NTO_REG_END;
  else if (regno < I386_NUM_GREGS)
    return NTO_REG_GENERAL;
  else if (regno < I386_NUM_GREGS + I386_NUM_FREGS)
    return NTO_REG_FLOAT;

  return -1;			/* Error.  */
}

static int
i386nto_register_area (int regno, int regset, unsigned *off)
{
  int len;

  *off = 0;
  if (regset == NTO_REG_GENERAL)
    {
      if (regno == -1)
	return NUM_GPREGS * 4;

      *off = nto_reg_offset (regno);
      if (*off == -1)
	return 0;
      return 4;
    }
  else if (regset == NTO_REG_FLOAT)
    {
      unsigned off_adjust, regsize, regset_size;

      if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR)
	{
	  off_adjust = 32;
	  regsize = 16;
	  regset_size = 512;
	}
      else
	{
	  off_adjust = 28;
	  regsize = 10;
	  regset_size = 128;
	}

      if (regno == -1)
	return regset_size;

      *off = (regno - FP0_REGNUM) * regsize + off_adjust;
      return 10;
      /* Why 10 instead of regsize?  GDB only stores 10 bytes per FP
         register so if we're sending a register back to the target,
         we only want pdebug to write 10 bytes so as not to clobber
         the reserved 6 bytes in the fxsave structure.  */
    }
  return -1;
}

static int
i386nto_regset_fill (int regset, char *data)
{
  if (regset == NTO_REG_GENERAL)
    {
      int regno;

      for (regno = 0; regno < NUM_GPREGS; regno++)
	{
	  int offset = nto_reg_offset (regno);
	  if (offset != -1)
	    regcache_raw_collect (current_regcache, regno, data + offset);
	}
    }
  else if (regset == NTO_REG_FLOAT)
    {
      if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR)
	i387_fill_fxsave (data, -1);
      else
	i387_fill_fsave (data, -1);
    }
  else
    return -1;

  return 0;
}

static struct link_map_offsets *
i386nto_svr4_fetch_link_map_offsets (void)
{
  static struct link_map_offsets lmo;
  static struct link_map_offsets *lmp = NULL;

  if (lmp == NULL)
    {
      lmp = &lmo;

      lmo.r_debug_size = 8;	/* The actual size is 20 bytes, but
				   only 8 bytes are used.  */
      lmo.r_map_offset = 4;
      lmo.r_map_size = 4;

      lmo.link_map_size = 20;	/* The actual size is 552 bytes, but
				   only 20 bytes are used.  */
      lmo.l_addr_offset = 0;
      lmo.l_addr_size = 4;

      lmo.l_name_offset = 4;
      lmo.l_name_size = 4;

      lmo.l_next_offset = 12;
      lmo.l_next_size = 4;

      lmo.l_prev_offset = 16;
      lmo.l_prev_size = 4;
    }

  return lmp;
}

/* Return whether the frame preceding NEXT_FRAME corresponds to a QNX
   Neutrino sigtramp routine.  */

static int
i386nto_sigtramp_p (struct frame_info *next_frame)
{
  CORE_ADDR pc = frame_pc_unwind (next_frame);
  char *name;

  find_pc_partial_function (pc, &name, NULL, NULL);
  return name && strcmp ("__signalstub", name) == 0;
}

#define I386_NTO_SIGCONTEXT_OFFSET 136

/* Assuming NEXT_FRAME is a frame following a QNX Neutrino sigtramp
   routine, return the address of the associated sigcontext structure.  */

static CORE_ADDR
i386nto_sigcontext_addr (struct frame_info *next_frame)
{
  char buf[4];
  CORE_ADDR sp;

  frame_unwind_register (next_frame, I386_ESP_REGNUM, buf);
  sp = extract_unsigned_integer (buf, 4);

  return sp + I386_NTO_SIGCONTEXT_OFFSET;
}

static void
init_i386nto_ops (void)
{
  current_nto_target.nto_regset_id = i386nto_regset_id;
  current_nto_target.nto_supply_gregset = i386nto_supply_gregset;
  current_nto_target.nto_supply_fpregset = i386nto_supply_fpregset;
  current_nto_target.nto_supply_altregset = nto_dummy_supply_regset;
  current_nto_target.nto_supply_regset = i386nto_supply_regset;
  current_nto_target.nto_register_area = i386nto_register_area;
  current_nto_target.nto_regset_fill = i386nto_regset_fill;
  current_nto_target.nto_fetch_link_map_offsets =
    i386nto_svr4_fetch_link_map_offsets;
}

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

  /* NTO uses ELF.  */
  i386_elf_init_abi (info, gdbarch);

  /* Neutrino rewinds to look more normal.  Need to override the i386
     default which is [unfortunately] to decrement the PC.  */
  set_gdbarch_decr_pc_after_break (gdbarch, 0);

  /* NTO has shared libraries.  */
  set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section);
  set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);

  tdep->sigtramp_p = i386nto_sigtramp_p;
  tdep->sigcontext_addr = i386nto_sigcontext_addr;
  tdep->sc_pc_offset = 56;
  tdep->sc_sp_offset = 68;

  /* Setjmp()'s return PC saved in EDX (5).  */
  tdep->jb_pc_offset = 20;	/* 5x32 bit ints in.  */

  set_solib_svr4_fetch_link_map_offsets (gdbarch,
					 i386nto_svr4_fetch_link_map_offsets);

  /* Our loader handles solib relocations slightly differently than svr4.  */
  TARGET_SO_RELOCATE_SECTION_ADDRESSES = nto_relocate_section_addresses;

  /* Supply a nice function to find our solibs.  */
  TARGET_SO_FIND_AND_OPEN_SOLIB = nto_find_and_open_solib;

  init_i386nto_ops ();
}

void
_initialize_i386nto_tdep (void)
{
  gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_QNXNTO,
			  i386nto_init_abi);
}
