summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog24
-rw-r--r--gdb/Makefile.in19
-rw-r--r--gdb/arch-utils.c8
-rw-r--r--gdb/gdbarch.c24
-rw-r--r--gdb/gdbarch.h15
-rwxr-xr-xgdb/gdbarch.sh23
-rw-r--r--gdb/infcmd.c7
-rw-r--r--gdb/remote.c21
-rw-r--r--gdb/target-descriptions.c131
-rw-r--r--gdb/target-descriptions.h52
-rw-r--r--gdb/target.c26
-rw-r--r--gdb/target.h7
12 files changed, 333 insertions, 24 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index d8c9eac3b5..ab8040e89c 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,27 @@
+2006-11-28 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.
+ * 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.
+
2006-11-29 Nick Roberts <nickrob@snap.net.nz>
* linux-thread-db.c: Include <signal.h>.
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index c2d47ad03b..c98e5b94c4 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -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-typeprint.c ada-valprint.c \
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 \
@@ -806,6 +807,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
@@ -967,7 +969,8 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
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
@@ -1783,7 +1786,7 @@ annotate.o: annotate.c $(defs_h) $(annotate_h) $(value_h) $(target_h) \
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)
@@ -2178,7 +2181,7 @@ infcmd.o: infcmd.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
$(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) \
@@ -2513,7 +2516,7 @@ remote.o: remote.c $(defs_h) $(gdb_string_h) $(inferior_h) $(bfd_h) \
$(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) \
@@ -2775,7 +2778,9 @@ symtab.o: symtab.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(gdbcore_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) \
diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c
index c1801c9a0f..9e3fb94c65 100644
--- a/gdb/arch-utils.c
+++ b/gdb/arch-utils.c
@@ -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,10 +689,15 @@ gdbarch_info_fill (struct gdbarch_info *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
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index 784816f300..6939312d83 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -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 *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_gdbarch, struct ui_file *file)
"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_architecture bfd_architecture,
}
-/* 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 gdbarch_list *arches,
continue;
if (info->osabi != arches->gdbarch->osabi)
continue;
+ if (info->target_desc != arches->gdbarch->target_desc)
+ continue;
return arches;
}
return NULL;
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 1bebaa6dc4..30ae3d0164 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -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 (struct gdbarch *gdbarch);
#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_names (void);
/* 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. */
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index a815f0476f..a3142ff33b 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -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_arch_info *:bfd_arch_info:::&bfd_default_
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_names (void);
/* 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_architecture bfd_architecture,
}
-/* 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 gdbarch_list *arches,
continue;
if (info->osabi != arches->gdbarch->osabi)
continue;
+ if (info->target_desc != arches->gdbarch->target_desc)
+ continue;
return arches;
}
return NULL;
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index b72d7d620f..5fd083eb99 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -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
diff --git a/gdb/remote.c b/gdb/remote.c
index 302fa3ee1f..e758412fe2 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -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>
@@ -2501,6 +2502,10 @@ remote_open_1 (char *name, int from_tty, struct target_ops *target,
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
@@ -5023,6 +5028,14 @@ extended_remote_create_inferior (char *exec_file, char *args,
/* 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 ();
@@ -5048,6 +5061,14 @@ extended_remote_async_create_inferior (char *exec_file, char *args,
/* 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 ();
diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c
new file mode 100644
index 0000000000..041d72be15
--- /dev/null
+++ b/gdb/target-descriptions.c
@@ -0,0 +1,131 @@
+/* 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
+{
+};
+
+/* 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;
+}
+
+/* Methods for constructing a target description. */
+
+struct target_desc *
+allocate_target_description (void)
+{
+ return XZALLOC (struct target_desc);
+}
diff --git a/gdb/target-descriptions.h b/gdb/target-descriptions.h
new file mode 100644
index 0000000000..bbcf879a86
--- /dev/null
+++ b/gdb/target-descriptions.h
@@ -0,0 +1,52 @@
+/* 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. */
+
+/* Methods for constructing a target description. */
+
+struct target_desc *allocate_target_description (void);
+
+#endif /* TARGET_DESCRIPTIONS_H */
diff --git a/gdb/target.c b/gdb/target.c
index 2062733037..349f1b6cb3 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -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
@@ -1602,6 +1605,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
@@ -1689,6 +1694,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.
diff --git a/gdb/target.h b/gdb/target.h
index 7be4aca5a0..412bf93c04 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -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 (struct target_ops *);
#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.