2009-01-08 Kai Tietz <kai.tietz@onevision.com>
[binutils-gdb.git] / gdb / i386-nto-tdep.c
index 666a077d32599c99217065e9a399da13121151b4..ede9bf13f10445804b227222f72ef11cb4fe75a2 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for QNX Neutrino x86.
 
-   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2007, 2008, 2009 Free Software Foundation, Inc.
 
    Contributed by QNX Software Systems Ltd.
 
@@ -8,7 +8,7 @@
 
    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
+   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,
@@ -17,9 +17,7 @@
    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., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "frame.h"
@@ -33,6 +31,7 @@
 #include "i386-tdep.h"
 #include "i387-tdep.h"
 #include "nto-tdep.h"
+#include "solib.h"
 #include "solib-svr4.h"
 
 /* Target vector for QNX NTO x86.  */
@@ -81,38 +80,39 @@ nto_reg_offset (int regnum)
 }
 
 static void
-i386nto_supply_gregset (char *gpregs)
+i386nto_supply_gregset (struct regcache *regcache, char *gpregs)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   if(tdep->gregset == NULL)
-    tdep->gregset = regset_alloc (current_gdbarch, i386_supply_gregset,
+    tdep->gregset = regset_alloc (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,
+  tdep->gregset->supply_regset (tdep->gregset, regcache, -1,
                                gpregs, NUM_GPREGS * 4);
 }
 
 static void
-i386nto_supply_fpregset (char *fpregs)
+i386nto_supply_fpregset (struct regcache *regcache, char *fpregs)
 {
   if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR)
-    i387_supply_fxsave (current_regcache, -1, fpregs);
+    i387_supply_fxsave (regcache, -1, fpregs);
   else
-    i387_supply_fsave (current_regcache, -1, fpregs);
+    i387_supply_fsave (regcache, -1, fpregs);
 }
 
 static void
-i386nto_supply_regset (int regset, char *data)
+i386nto_supply_regset (struct regcache *regcache, int regset, char *data)
 {
   switch (regset)
     {
     case NTO_REG_GENERAL:
-      i386nto_supply_gregset (data);
+      i386nto_supply_gregset (regcache, data);
       break;
     case NTO_REG_FLOAT:
-      i386nto_supply_fpregset (data);
+      i386nto_supply_fpregset (regcache, data);
       break;
     }
 }
@@ -131,7 +131,8 @@ i386nto_regset_id (int regno)
 }
 
 static int
-i386nto_register_area (int regno, int regset, unsigned *off)
+i386nto_register_area (struct gdbarch *gdbarch,
+                      int regno, int regset, unsigned *off)
 {
   int len;
 
@@ -166,7 +167,7 @@ i386nto_register_area (int regno, int regset, unsigned *off)
       if (regno == -1)
        return regset_size;
 
-      *off = (regno - FP0_REGNUM) * regsize + off_adjust;
+      *off = (regno - gdbarch_fp0_regnum (gdbarch)) * 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,
@@ -177,7 +178,7 @@ i386nto_register_area (int regno, int regset, unsigned *off)
 }
 
 static int
-i386nto_regset_fill (int regset, char *data)
+i386nto_regset_fill (const struct regcache *regcache, int regset, char *data)
 {
   if (regset == NTO_REG_GENERAL)
     {
@@ -187,15 +188,15 @@ i386nto_regset_fill (int regset, char *data)
        {
          int offset = nto_reg_offset (regno);
          if (offset != -1)
-           regcache_raw_collect (current_regcache, regno, data + offset);
+           regcache_raw_collect (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);
+       i387_collect_fxsave (regcache, -1, data);
       else
-       i387_fill_fsave (data, -1);
+       i387_collect_fsave (regcache, -1, data);
     }
   else
     return -1;
@@ -203,13 +204,13 @@ i386nto_regset_fill (int regset, char *data)
   return 0;
 }
 
-/* Return whether the frame preceding NEXT_FRAME corresponds to a QNX
-   Neutrino sigtramp routine.  */
+/* Return whether THIS_FRAME corresponds to a QNX Neutrino sigtramp
+   routine.  */
 
 static int
-i386nto_sigtramp_p (struct frame_info *next_frame)
+i386nto_sigtramp_p (struct frame_info *this_frame)
 {
-  CORE_ADDR pc = frame_pc_unwind (next_frame);
+  CORE_ADDR pc = get_frame_pc (this_frame);
   char *name;
 
   find_pc_partial_function (pc, &name, NULL, NULL);
@@ -218,16 +219,16 @@ i386nto_sigtramp_p (struct frame_info *next_frame)
 
 #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.  */
+/* Assuming THIS_FRAME is a QNX Neutrino sigtramp routine, return the
+   address of the associated sigcontext structure.  */
 
 static CORE_ADDR
-i386nto_sigcontext_addr (struct frame_info *next_frame)
+i386nto_sigcontext_addr (struct frame_info *this_frame)
 {
   char buf[4];
   CORE_ADDR sp;
 
-  frame_unwind_register (next_frame, I386_ESP_REGNUM, buf);
+  get_frame_register (this_frame, I386_ESP_REGNUM, buf);
   sp = extract_unsigned_integer (buf, 4);
 
   return sp + I386_NTO_SIGCONTEXT_OFFSET;
@@ -251,6 +252,7 @@ static void
 i386nto_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  static struct target_so_ops nto_svr4_so_ops;
 
   /* Deal with our strange signals.  */
   nto_initialize_signals ();
@@ -277,14 +279,25 @@ i386nto_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   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;
+  /* Initialize this lazily, to avoid an initialization order
+     dependency on solib-svr4.c's _initialize routine.  */
+  if (nto_svr4_so_ops.in_dynsym_resolve_code == NULL)
+    {
+      nto_svr4_so_ops = svr4_so_ops;
+
+      /* Our loader handles solib relocations differently than svr4.  */
+      nto_svr4_so_ops.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;
+      /* Supply a nice function to find our solibs.  */
+      nto_svr4_so_ops.find_and_open_solib
+        = nto_find_and_open_solib;
 
-  /* Our linker code is in libc.  */
-  TARGET_SO_IN_DYNSYM_RESOLVE_CODE = nto_in_dynsym_resolve_code;
+      /* Our linker code is in libc.  */
+      nto_svr4_so_ops.in_dynsym_resolve_code
+        = nto_in_dynsym_resolve_code;
+    }
+  set_solib_ops (gdbarch, &nto_svr4_so_ops);
 
   nto_set_target (&i386_nto_target);
 }