This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[rfc] Framework for "target descriptions" from the target, arch, etc


This is an infrastructure patch; applying it won't change any behavior
until you get to the two patches I'm going to post next, which add neat
features.

It doesn't include any documentation for the internals manual.  I promise to
fix that, but I have a bunch of patches on top of this one which keep adding
new things; I'd rather not write documentation that makes sense for each
piece in isolation, so I'm planning to do that at the end.

This patch causes a target hook (i.e. a method in struct target_ops) which
is called when creating or connecting to a new target. That hook may return
a "target description".  If it does, the current gdbarch (which has no
associated target description) is replaced with one based on the new target
description.  Right now, these descriptions are not very substantial:

+struct target_desc
+{
+  /* The architecture reported by the target, if any.  */
+  const struct bfd_arch_info *arch;
+};

Later patches will add more members.  However, that one is enough to do
something neat: auto-detect when we connect to an i386 remote target whether
it's i386:i386 or i386:x86-64.  I have that patch, and a similar one for
MIPS/MIPS64 which adds named properties to the target_desc, queued up to
post in a moment.  I also have detailed XML descriptions queued up for
later; those add target-defined types and target-defined registers to the
mix.

Something I haven't implemented yet, but probably will before posting the
XML bits: this is enough to implement a remote target which can tell you its
architecture!  Pretty neat, though a little tricky to get right.  What we
ought to do at that point is validate that the remote target and the
selected executable have sufficiently compatible architectures.  Then
GDB will be able to warn me when I connect a MIPS cross GDB to an i386
gdbserver by accident (which I do probably once a week).

The target is free to construct a struct target_desc in whatever way it
pleases, from whatever information it pleases; the interface exposes
constructors, though not the struct contents.

Tested variously on x86_64, ARM, and MIPS GNU/Linux.  All comments welcome!

-- 
Daniel Jacobowitz
CodeSourcery

2006-11-09  Daniel Jacobowitz  <dan@codesourcery.com>

	* Makefile.in (SFILES): Add new and missed files.
	(target_descriptions_h): New.
	(COMMON_OBS): Add target-descriptions.o.
	(arch-utils.o, infcmd.o, remote.o, target.o): Update.
	(target-descriptions.o): New.
	* arch-utils.c (gdbarch_info_fill): Check for a target
	description.  Optionally fetch the architecture from it.
	* target-descriptions.c, target-descriptions.h: New files.
	* gdbarch.sh: Add target_desc to info.  Declare it in gdbarch.h.
	Correct typos.
	(gdbarch_list_lookup_by_info): Check target_desc.
	* gdbarch.c, gdbarch.h: Regenerated.
	* target.c (update_current_target): Mention to_read_description.
	(target_pre_inferior): Call target_clear_description.
	(target_read_description): New.
	* target.h (struct target_ops): Add to_read_description.
	(target_read_description): New prototype.
	* infcmd.c (post_create_inferior): Call target_find_description.
	* remote.c (remote_open_1): Likewise.
	(extended_remote_create_inferior): Add a comment.
	(extended_remote_async_create_inferior): Likewise.

---
 gdb/Makefile.in           |   19 +++--
 gdb/arch-utils.c          |   13 +++-
 gdb/gdbarch.c             |   24 ++++++-
 gdb/gdbarch.h             |   15 +++-
 gdb/gdbarch.sh            |   23 ++++---
 gdb/infcmd.c              |    7 ++
 gdb/remote.c              |   21 ++++++
 gdb/target-descriptions.c |  149 ++++++++++++++++++++++++++++++++++++++++++++++
 gdb/target-descriptions.h |   60 ++++++++++++++++++
 gdb/target.c              |   26 ++++++++
 gdb/target.h              |    7 ++
 11 files changed, 340 insertions(+), 24 deletions(-)

