* target.h (struct section_table): Rename to ...
[deliverable/binutils-gdb.git] / gdb / arch-utils.c
index 73e45205a2bd38031b14d020baeba154435f9fa7..c1ea9da3636cec98d6b05fdbede3a0ee9e441042 100644 (file)
@@ -1,13 +1,13 @@
 /* Dynamic architecture support for GDB, the GNU debugger.
 
-   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
-   Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+   2008, 2009 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 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,
@@ -16,9 +16,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 "gdbcore.h"
 #include "osabi.h"
 #include "target-descriptions.h"
+#include "objfiles.h"
 
 #include "version.h"
 
 #include "floatformat.h"
 
-int
-always_use_struct_convention (int gcc_p, struct type *value_type)
-{
-  return 1;
-}
 
-enum return_value_convention
-legacy_return_value (struct gdbarch *gdbarch, struct type *valtype,
-                    struct regcache *regcache, gdb_byte *readbuf,
-                    const gdb_byte *writebuf)
+struct displaced_step_closure *
+simple_displaced_step_copy_insn (struct gdbarch *gdbarch,
+                                 CORE_ADDR from, CORE_ADDR to,
+                                 struct regcache *regs)
 {
-  /* NOTE: cagney/2004-06-13: The gcc_p parameter to
-     USE_STRUCT_CONVENTION isn't used.  */
-  int struct_return = ((TYPE_CODE (valtype) == TYPE_CODE_STRUCT
-                       || TYPE_CODE (valtype) == TYPE_CODE_UNION
-                       || TYPE_CODE (valtype) == TYPE_CODE_ARRAY)
-                      && gdbarch_deprecated_use_struct_convention
-                           (current_gdbarch, 0, valtype));
+  size_t len = gdbarch_max_insn_length (gdbarch);
+  gdb_byte *buf = xmalloc (len);
 
-  if (writebuf != NULL)
-    {
-      gdb_assert (!struct_return);
-      /* NOTE: cagney/2004-06-13: See stack.c:return_command.  Old
-        architectures don't expect store_return_value to handle small
-        structures.  Should not be called with such types.  */
-      gdb_assert (TYPE_CODE (valtype) != TYPE_CODE_STRUCT
-                 && TYPE_CODE (valtype) != TYPE_CODE_UNION);
-      gdbarch_store_return_value (current_gdbarch, valtype, regcache, writebuf);
-    }
+  read_memory (from, buf, len);
+  write_memory (to, buf, len);
 
-  if (readbuf != NULL)
+  if (debug_displaced)
     {
-      gdb_assert (!struct_return);
-      gdbarch_extract_return_value (current_gdbarch,
-                                   valtype, regcache, readbuf);
+      fprintf_unfiltered (gdb_stdlog, "displaced: copy 0x%s->0x%s: ",
+                          paddr_nz (from), paddr_nz (to));
+      displaced_step_dump_bytes (gdb_stdlog, buf, len);
     }
 
-  if (struct_return)
-    return RETURN_VALUE_STRUCT_CONVENTION;
-  else
-    return RETURN_VALUE_REGISTER_CONVENTION;
+  return (struct displaced_step_closure *) buf;
+}
+
+
+void
+simple_displaced_step_free_closure (struct gdbarch *gdbarch,
+                                    struct displaced_step_closure *closure)
+{
+  xfree (closure);
+}
+
+
+CORE_ADDR
+displaced_step_at_entry_point (struct gdbarch *gdbarch)
+{
+  CORE_ADDR addr;
+  int bp_len;
+
+  addr = entry_point_address ();
+
+  /* Make certain that the address points at real code, and not a
+     function descriptor.  */
+  addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr, &current_target);
+
+  /* Inferior calls also use the entry point as a breakpoint location.
+     We don't want displaced stepping to interfere with those
+     breakpoints, so leave space.  */
+  gdbarch_breakpoint_from_pc (gdbarch, &addr, &bp_len);
+  addr += bp_len * 2;
+
+  return addr;
 }
 
 int
-legacy_register_sim_regno (int regnum)
+legacy_register_sim_regno (struct gdbarch *gdbarch, int regnum)
 {
   /* Only makes sense to supply raw registers.  */
-  gdb_assert (regnum >= 0 && regnum < gdbarch_num_regs (current_gdbarch));
+  gdb_assert (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch));
   /* NOTE: cagney/2002-05-13: The old code did it this way and it is
      suspected that some GDB/SIM combinations may rely on this
      behavour.  The default should be one2one_register_sim_regno
      (below).  */
