add autom4te.cache to .cvsignore
[deliverable/binutils-gdb.git] / gdb / i386-nto-tdep.c
index 6d2f4923b3e2bd5dac6ca8836a7ae6c410ed22ce..75acd7e84d35157a7739e1df0b585c2df7f931d8 100644 (file)
@@ -1,6 +1,6 @@
-/* i386-nto-tdep.c - i386 specific functionality for QNX Neutrino.
+/* Target-dependent code for QNX Neutrino x86.
 
-   Copyright 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
 
    Contributed by QNX Software Systems Ltd.
 
 
    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.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
-#include "gdb_string.h"
-#include "gdb_assert.h"
 #include "defs.h"
 #include "frame.h"
-#include "target.h"
+#include "osabi.h"
 #include "regcache.h"
-#include "solib-svr4.h"
+#include "target.h"
+
+#include "gdb_assert.h"
+#include "gdb_string.h"
+
 #include "i386-tdep.h"
-#include "nto-tdep.h"
-#include "osabi.h"
 #include "i387-tdep.h"
+#include "nto-tdep.h"
+#include "solib-svr4.h"
+
+/* Target vector for QNX NTO x86.  */
+static struct nto_target_ops i386_nto_target;
 
 #ifndef X86_CPU_FXSR
 #define X86_CPU_FXSR (1L << 12)
    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 */
+/* Mapping between the general-purpose registers in `struct xxx'
+   format and GDB's register cache layout.  */
+
+/* From <x86/context.h>.  */
+static int i386nto_gregset_reg_offset[] =
+{
+  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                           /* filler */
 };
 
-/* Given a gdb regno, return the offset into Neutrino's register structure
-   or -1 if register is unknown.  */
+/* Given a GDB register number REGNUM, return the offset into
+   Neutrino's register structure or -1 if the register is unknown.  */
+
 static int
-nto_reg_offset (int regno)
+nto_reg_offset (int regnum)
 {
-  return (regno >= 0 && regno < NUM_GPREGS) ? regmap[regno] : -1;
+  if (regnum >= 0 && regnum < ARRAY_SIZE (i386nto_gregset_reg_offset))
+    return i386nto_gregset_reg_offset[regnum];
+
+  return -1;
 }
 
 static void
 i386nto_supply_gregset (char *gpregs)
 {
-  unsigned regno;
-  int empty = 0;
+  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
 
-  for (regno = 0; regno < FP0_REGNUM; regno++)
-    {
-      int offset = nto_reg_offset (regno);
-      if (offset == -1)
-       supply_register (regno, (char *) &empty);
-      else
-       supply_register (regno, gpregs + offset);
-    }
+  if(tdep->gregset == NULL)
+    tdep->gregset = regset_alloc (current_gdbarch, i386_supply_gregset,
+                                 i386_collect_gregset);
+
+  gdb_assert (tdep->gregset_reg_offset == i386nto_gregset_reg_offset);
+  tdep->gregset->supply_regset (tdep->gregset, current_regcache, -1,
+                               gpregs, NUM_GPREGS * 4);
 }
 
 static void
@@ -97,7 +108,7 @@ i386nto_supply_regset (int regset, char *data)
 {
   switch (regset)
     {
-    case NTO_REG_GENERAL:      /* QNX has different ordering of GP regs than GDB.  */
+    case NTO_REG_GENERAL:
       i386nto_supply_gregset (data);
       break;
     case NTO_REG_FLOAT:
@@ -111,9 +122,9 @@ i386nto_regset_id (int regno)
 {
   if (regno == -1)
     return NTO_REG_END;
-  else if (regno < FP0_REGNUM)
+  else if (regno < I386_NUM_GREGS)
     return NTO_REG_GENERAL;
-  else if (regno < FPC_REGNUM)
+  else if (regno < I386_NUM_GREGS + I386_NUM_FREGS)
     return NTO_REG_FLOAT;
 
   return -1;                   /* Error.  */
@@ -176,7 +187,7 @@ i386nto_regset_fill (int regset, char *data)
        {
          int offset = nto_reg_offset (regno);
          if (offset != -1)
-           regcache_collect (regno, data + offset);
+           regcache_raw_collect (current_regcache, regno, data + offset);
        }
     }
   else if (regset == NTO_REG_FLOAT)
@@ -192,42 +203,16 @@ i386nto_regset_fill (int regset, char *data)
   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_pc_in_sigtramp (CORE_ADDR pc, char *name)
+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;
 }
 
@@ -242,7 +227,7 @@ i386nto_sigcontext_addr (struct frame_info *next_frame)
   char buf[4];
   CORE_ADDR sp;
 
-  frame_unwind_register (next_frame, SP_REGNUM, buf);
+  frame_unwind_register (next_frame, I386_ESP_REGNUM, buf);
   sp = extract_unsigned_integer (buf, 4);
 
   return sp + I386_NTO_SIGCONTEXT_OFFSET;
@@ -251,15 +236,15 @@ i386nto_sigcontext_addr (struct frame_info *next_frame)
 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;
+  i386_nto_target.regset_id = i386nto_regset_id;
+  i386_nto_target.supply_gregset = i386nto_supply_gregset;
+  i386_nto_target.supply_fpregset = i386nto_supply_fpregset;
+  i386_nto_target.supply_altregset = nto_dummy_supply_regset;
+  i386_nto_target.supply_regset = i386nto_supply_regset;
+  i386_nto_target.register_area = i386nto_register_area;
+  i386_nto_target.regset_fill = i386nto_regset_fill;
+  i386_nto_target.fetch_link_map_offsets =
+    svr4_ilp32_fetch_link_map_offsets;
 }
 
 static void
@@ -267,6 +252,9 @@ i386nto_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
+  /* Deal with our strange signals.  */
+  nto_initialize_signals ();
+
   /* NTO uses ELF.  */
   i386_elf_init_abi (info, gdbarch);
 
@@ -274,11 +262,11 @@ i386nto_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
      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->gregset_reg_offset = i386nto_gregset_reg_offset;
+  tdep->gregset_num_regs = ARRAY_SIZE (i386nto_gregset_reg_offset);
+  tdep->sizeof_gregset = NUM_GPREGS * 4;
 
-  set_gdbarch_pc_in_sigtramp (gdbarch, i386nto_pc_in_sigtramp);
+  tdep->sigtramp_p = i386nto_sigtramp_p;
   tdep->sigcontext_addr = i386nto_sigcontext_addr;
   tdep->sc_pc_offset = 56;
   tdep->sc_sp_offset = 68;
@@ -286,8 +274,8 @@ i386nto_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   /* 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);
+  set_solib_svr4_fetch_link_map_offsets
+    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
 
   /* Our loader handles solib relocations slightly differently than svr4.  */
   TARGET_SO_RELOCATE_SECTION_ADDRESSES = nto_relocate_section_addresses;
@@ -295,12 +283,18 @@ i386nto_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   /* Supply a nice function to find our solibs.  */
   TARGET_SO_FIND_AND_OPEN_SOLIB = nto_find_and_open_solib;
 
-  init_i386nto_ops ();
+  /* Our linker code is in libc.  */
+  TARGET_SO_IN_DYNSYM_RESOLVE_CODE = nto_in_dynsym_resolve_code;
+
+  nto_set_target (&i386_nto_target);
 }
 
 void
 _initialize_i386nto_tdep (void)
 {
+  init_i386nto_ops ();
   gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_QNXNTO,
                          i386nto_init_abi);
+  gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_elf_flavour,
+                                 nto_elf_osabi_sniffer);
 }
This page took 0.049506 seconds and 4 git commands to generate.