Index: src/gdb/Makefile.in
===================================================================
--- src.orig/gdb/Makefile.in	2006-11-09 10:24:48.000000000 -0500
+++ src/gdb/Makefile.in	2006-11-09 10:27:45.000000000 -0500
@@ -516,7 +516,7 @@ TARGET_FLAGS_TO_PASS = \
 # SFILES is used in building the distribution archive.
 
 SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c  \
-	ax-general.c ax-gdb.c \
+	auxv.c ax-general.c ax-gdb.c \
 	bcache.c \
 	bfd-target.c \
 	block.c blockframe.c breakpoint.c buildsym.c \
@@ -554,7 +554,8 @@ SFILES = ada-exp.y ada-lang.c ada-typepr
 	solib.c solib-null.c source.c \
 	stabsread.c stack.c std-regs.c symfile.c symfile-mem.c symmisc.c \
 	symtab.c \
-	target.c target-memory.c thread.c top.c tracepoint.c \
+	target.c target-descriptions.c target-memory.c \
+	thread.c top.c tracepoint.c \
 	trad-frame.c \
 	tramp-frame.c \
 	typeprint.c \
@@ -805,6 +806,7 @@ stack_h = stack.h
 symfile_h = symfile.h
 symtab_h = symtab.h
 target_h = target.h $(bfd_h) $(symtab_h) $(dcache_h) $(memattr_h) $(vec_h)
+target_descriptions_h = target-descriptions.h
 terminal_h = terminal.h
 top_h = top.h
 tracepoint_h = tracepoint.h
@@ -965,7 +967,8 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $
 	trad-frame.o \
 	tramp-frame.o \
 	solib.o solib-null.o \
-	prologue-value.o memory-map.o xml-support.o target-memory.o
+	prologue-value.o memory-map.o xml-support.o \
+	target-descriptions.o target-memory.o
 
 TSOBS = inflow.o
 
@@ -1779,7 +1782,7 @@ annotate.o: annotate.c $(defs_h) $(annot
 arch-utils.o: arch-utils.c $(defs_h) $(arch_utils_h) $(buildsym_h) \
 	$(gdbcmd_h) $(inferior_h) $(gdb_string_h) $(regcache_h) \
 	$(gdb_assert_h) $(sim_regno_h) $(gdbcore_h) $(osabi_h) $(version_h) \
-	$(floatformat_h)
+	$(floatformat_h) $(target_descriptions_h)
 arm-linux-nat.o: arm-linux-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) \
 	$(gdb_string_h) $(regcache_h) $(arm_tdep_h) $(gregset_h) \
 	$(target_h) $(linux_nat_h) $(gdb_proc_service_h) $(arm_linux_tdep_h)