-  if (gdbarch_register_name (current_gdbarch, regnum) != NULL
-      && gdbarch_register_name (current_gdbarch, regnum)[0] != '\0')
+  if (gdbarch_register_name (gdbarch, regnum) != NULL
+      && gdbarch_register_name (gdbarch, regnum)[0] != '\0')
     return regnum;
   else
     return LEGACY_SIM_REGNO_IGNORE;
@@ -138,7 +146,7 @@ core_addr_greaterthan (CORE_ADDR lhs, CORE_ADDR rhs)
 /* Misc helper functions for targets. */
 
 CORE_ADDR
-core_addr_identity (CORE_ADDR addr)
+core_addr_identity (struct gdbarch *gdbarch, CORE_ADDR addr)
 {
   return addr;
 }
@@ -151,7 +159,7 @@ convert_from_func_ptr_addr_identity (struct gdbarch *gdbarch, CORE_ADDR addr,
 }
 
 int
-no_op_reg_to_regnum (int reg)
+no_op_reg_to_regnum (struct gdbarch *gdbarch, int reg)
 {
   return reg;
 }
@@ -169,17 +177,18 @@ default_coff_make_msymbol_special (int val, struct minimal_symbol *msym)
 }
 
 int
-cannot_register_not (int regnum)
+cannot_register_not (struct gdbarch *gdbarch, int regnum)
 {
   return 0;
 }
 
 /* Legacy version of target_virtual_frame_pointer().  Assumes that
-   there is an DEPRECATED_FP_REGNUM and that it is the same, cooked or
+   there is an gdbarch_deprecated_fp_regnum and that it is the same, cooked or
    raw.  */
 
 void
-legacy_virtual_frame_pointer (CORE_ADDR pc,
+legacy_virtual_frame_pointer (struct gdbarch *gdbarch, 
+                             CORE_ADDR pc,
                              int *frame_regnum,
                              LONGEST *frame_offset)
 {
@@ -188,13 +197,14 @@ legacy_virtual_frame_pointer (CORE_ADDR pc,
      register and an offset can determine this.  I think it should
      instead generate a byte code expression as that would work better
      with things like Dwarf2's CFI.  */
-  if (DEPRECATED_FP_REGNUM >= 0
-      && DEPRECATED_FP_REGNUM < gdbarch_num_regs (current_gdbarch))
-    *frame_regnum = DEPRECATED_FP_REGNUM;
-  else if (gdbarch_sp_regnum (current_gdbarch) >= 0
-          && gdbarch_sp_regnum (current_gdbarch)
-               < gdbarch_num_regs (current_gdbarch))
-    *frame_regnum = gdbarch_sp_regnum (current_gdbarch);
+  if (gdbarch_deprecated_fp_regnum (gdbarch) >= 0
+      && gdbarch_deprecated_fp_regnum (gdbarch)
+          < gdbarch_num_regs (gdbarch))
+    *frame_regnum = gdbarch_deprecated_fp_regnum (gdbarch);
+  else if (gdbarch_sp_regnum (gdbarch) >= 0
+          && gdbarch_sp_regnum (gdbarch)
+               < gdbarch_num_regs (gdbarch))
+    *frame_regnum = gdbarch_sp_regnum (gdbarch);
   else
     /* Should this be an internal error?  I guess so, it is reflecting
        an architectural limitation in the current design.  */
@@ -204,7 +214,8 @@ legacy_virtual_frame_pointer (CORE_ADDR pc,
 
 \f
 int
-generic_convert_register_p (int regnum, struct type *type)
+generic_convert_register_p (struct gdbarch *gdbarch, int regnum,
+                           struct type *type)
 {
   return 0;
 }
@@ -455,7 +466,19 @@ set_architecture (char *ignore_args, int from_tty, struct cmd_list_element *c)
 int
 gdbarch_update_p (struct gdbarch_info info)
 {
-  struct gdbarch *new_gdbarch = gdbarch_find_by_info (info);
+  struct gdbarch *new_gdbarch;
+
+  /* Check for the current file.  */
+  if (info.abfd == NULL)
+    info.abfd = exec_bfd;
+  if (info.abfd == NULL)
+    info.abfd = core_bfd;
+
+  /* Check for the current target description.  */
+  if (info.target_desc == NULL)
+    info.target_desc = target_current_description ();
+
+  new_gdbarch = gdbarch_find_by_info (info);
 
   /* If there no architecture by that name, reject the request.  */
   if (new_gdbarch == NULL)
@@ -468,12 +491,12 @@ gdbarch_update_p (struct gdbarch_info info)
 
   /* If it is the same old architecture, accept the request (but don't
      swap anything).  */
-  if (new_gdbarch == current_gdbarch)
+  if (new_gdbarch == target_gdbarch)
     {
       if (gdbarch_debug)
        fprintf_unfiltered (gdb_stdlog, "gdbarch_update_p: "
-                           "Architecture 0x%08lx (%s) unchanged\n",
-                           (long) new_gdbarch,
+                           "Architecture %s (%s) unchanged\n",
+                           host_address_to_string (new_gdbarch),
                            gdbarch_bfd_arch_info (new_gdbarch)->printable_name);
       return 1;
     }
@@ -481,8 +504,8 @@ gdbarch_update_p (struct gdbarch_info info)
   /* It's a new architecture, swap it in.  */
   if (gdbarch_debug)
     fprintf_unfiltered (gdb_stdlog, "gdbarch_update_p: "
-                       "New architecture 0x%08lx (%s) selected\n",
-                       (long) new_gdbarch,
+                       "New architecture %s (%s) selected\n",
+                       host_address_to_string (new_gdbarch),
                        gdbarch_bfd_arch_info (new_gdbarch)->printable_name);
   deprecated_current_gdbarch_select_hack (new_gdbarch);
 
@@ -495,17 +518,7 @@ gdbarch_update_p (struct gdbarch_info info)
 struct gdbarch *
 gdbarch_from_bfd (bfd *abfd)
 {
-  struct gdbarch *old_gdbarch = current_gdbarch;
-  struct gdbarch *new_gdbarch;
   struct gdbarch_info info;
-
-  /* If we call gdbarch_find_by_info without filling in info.abfd,
-     then it will use the global exec_bfd.  That's fine if we don't
-     have one of those either.  And that's the only time we should
-     reach here with a NULL ABFD argument - when we are discarding
-     the executable.  */
-  gdb_assert (abfd != NULL || exec_bfd == NULL);
-
   gdbarch_info_init (&info);
   info.abfd = abfd;
   return gdbarch_find_by_info (info);
@@ -517,9 +530,14 @@ gdbarch_from_bfd (bfd *abfd)
 void
 set_gdbarch_from_file (bfd *abfd)
 {
+  struct gdbarch_info info;
   struct gdbarch *gdbarch;
 
-  gdbarch = gdbarch_from_bfd (abfd);
+  gdbarch_info_init (&info);
+  info.abfd = abfd;
+  info.target_desc = target_current_description ();
+  gdbarch = gdbarch_find_by_info (info);
+
   if (gdbarch == NULL)
     error (_("Architecture of file not recognized."));
   deprecated_current_gdbarch_select_hack (gdbarch);
@@ -611,6 +629,7 @@ initialize_current_architecture (void)
     }
 
   info.byte_order = default_byte_order;
+  info.byte_order_for_code = info.byte_order;
 
   if (! gdbarch_update_p (info))
     internal_error (__FILE__, __LINE__,
@@ -649,6 +668,7 @@ gdbarch_info_init (struct gdbarch_info *info)
 {
   memset (info, 0, sizeof (struct gdbarch_info));
   info->byte_order = BFD_ENDIAN_UNKNOWN;
+  info->byte_order_for_code = info->byte_order;
   info->osabi = GDB_OSABI_UNINITIALIZED;
 }
 
@@ -659,14 +679,6 @@ gdbarch_info_init (struct gdbarch_info *info)
 void
 gdbarch_info_fill (struct gdbarch_info *info)
 {
-  /* Check for the current file.  */
-  if (info->abfd == NULL)
-    info->abfd = exec_bfd;
-
-  /* Check for the current target description.  */
-  if (info->target_desc == NULL)
-    info->target_desc = target_current_description ();
-
   /* "(gdb) set architecture ...".  */
   if (info->bfd_arch_info == NULL
       && target_architecture_user)
@@ -698,6 +710,7 @@ gdbarch_info_fill (struct gdbarch_info *info)
   /* From the default.  */
   if (info->byte_order == BFD_ENDIAN_UNKNOWN)
     info->byte_order = default_byte_order;
+  info->byte_order_for_code = info->byte_order;
 
   /* "(gdb) set osabi ...".  Handled by gdbarch_lookup_osabi.  */
   if (info->osabi == GDB_OSABI_UNINITIALIZED)
This page took 0.029524 seconds and 4 git commands to generate.