@@ -2172,7 +2175,7 @@ infcmd.o: infcmd.c $(defs_h) $(gdb_strin
 	$(symfile_h) $(gdbcore_h) $(target_h) $(language_h) $(symfile_h) \
 	$(objfiles_h) $(completer_h) $(ui_out_h) $(event_top_h) \
 	$(parser_defs_h) $(regcache_h) $(reggroups_h) $(block_h) \
-	$(solib_h) $(gdb_assert_h) $(observer_h)
+	$(solib_h) $(gdb_assert_h) $(observer_h) $(target_descriptions_h)
 inf-loop.o: inf-loop.c $(defs_h) $(inferior_h) $(target_h) $(event_loop_h) \
 	$(event_top_h) $(inf_loop_h) $(remote_h) $(exceptions_h)
 inflow.o: inflow.c $(defs_h) $(frame_h) $(inferior_h) $(command_h) \
@@ -2506,7 +2509,7 @@ remote.o: remote.c $(defs_h) $(gdb_strin
 	$(gdb_stabs_h) $(gdbthread_h) $(remote_h) $(regcache_h) $(value_h) \
 	$(gdb_assert_h) $(event_loop_h) $(event_top_h) $(inf_loop_h) \
 	$(serial_h) $(gdbcore_h) $(remote_fileio_h) $(solib_h) $(observer_h) \
-	$(cli_decode_h) $(cli_setshow_h) $(memory_map_h)
+	$(cli_decode_h) $(cli_setshow_h) $(memory_map_h) $(target_descriptions_h)
 remote-e7000.o: remote-e7000.c $(defs_h) $(gdbcore_h) $(gdbarch_h) \
 	$(inferior_h) $(target_h) $(value_h) $(command_h) $(gdb_string_h) \
 	$(exceptions_h) $(gdbcmd_h) $(serial_h) $(remote_utils_h) \
@@ -2758,7 +2761,9 @@ symtab.o: symtab.c $(defs_h) $(symtab_h)
 target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \
 	$(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
 	$(gdb_wait_h) $(dcache_h) $(regcache_h) $(gdb_assert_h) $(gdbcore_h) \
-	$(exceptions_h)
+	$(exceptions_h) $(target_descriptions_h)
+target-descriptions.o: target-descriptions.c $(defs_h) $(arch_utils_h) \
+	$(target_h) $(target_descriptions_h) $(gdb_assert_h)
 target-memory.o: target-memory.c $(defs_h) $(vec_h) $(target_h) \
 	$(memory_map_h) $(gdb_assert_h)
 thread.o: thread.c $(defs_h) $(symtab_h) $(frame_h) $(inferior_h) \
Index: src/gdb/arch-utils.c
===================================================================
--- src.orig/gdb/arch-utils.c	2006-11-09 10:24:48.000000000 -0500
+++ src/gdb/arch-utils.c	2006-11-09 10:27:45.000000000 -0500
@@ -1,6 +1,6 @@
 /* Dynamic architecture support for GDB, the GNU debugger.
 
-   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -32,6 +32,7 @@
 #include "sim-regno.h"
 #include "gdbcore.h"
 #include "osabi.h"
+#include "target-descriptions.h"
 
 #include "version.h"
 
@@ -688,15 +689,25 @@ gdbarch_info_fill (struct gdbarch_info *
   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)
     info->bfd_arch_info = target_architecture_user;
+  /* From the file.  */
   if (info->bfd_arch_info == NULL
       && info->abfd != NULL
       && bfd_get_arch (info->abfd) != bfd_arch_unknown
       && bfd_get_arch (info->abfd) != bfd_arch_obscure)
     info->bfd_arch_info = bfd_get_arch_info (info->abfd);
+  /* From the architecture.  */
+  if (info->bfd_arch_info == NULL
+      && info->target_desc != NULL
+      && tdesc_architecture (info->target_desc) != NULL)
+    info->bfd_arch_info = tdesc_architecture (info->target_desc);
   /* From the default.  */
   if (info->bfd_arch_info == NULL)
     info->bfd_arch_info = default_bfd_arch;
Index: src/gdb/target-descriptions.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/gdb/target-descriptions.c	2006-11-09 10:27:45.000000000 -0500
@@ -0,0 +1,149 @@
+/* Target description support for GDB.
+
+   Copyright (C) 2006
+   Free Software Foundation, Inc.
+
+   Contributed by CodeSourcery.
+
+   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., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "target.h"
+#include "target-descriptions.h"
+
+#include "gdb_assert.h"
+
+/* Types.  */
+
+struct target_desc
+{
+  /* The architecture reported by the target, if any.  */
+  const struct bfd_arch_info *arch;
+};
+
+/* Global state.  These variables are associated with the current
+   target; if GDB adds support for multiple simultaneous targets, then
+   these variables should become target-specific data.  */
+
+/* A flag indicating that a description has already been fetched from
+   the current target, so it should not be queried again.  */
+
+static int target_desc_fetched;
+
+/* The description fetched from the current target, or NULL if the
+   current target did not supply any description.  Only valid when
+   target_desc_fetched is set.  Only the description initialization
+   code should access this; normally, the description should be
+   accessed through the gdbarch object.  */
+
+static const struct target_desc *current_target_desc;
+
+/* Fetch the current target's description, and switch the current
+   architecture to one which incorporates that description.  */
+
+void
+target_find_description (void)
+{
+  /* If we've already fetched a description from the target, don't do
+     it again.  This allows a target to fetch the description early,
+     during its to_open or to_create_inferior, if it needs extra
+     information about the target to initialize.  */
+  if (target_desc_fetched)
+    return;
+
+  /* The current architecture should not have any target description
+     specified.  It should have been cleared, e.g. when we
+     disconnected from the previous target.  */
+  gdb_assert (gdbarch_target_desc (current_gdbarch) == NULL);
+
+  current_target_desc = target_read_description (&current_target);
+
+  /* If a non-NULL description was returned, then update the current
+     architecture.  */
+  if (current_target_desc)
+    {
+      struct gdbarch_info info;
+
+      gdbarch_info_init (&info);
+      info.target_desc = current_target_desc;
+      if (!gdbarch_update_p (info))
+	warning (_("Could not use target-supplied description"));
+    }
+
+  /* Now that we know this description is usable, record that we
+     fetched it.  */
+  target_desc_fetched = 1;
+}
+
+/* Discard any description fetched from the current target, and switch
+   the current architecture to one with no target description.  */
+
+void
+target_clear_description (void)
+{
+  struct gdbarch_info info;
+
+  if (!target_desc_fetched)
+    return;
+
+  target_desc_fetched = 0;
+  current_target_desc = NULL;
+
+  gdbarch_info_init (&info);
+  if (!gdbarch_update_p (info))
+    internal_error (__FILE__, __LINE__,
+		    _("Could not remove target-supplied description"));
+}
+
+/* Return the global current target description.  This should only be
+   used by gdbarch initialization code; most access should be through
+   an existing gdbarch.  */
+
+const struct target_desc *
+target_current_description (void)
+{
+  if (target_desc_fetched)
+    return current_target_desc;
+
+  return NULL;
+}
+
+/* Return the BFD architecture associated with this target
+   description, or NULL if no architecture was specified.  */
+
+const struct bfd_arch_info *
+tdesc_architecture (const struct target_desc *target_desc)
+{
+  return target_desc->arch;
+}
+
+/* Methods for constructing a target description.  */
+
+struct target_desc *
+allocate_target_description (void)
+{
+  return XZALLOC (struct target_desc);
+}
+
+void
+set_tdesc_architecture (struct target_desc *target_desc,
+			const struct bfd_arch_info *arch)
+{
+  target_desc->arch = arch;
+}
Index: src/gdb/target-descriptions.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/gdb/target-descriptions.h	2006-11-09 10:27:45.000000000 -0500
@@ -0,0 +1,60 @@
+/* Target description support for GDB.
+
+   Copyright (C) 2006
+   Free Software Foundation, Inc.
+
+   Contributed by CodeSourcery.
+
+   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., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+#ifndef TARGET_DESCRIPTIONS_H
+#define TARGET_DESCRIPTIONS_H 1
+
+struct target_desc;
+
+/* Fetch the current target's description, and switch the current
+   architecture to one which incorporates that description.  */
+
+void target_find_description (void);
+
+/* Discard any description fetched from the current target, and switch
+   the current architecture to one with no target description.  */
+
+void target_clear_description (void);
+
+/* Return the global current target description.  This should only be
+   used by gdbarch initialization code; most access should be through
+   an existing gdbarch.  */
+
+const struct target_desc *target_current_description (void);
+
+/* Accessors for target descriptions.  */
+
+/* Return the BFD architecture associated with this target
+   description, or NULL if no architecture was specified.  */
+
+const struct bfd_arch_info *tdesc_architecture
+  (const struct target_desc *);
+
+/* Methods for constructing a target description.  */
+
+struct target_desc *allocate_target_description (void);
+void set_tdesc_architecture (struct target_desc *,
+			     const struct bfd_arch_info *);
+
+#endif /* TARGET_DESCRIPTIONS_H */
Index: src/gdb/gdbarch.c
===================================================================
--- src.orig/gdb/gdbarch.c	2006-11-09 10:24:48.000000000 -0500
+++ src/gdb/gdbarch.c	2006-11-09 10:27:45.000000000 -0500
@@ -2,8 +2,8 @@
 
 /* Dynamic architecture support for GDB, the GNU debugger.
 
-   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free
-   Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -92,6 +92,7 @@ struct gdbarch
   const struct bfd_arch_info * bfd_arch_info;
   int byte_order;
   enum gdb_osabi osabi;
+  const struct target_desc * target_desc;
 
   /* target specific vector. */
   struct gdbarch_tdep *tdep;
@@ -250,6 +251,7 @@ struct gdbarch startup_gdbarch =
   &bfd_default_arch_struct,  /* bfd_arch_info */
   BFD_ENDIAN_BIG,  /* byte_order */
   GDB_OSABI_UNKNOWN,  /* osabi */
+  0,  /* target_desc */
   /* target specific vector and its dump routine */
   NULL, NULL,
   /*per-architecture data-pointers and swap regions */
@@ -394,6 +396,7 @@ gdbarch_alloc (const struct gdbarch_info
   current_gdbarch->bfd_arch_info = info->bfd_arch_info;
   current_gdbarch->byte_order = info->byte_order;
   current_gdbarch->osabi = info->osabi;
+  current_gdbarch->target_desc = info->target_desc;
 
   /* Force the explicit initialization of these. */
   current_gdbarch->short_bit = 2*TARGET_CHAR_BIT;
@@ -1563,6 +1566,9 @@ gdbarch_dump (struct gdbarch *current_gd
                       "gdbarch_dump: store_return_value = <0x%lx>\n",
                       (long) current_gdbarch->store_return_value);
   fprintf_unfiltered (file,
+                      "gdbarch_dump: target_desc = %s\n",
+                      paddr_d ((long) current_gdbarch->target_desc));
+  fprintf_unfiltered (file,
                       "gdbarch_dump: gdbarch_unwind_dummy_id_p() = %d\n",
                       gdbarch_unwind_dummy_id_p (current_gdbarch));
   fprintf_unfiltered (file,
@@ -1647,6 +1653,15 @@ gdbarch_osabi (struct gdbarch *gdbarch)
   return gdbarch->osabi;
 }
 
+const struct target_desc *
+gdbarch_target_desc (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_target_desc called\n");
+  return gdbarch->target_desc;
+}
+
 int
 gdbarch_short_bit (struct gdbarch *gdbarch)
 {
@@ -3961,8 +3976,7 @@ register_gdbarch_init (enum bfd_architec
 }
 
 
-/* Look for an architecture using gdbarch_info.  Base search on only
-   BFD_ARCH_INFO and BYTE_ORDER. */
+/* Look for an architecture using gdbarch_info.  */
 
 struct gdbarch_list *
 gdbarch_list_lookup_by_info (struct gdbarch_list *arches,
@@ -3976,6 +3990,8 @@ gdbarch_list_lookup_by_info (struct gdba
 	continue;
       if (info->osabi != arches->gdbarch->osabi)
 	continue;
+      if (info->target_desc != arches->gdbarch->target_desc)
+	continue;
       return arches;
     }
   return NULL;
Index: src/gdb/gdbarch.h
===================================================================
--- src.orig/gdb/gdbarch.h	2006-11-09 10:24:48.000000000 -0500
+++ src/gdb/gdbarch.h	2006-11-09 10:27:45.000000000 -0500
@@ -2,8 +2,8 @@
 
 /* Dynamic architecture support for GDB, the GNU debugger.
 
-   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free
-   Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -50,6 +50,7 @@ struct disassemble_info;
 struct target_ops;
 struct obstack;
 struct bp_target_info;
+struct target_desc;
 
 extern struct gdbarch *current_gdbarch;
 
@@ -83,6 +84,9 @@ extern enum gdb_osabi gdbarch_osabi (str
 #define TARGET_OSABI (gdbarch_osabi (current_gdbarch))
 #endif
 
+extern const struct target_desc * gdbarch_target_desc (struct gdbarch *gdbarch);
+/* set_gdbarch_target_desc() - not applicable - pre-initialized. */
+
 
 /* The following are initialized by the target dependent code. */
 
@@ -1462,6 +1466,9 @@ struct gdbarch_info
 
   /* Use default: GDB_OSABI_UNINITIALIZED (-1).  */
   enum gdb_osabi osabi;
+
+  /* Use default: NULL (ZERO).  */
+  const struct target_desc *target_desc;
 };
 
 typedef struct gdbarch *(gdbarch_init_ftype) (struct gdbarch_info info, struct gdbarch_list *arches);
@@ -1486,11 +1493,11 @@ extern const char **gdbarch_printable_na
 /* Helper function.  Search the list of ARCHES for a GDBARCH that
    matches the information provided by INFO. */
 
-extern struct gdbarch_list *gdbarch_list_lookup_by_info (struct gdbarch_list *arches,  const struct gdbarch_info *info);
+extern struct gdbarch_list *gdbarch_list_lookup_by_info (struct gdbarch_list *arches, const struct gdbarch_info *info);
 
 
 /* Helper function.  Create a preliminary ``struct gdbarch''.  Perform
-   basic initialization using values obtained from the INFO andTDEP
+   basic initialization using values obtained from the INFO and TDEP
    parameters.  set_gdbarch_*() functions are called to complete the
    initialization of the object. */
 
Index: src/gdb/gdbarch.sh
===================================================================
--- src.orig/gdb/gdbarch.sh	2006-11-09 10:24:48.000000000 -0500
+++ src/gdb/gdbarch.sh	2006-11-09 10:27:45.000000000 -0500
@@ -2,8 +2,8 @@
 
 # Architecture commands for GDB, the GNU debugger.
 #
-# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free
-# Software Foundation, Inc.
+# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+# Free Software Foundation, Inc.
 #
 # This file is part of GDB.
 #
@@ -372,6 +372,8 @@ i:TARGET_ARCHITECTURE:const struct bfd_a
 i:TARGET_BYTE_ORDER:int:byte_order:::BFD_ENDIAN_BIG
 #
 i:TARGET_OSABI:enum gdb_osabi:osabi:::GDB_OSABI_UNKNOWN
+#
+i::const struct target_desc *:target_desc:::::::paddr_d ((long) current_gdbarch->target_desc)
 # Number of bits in a char or unsigned char for the target machine.
 # Just like CHAR_BIT in <limits.h> but describes the target machine.
 # v:TARGET_CHAR_BIT:int:char_bit::::8 * sizeof (char):8::0:
@@ -713,8 +715,8 @@ cat <<EOF
 
 /* Dynamic architecture support for GDB, the GNU debugger.
 
-   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free
-   Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -771,6 +773,7 @@ struct disassemble_info;
 struct target_ops;
 struct obstack;
 struct bp_target_info;
+struct target_desc;
 
 extern struct gdbarch *current_gdbarch;
 EOF
@@ -985,6 +988,9 @@ struct gdbarch_info
 
   /* Use default: GDB_OSABI_UNINITIALIZED (-1).  */
   enum gdb_osabi osabi;
+
+  /* Use default: NULL (ZERO).  */
+  const struct target_desc *target_desc;
 };
 
 typedef struct gdbarch *(gdbarch_init_ftype) (struct gdbarch_info info, struct gdbarch_list *arches);
@@ -1009,11 +1015,11 @@ extern const char **gdbarch_printable_na
 /* Helper function.  Search the list of ARCHES for a GDBARCH that
    matches the information provided by INFO. */
 
-extern struct gdbarch_list *gdbarch_list_lookup_by_info (struct gdbarch_list *arches,  const struct gdbarch_info *info);
+extern struct gdbarch_list *gdbarch_list_lookup_by_info (struct gdbarch_list *arches, const struct gdbarch_info *info);
 
 
 /* Helper function.  Create a preliminary \`\`struct gdbarch''.  Perform
-   basic initialization using values obtained from the INFO andTDEP
+   basic initialization using values obtained from the INFO and TDEP
    parameters.  set_gdbarch_*() functions are called to complete the
    initialization of the object. */
 
@@ -2023,8 +2029,7 @@ register_gdbarch_init (enum bfd_architec
 }
 
 
-/* Look for an architecture using gdbarch_info.  Base search on only
-   BFD_ARCH_INFO and BYTE_ORDER. */
+/* Look for an architecture using gdbarch_info.  */
 
 struct gdbarch_list *
 gdbarch_list_lookup_by_info (struct gdbarch_list *arches,
@@ -2038,6 +2043,8 @@ gdbarch_list_lookup_by_info (struct gdba
 	continue;
       if (info->osabi != arches->gdbarch->osabi)
 	continue;
+      if (info->target_desc != arches->gdbarch->target_desc)
+	continue;
       return arches;
     }
   return NULL;
Index: src/gdb/target.c
===================================================================
--- src.orig/gdb/target.c	2006-11-09 10:24:48.000000000 -0500
+++ src/gdb/target.c	2006-11-09 10:27:45.000000000 -0500
@@ -40,6 +40,7 @@
 #include "gdb_assert.h"
 #include "gdbcore.h"
 #include "exceptions.h"
+#include "target-descriptions.h"
 
 static void target_info (char *, int);
 
@@ -464,6 +465,7 @@ update_current_target (void)
       INHERIT (to_find_memory_regions, t);
       INHERIT (to_make_corefile_notes, t);
       INHERIT (to_get_thread_local_address, t);
+      /* Do not inherit to_read_description.  */
       INHERIT (to_magic, t);
       /* Do not inherit to_memory_map.  */
       /* Do not inherit to_flash_erase.  */
@@ -641,6 +643,7 @@ update_current_target (void)
   de_fault (to_async,
 	    (void (*) (void (*) (enum inferior_event_type, void*), void*))
 	    tcomplain);
+  current_target.to_read_description = NULL;
 #undef de_fault
 
   /* Finally, position the target-stack beneath the squashed
@@ -1598,6 +1601,8 @@ void
 target_pre_inferior (int from_tty)
 {
   invalidate_target_mem_regions ();
+
+  target_clear_description ();
 }
 
 /* This is to be called by the open routine before it does
@@ -1685,6 +1690,27 @@ target_follow_fork (int follow_child)
 		  "could not find a target to follow fork");
 }
 
+/* Look for a target which can describe architectural features, starting
+   from TARGET.  If we find one, return its description.  */
+
+const struct target_desc *
+target_read_description (struct target_ops *target)
+{
+  struct target_ops *t;
+
+  for (t = target; t != NULL; t = t->beneath)
+    if (t->to_read_description != NULL)
+      {
+	const struct target_desc *tdesc;
+
+	tdesc = t->to_read_description (t);
+	if (tdesc)
+	  return tdesc;
+      }
+
+  return NULL;
+}
+
 /* Look through the list of possible targets for a target that can
    execute a run or attach command without any other data.  This is
    used to locate the default process stratum.
Index: src/gdb/target.h
===================================================================
--- src.orig/gdb/target.h	2006-11-09 10:24:48.000000000 -0500
+++ src/gdb/target.h	2006-11-09 10:27:45.000000000 -0500
@@ -492,6 +492,11 @@ struct target_ops
        equal to what was written.  */
     void (*to_flash_done) (struct target_ops *);
 
+    /* Describe the architecture-specific features of this target.
+       Returns the description found, or NULL if no description
+       was available.  */
+    const struct target_desc *(*to_read_description) (struct target_ops *ops);
+
     int to_magic;
     /* Need sub-structure for target machine related rather than comm related?
      */
@@ -1179,6 +1184,8 @@ extern int target_stopped_data_address_p
 #define target_stopped_data_address_p(CURRENT_TARGET) (1)
 #endif
 
+extern const struct target_desc *target_read_description (struct target_ops *);
+
 /* This will only be defined by a target that supports catching vfork events,
    such as HP-UX.
 
Index: src/gdb/infcmd.c
===================================================================
--- src.orig/gdb/infcmd.c	2006-11-09 10:24:48.000000000 -0500
+++ src/gdb/infcmd.c	2006-11-09 10:27:45.000000000 -0500
@@ -48,6 +48,7 @@
 #include <ctype.h>
 #include "gdb_assert.h"
 #include "observer.h"
+#include "target-descriptions.h"
 
 /* Functions exported for general use, in inferior.h: */
 
@@ -405,6 +406,12 @@ tty_command (char *file, int from_tty)
 void
 post_create_inferior (struct target_ops *target, int from_tty)
 {
+  /* If the target hasn't taken care of this already, do it now.
+     Targets which need to access registers during to_open,
+     to_create_inferior, or to_attach should do it earlier; but many
+     don't need to.  */
+  target_find_description ();
+
   if (exec_bfd)
     {
       /* Sometimes the platform-specific hook loads initial shared
Index: src/gdb/remote.c
===================================================================
--- src.orig/gdb/remote.c	2006-11-09 10:27:02.000000000 -0500
+++ src/gdb/remote.c	2006-11-09 10:27:45.000000000 -0500
@@ -45,6 +45,7 @@
 #include "solib.h"
 #include "cli/cli-decode.h"
 #include "cli/cli-setshow.h"
+#include "target-descriptions.h"
 
 #include <ctype.h>
 #include <sys/time.h>
@@ -2435,6 +2436,10 @@ remote_open_1 (char *name, int from_tty,
      which later probes to skip.  */
   remote_query_supported ();
 
+  /* Next, if the target can specify a description, read it.  We do
+     this before anything involving memory or registers.  */
+  target_find_description ();
+
   /* Without this, some commands which require an active target (such
      as kill) won't work.  This variable serves (at least) double duty
      as both the pid of the target process (if it has such), and as a
@@ -4954,6 +4959,14 @@ extended_remote_create_inferior (char *e
   /* Now restart the remote server.  */
   extended_remote_restart ();
 
+  /* NOTE: We don't need to recheck for a target description here; but
+     if we gain the ability to switch the remote executable we may
+     need to, if for instance we are running a process which requested
+     different emulated hardware from the operating system.  A
+     concrete example of this is ARM GNU/Linux, where some binaries
+     will have a legacy FPA coprocessor emulated and others may have
+     access to a hardware VFP unit.  */
+
   /* Now put the breakpoints back in.  This way we're safe if the
      restart function works via a unix fork on the remote side.  */
   insert_breakpoints ();
@@ -4979,6 +4992,14 @@ extended_remote_async_create_inferior (c
   /* Now restart the remote server.  */
   extended_remote_restart ();
 
+  /* NOTE: We don't need to recheck for a target description here; but
+     if we gain the ability to switch the remote executable we may
+     need to, if for instance we are running a process which requested
+     different emulated hardware from the operating system.  A
+     concrete example of this is ARM GNU/Linux, where some binaries
+     will have a legacy FPA coprocessor emulated and others may have
+     access to a hardware VFP unit.  */
+
   /* Now put the breakpoints back in.  This way we're safe if the
      restart function works via a unix fork on the remote side.  */
   insert_breakpoints ();


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]