* target-descriptions.c (tdesc_predefined_types): New.
authorDaniel Jacobowitz <drow@false.org>
Mon, 15 Oct 2007 19:19:18 +0000 (19:19 +0000)
committerDaniel Jacobowitz <drow@false.org>
Mon, 15 Oct 2007 19:19:18 +0000 (19:19 +0000)
(tdesc_named_type): Use it.
(tdesc_type_id, maint_print_c_tdesc_cmd): New functions.
(_intialize_target_descriptions): Register "maint print c-tdesc".
* features/Makefile (XMLTOC, CFILES, GDB): New macros.
(cfiles, %.c): New rules.
* features/arm-with-iwmmxt.c, features/mips-linux.c,
features/mips64-linux.c: New generated files.

* arm-linux-nat.c: Include preparsed description instead of
"xml-support.h".
(super_xfer_partial, arm_linux_xfer_partial): Remove.
(arm_linux_read_description): New function.
(_initialize_arm_linux_nat): Set to_read_description instead of
to_xfer_partial.  Initialize preparsed description.
* config/arm/linux.mh (TDEP_XML): Delete.
* mips-linux-nat.c: Include preparsed descriptions instead of
"xml-support.h".
(super_xfer_partial, mips_linux_xfer_partial): Remove.
(mips_linux_read_description): New function.
(_initialize_mips_linux_nat): Set to_read_description instead of
to_xfer_partial.  Initialize preparsed description.
* config/mips/linux.mh (TDEP_XML): Delete.
* Makefile.in (XMLFILES): Remove $(TDEP_XML).
(features_headers, arm_with_iwmmxt_c, mips_linux_c)
(mips64_linux_c): New macros.
(arm-linux-nat.o, mips-linux-nat.o): Update.

* gdb.texinfo (Maintenance Commands): Document "maint print c-tdesc".

13 files changed:
gdb/ChangeLog
gdb/Makefile.in
gdb/arm-linux-nat.c
gdb/config/arm/linux.mh
gdb/config/mips/linux.mh
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/features/Makefile
gdb/features/arm-with-iwmmxt.c [new file with mode: 0644]
gdb/features/mips-linux.c [new file with mode: 0644]
gdb/features/mips64-linux.c [new file with mode: 0644]
gdb/mips-linux-nat.c
gdb/target-descriptions.c

index 4358bd0e161fd9b468aef50bb6bfd60121268770..a22186353cf4e3e5b0e6e92f31dc03421e2b08c1 100644 (file)
@@ -1,3 +1,33 @@
+2007-10-15  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * target-descriptions.c (tdesc_predefined_types): New.
+       (tdesc_named_type): Use it.
+       (tdesc_type_id, maint_print_c_tdesc_cmd): New functions.
+       (_intialize_target_descriptions): Register "maint print c-tdesc".
+       * features/Makefile (XMLTOC, CFILES, GDB): New macros.
+       (cfiles, %.c): New rules.
+       * features/arm-with-iwmmxt.c, features/mips-linux.c,
+       features/mips64-linux.c: New generated files.
+
+       * arm-linux-nat.c: Include preparsed description instead of
+       "xml-support.h".
+       (super_xfer_partial, arm_linux_xfer_partial): Remove.
+       (arm_linux_read_description): New function.
+       (_initialize_arm_linux_nat): Set to_read_description instead of
+       to_xfer_partial.  Initialize preparsed description.
+       * config/arm/linux.mh (TDEP_XML): Delete.
+       * mips-linux-nat.c: Include preparsed descriptions instead of
+       "xml-support.h".
+       (super_xfer_partial, mips_linux_xfer_partial): Remove.
+       (mips_linux_read_description): New function.
+       (_initialize_mips_linux_nat): Set to_read_description instead of
+       to_xfer_partial.  Initialize preparsed description.
+       * config/mips/linux.mh (TDEP_XML): Delete.
+       * Makefile.in (XMLFILES): Remove $(TDEP_XML).
+       (features_headers, arm_with_iwmmxt_c, mips_linux_c)
+       (mips64_linux_c): New macros.
+       (arm-linux-nat.o, mips-linux-nat.o): Update.
+
 2007-10-15  Pierre Muller  <muller@ics.u-strasbg.fr>
 
        * cp-abi.c (set_cp_abi_as_auto_default): ARI fix:
index 5a51f4c6b4ac5c2cb897b0667f207bed8bde0dfb..151d1393f36cbb676dd69e3c14f1eca57b22b6e7 100644 (file)
@@ -406,8 +406,7 @@ RUNTESTFLAGS=
 
 # XML files to build in to GDB.
 XMLFILES = $(srcdir)/features/gdb-target.dtd $(srcdir)/features/xinclude.dtd \
-       $(srcdir)/features/library-list.dtd \
-       $(TDEP_XML)
+       $(srcdir)/features/library-list.dtd
 
 # This is ser-unix.o for any system which supports a v7/BSD/SYSV/POSIX
 # interface to the serial port.  Hopefully if get ported to OS/2, VMS,
@@ -884,6 +883,12 @@ tui_wingeneral_h = $(srcdir)/tui/tui-wingeneral.h
 tui_win_h = $(srcdir)/tui/tui-win.h $(tui_data_h)
 tui_winsource_h = $(srcdir)/tui/tui-winsource.h $(tui_data_h)
 
+# gdb/features preparsed descriptions
+features_headers = $(defs_h) $(gdbtypes_h) $(target_descriptions_h)
+arm_with_iwmmxt_c = $(srcdir)/features/arm-with-iwmmxt.c $(features_headers)
+mips_linux_c = $(srcdir)/features/mips-linux.c $(features_headers)
+mips64_linux_c = $(srcdir)/features/mips64-linux.c $(features_headers)
+
 # Header files that need to have srcdir added.  Note that in the cases
 # where we use a macro like $(gdbcmd_h), things are carefully arranged
 # so that each .h file is listed exactly once (M-x tags-search works
@@ -1802,7 +1807,7 @@ arch-utils.o: arch-utils.c $(defs_h) $(arch_utils_h) $(buildsym_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) \
-       $(target_descriptions_h) $(xml_support_h)
+       $(target_descriptions_h) $(arm_with_iwmmxt_c)
 arm-linux-tdep.o: arm-linux-tdep.c $(defs_h) $(target_h) $(value_h) \
        $(gdbtypes_h) $(floatformat_h) $(gdbcore_h) $(frame_h) $(regcache_h) \
        $(doublest_h) $(solib_svr4_h) $(osabi_h) $(arm_tdep_h) \
@@ -2361,7 +2366,7 @@ mips-irix-tdep.o: mips-irix-tdep.c $(defs_h) $(osabi_h) $(elf_bfd_h)
 mips-linux-nat.o: mips-linux-nat.c $(defs_h) $(mips_tdep_h) $(target_h) \
        $(regcache_h) $(linux_nat_h) $(gdb_proc_service_h) $(gregset_h) \
        $(mips_linux_tdep_h) $(inferior_h) $(target_descriptions_h) \
-       $(xml_support_h)
+       $(mips_linux_c) $(mips64_linux_c)
 mips-linux-tdep.o: mips-linux-tdep.c $(defs_h) $(gdbcore_h) $(target_h) \
        $(solib_svr4_h) $(osabi_h) $(mips_tdep_h) $(gdb_string_h) \
        $(gdb_assert_h) $(frame_h) $(regcache_h) $(trad_frame_h) \
index 6f1056872a4642648217bf58379e7998a5aa9d75..bc005934a9bb919aa7bd63c586bfb05c0c24ee2e 100644 (file)
@@ -25,7 +25,6 @@
 #include "target.h"
 #include "linux-nat.h"
 #include "target-descriptions.h"
-#include "xml-support.h"
 
 #include "arm-tdep.h"
 #include "arm-linux-tdep.h"
@@ -41,6 +40,8 @@
 /* Defines ps_err_e, struct ps_prochandle.  */
 #include "gdb_proc_service.h"
 
+#include "features/arm-with-iwmmxt.c"
+
 #ifndef PTRACE_GET_THREAD_AREA
 #define PTRACE_GET_THREAD_AREA 22
 #endif
@@ -571,42 +572,23 @@ get_linux_version (unsigned int *vmajor,
   return ((*vmajor << 16) | (*vminor << 8) | *vrelease);
 }
 
-static LONGEST (*super_xfer_partial) (struct target_ops *, enum target_object,
-                                     const char *, gdb_byte *, const gdb_byte *,
-                                     ULONGEST, LONGEST);
-
-static LONGEST
-arm_linux_xfer_partial (struct target_ops *ops,
-                        enum target_object object,
-                        const char *annex,
-                        gdb_byte *readbuf, const gdb_byte *writebuf,
-                        ULONGEST offset, LONGEST len)
+static const struct target_desc *
+arm_linux_read_description (struct target_ops *ops)
 {
-  if (object == TARGET_OBJECT_AVAILABLE_FEATURES)
-    {
-      if (annex != NULL && strcmp (annex, "target.xml") == 0)
-       {
-         int ret;
-         char regbuf[IWMMXT_REGS_SIZE];
-
-         ret = ptrace (PTRACE_GETWMMXREGS, GET_THREAD_ID (inferior_ptid),
-                       0, regbuf);
-         if (ret < 0)
-           arm_linux_has_wmmx_registers = 0;
-         else
-           arm_linux_has_wmmx_registers = 1;
-
-         if (arm_linux_has_wmmx_registers)
-           annex = "arm-with-iwmmxt.xml";
-         else
-           return -1;
-       }
-
-      return xml_builtin_xfer_partial (annex, readbuf, writebuf, offset, len);
-    }
+  int ret;
+  char regbuf[IWMMXT_REGS_SIZE];
 
-  return super_xfer_partial (ops, object, annex, readbuf, writebuf,
-                            offset, len);
+  ret = ptrace (PTRACE_GETWMMXREGS, GET_THREAD_ID (inferior_ptid),
+               0, regbuf);
+  if (ret < 0)
+    arm_linux_has_wmmx_registers = 0;
+  else
+    arm_linux_has_wmmx_registers = 1;
+
+  if (arm_linux_has_wmmx_registers)
+    return tdesc_arm_with_iwmmxt;
+  else
+    return NULL;
 }
 
 void _initialize_arm_linux_nat (void);
@@ -625,10 +607,11 @@ _initialize_arm_linux_nat (void)
   t->to_fetch_registers = arm_linux_fetch_inferior_registers;
   t->to_store_registers = arm_linux_store_inferior_registers;
 
-  /* Override the default to_xfer_partial.  */
-  super_xfer_partial = t->to_xfer_partial;
-  t->to_xfer_partial = arm_linux_xfer_partial;
+  t->to_read_description = arm_linux_read_description;
 
   /* Register the target.  */
   linux_nat_add_target (t);
+
+  /* Initialize the standard target descriptions.  */
+  initialize_tdesc_arm_with_iwmmxt ();
 }
index adca462e5f06beddfc8b76d9cff0a283c7f75ab9..b708f4b1de463acffa1fe8de715c7f60908ba153 100644 (file)
@@ -5,7 +5,3 @@ NATDEPFILES= inf-ptrace.o fork-child.o arm-linux-nat.o gcore.o \
        proc-service.o linux-thread-db.o linux-nat.o linux-fork.o
 
 LOADLIBES= -ldl -rdynamic
-
-TDEP_XML = $(srcdir)/features/arm-with-iwmmxt.xml \
-       $(srcdir)/features/xscale-iwmmxt.xml \
-       $(srcdir)/features/arm-core.xml
index 01478b618c8d139a6ea6750ca5f6b2a92adf1103..32381a4aa0cc5537f20d207e219e784641599a0e 100644 (file)
@@ -5,12 +5,3 @@ NATDEPFILES= inf-ptrace.o fork-child.o mips-linux-nat.o \
        linux-nat.o linux-fork.o
 
 LOADLIBES = -ldl -rdynamic
-
-TDEP_XML = $(srcdir)/features/mips-cpu.xml \
-       $(srcdir)/features/mips-cp0.xml \
-       $(srcdir)/features/mips-fpu.xml \
-       $(srcdir)/features/mips-linux.xml \
-       $(srcdir)/features/mips64-cpu.xml \
-       $(srcdir)/features/mips64-cp0.xml \
-       $(srcdir)/features/mips64-fpu.xml \
-       $(srcdir)/features/mips64-linux.xml
index 7fa66e8fd4bad0e055e535946de8bb9fb17a5204..f3ae004681d6fd2b2eda40e583bba198e97f489f 100644 (file)
@@ -1,3 +1,7 @@
+2007-10-15  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * gdb.texinfo (Maintenance Commands): Document "maint print c-tdesc".
+
 2007-10-12  Ulrich Weigand  <uweigand@de.ibm.com>
 
        * gdbint.texi (Target Conditionals): Remove documentation
index 468d600c383b94f2a8e3e7e4f04970ecce5166a5..c42cc4842b7e23266c66f408a2ca0d58956bf63b 100644 (file)
@@ -22589,6 +22589,12 @@ checksum.
 Print the entire architecture configuration.  The optional argument
 @var{file} names the file where the output goes.
 
+@kindex maint print c-tdesc
+@item maint print c-tdesc
+Print the current target description (@pxref{Target Descriptions}) as
+a C source file.  The created source file can be used in @value{GDBN}
+when an XML parser is not available to parse the description.
+
 @kindex maint print dummy-frames
 @item maint print dummy-frames
 Prints the contents of @value{GDBN}'s internal dummy-frame stack.
index e1162665198d87e506ac762a62888cbaf399199c..b81c1b82bfb7c058774cd81867362c30f3f47c59 100644 (file)
 # affected XML files is changed, and the results should be kept in the
 # GDB repository.
 
+# It can also update the C files in the features directory from their
+# XML master copies.  This relies on a GDB linked with expat and
+# configured for the correct architecture, so the files are again kept
+# in the GDB repository.  To generate C files:
+#   make GDB=/path/to/gdb XMLTOC="xml files" cfiles
+
 WHICH = arm-with-iwmmxt mips-linux mips64-linux
 
 # Record which registers should be sent to GDB by default after stop.
@@ -36,6 +42,10 @@ XSLTPROC = xsltproc
 outdir = ../regformats
 OUTPUTS = $(patsubst %,$(outdir)/%.dat,$(WHICH))
 
+XMLTOC =
+CFILES = $(patsubst %.xml,%.c,$(XMLTOC))
+GDB = false
+
 all: $(OUTPUTS)
 
 $(outdir)/%.dat: %.xml number-regs.xsl sort-regs.xsl gdbserver-regs.xsl
@@ -47,5 +57,11 @@ $(outdir)/%.dat: %.xml number-regs.xsl sort-regs.xsl gdbserver-regs.xsl
          $(XSLTPROC) gdbserver-regs.xsl - >> $(outdir)/$*.tmp
        sh ../../move-if-change $(outdir)/$*.tmp $(outdir)/$*.dat
 
+cfiles: $(CFILES)
+%.c: %.xml
+       $(GDB) -nx -q -batch \
+         -ex "set tdesc filename $<" -ex 'maint print c-tdesc' > $@.tmp
+       sh ../../move-if-change $@.tmp $@
+
 # Other dependencies.
 $(outdir)/arm-with-iwmmxt.dat: arm-core.xml xscale-iwmmxt.xml
diff --git a/gdb/features/arm-with-iwmmxt.c b/gdb/features/arm-with-iwmmxt.c
new file mode 100644 (file)
index 0000000..8255c7f
--- /dev/null
@@ -0,0 +1,89 @@
+/* THIS FILE IS GENERATED.  Original: arm-with-iwmmxt.xml */
+
+#include "defs.h"
+#include "gdbtypes.h"
+#include "target-descriptions.h"
+
+struct target_desc *tdesc_arm_with_iwmmxt;
+static void
+initialize_tdesc_arm_with_iwmmxt (void)
+{
+  struct target_desc *result = allocate_target_description ();
+  struct tdesc_feature *feature;
+  struct type *field_type, *type;
+
+  set_tdesc_architecture (result, bfd_scan_arch ("iwmmxt"));
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.arm.core");
+  tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r2", 2, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r3", 3, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r4", 4, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r5", 5, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r6", 6, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r7", 7, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r8", 8, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r9", 9, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r10", 10, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r11", 11, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r12", 12, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "sp", 13, 1, NULL, 32, "data_ptr");
+  tdesc_create_reg (feature, "lr", 14, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "pc", 15, 1, NULL, 32, "code_ptr");
+  tdesc_create_reg (feature, "cpsr", 25, 1, NULL, 32, "int");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.xscale.iwmmxt");
+  field_type = tdesc_named_type (feature, "uint8");
+  type = init_vector_type (field_type, 8);
+  TYPE_NAME (type) = xstrdup ("iwmmxt_v8u8");
+  tdesc_record_type (feature, type);
+
+  field_type = tdesc_named_type (feature, "uint16");
+  type = init_vector_type (field_type, 4);
+  TYPE_NAME (type) = xstrdup ("iwmmxt_v4u16");
+  tdesc_record_type (feature, type);
+
+  field_type = tdesc_named_type (feature, "uint32");
+  type = init_vector_type (field_type, 2);
+  TYPE_NAME (type) = xstrdup ("iwmmxt_v2u32");
+  tdesc_record_type (feature, type);
+
+  type = init_composite_type (NULL, TYPE_CODE_UNION);
+  TYPE_NAME (type) = xstrdup ("iwmmxt_vec64i");
+  field_type = tdesc_named_type (feature, "iwmmxt_v8u8");
+  append_composite_type_field (type, xstrdup ("u8"), field_type);
+  field_type = tdesc_named_type (feature, "iwmmxt_v4u16");
+  append_composite_type_field (type, xstrdup ("u16"), field_type);
+  field_type = tdesc_named_type (feature, "iwmmxt_v2u32");
+  append_composite_type_field (type, xstrdup ("u32"), field_type);
+  field_type = tdesc_named_type (feature, "uint64");
+  append_composite_type_field (type, xstrdup ("u64"), field_type);
+  TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR;
+  tdesc_record_type (feature, type);
+
+  tdesc_create_reg (feature, "wR0", 26, 1, NULL, 64, "iwmmxt_vec64i");
+  tdesc_create_reg (feature, "wR1", 27, 1, NULL, 64, "iwmmxt_vec64i");
+  tdesc_create_reg (feature, "wR2", 28, 1, NULL, 64, "iwmmxt_vec64i");
+  tdesc_create_reg (feature, "wR3", 29, 1, NULL, 64, "iwmmxt_vec64i");
+  tdesc_create_reg (feature, "wR4", 30, 1, NULL, 64, "iwmmxt_vec64i");
+  tdesc_create_reg (feature, "wR5", 31, 1, NULL, 64, "iwmmxt_vec64i");
+  tdesc_create_reg (feature, "wR6", 32, 1, NULL, 64, "iwmmxt_vec64i");
+  tdesc_create_reg (feature, "wR7", 33, 1, NULL, 64, "iwmmxt_vec64i");
+  tdesc_create_reg (feature, "wR8", 34, 1, NULL, 64, "iwmmxt_vec64i");
+  tdesc_create_reg (feature, "wR9", 35, 1, NULL, 64, "iwmmxt_vec64i");
+  tdesc_create_reg (feature, "wR10", 36, 1, NULL, 64, "iwmmxt_vec64i");
+  tdesc_create_reg (feature, "wR11", 37, 1, NULL, 64, "iwmmxt_vec64i");
+  tdesc_create_reg (feature, "wR12", 38, 1, NULL, 64, "iwmmxt_vec64i");
+  tdesc_create_reg (feature, "wR13", 39, 1, NULL, 64, "iwmmxt_vec64i");
+  tdesc_create_reg (feature, "wR14", 40, 1, NULL, 64, "iwmmxt_vec64i");
+  tdesc_create_reg (feature, "wR15", 41, 1, NULL, 64, "iwmmxt_vec64i");
+  tdesc_create_reg (feature, "wCSSF", 42, 1, "vector", 32, "int");
+  tdesc_create_reg (feature, "wCASF", 43, 1, "vector", 32, "int");
+  tdesc_create_reg (feature, "wCGR0", 44, 1, "vector", 32, "int");
+  tdesc_create_reg (feature, "wCGR1", 45, 1, "vector", 32, "int");
+  tdesc_create_reg (feature, "wCGR2", 46, 1, "vector", 32, "int");
+  tdesc_create_reg (feature, "wCGR3", 47, 1, "vector", 32, "int");
+
+  tdesc_arm_with_iwmmxt = result;
+}
diff --git a/gdb/features/mips-linux.c b/gdb/features/mips-linux.c
new file mode 100644 (file)
index 0000000..51785e4
--- /dev/null
@@ -0,0 +1,99 @@
+/* THIS FILE IS GENERATED.  Original: mips-linux.xml */
+
+#include "defs.h"
+#include "gdbtypes.h"
+#include "target-descriptions.h"
+
+struct target_desc *tdesc_mips_linux;
+static void
+initialize_tdesc_mips_linux (void)
+{
+  struct target_desc *result = allocate_target_description ();
+  struct tdesc_feature *feature;
+  struct type *field_type, *type;
+
+  set_tdesc_architecture (result, bfd_scan_arch ("mips"));
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.mips.cpu");
+  tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r2", 2, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r3", 3, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r4", 4, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r5", 5, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r6", 6, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r7", 7, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r8", 8, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r9", 9, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r10", 10, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r11", 11, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r12", 12, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r13", 13, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r14", 14, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r15", 15, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r16", 16, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r17", 17, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r18", 18, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r19", 19, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r20", 20, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r21", 21, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r22", 22, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r23", 23, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r24", 24, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r25", 25, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r26", 26, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r27", 27, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r28", 28, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r29", 29, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r30", 30, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r31", 31, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "lo", 33, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "hi", 34, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "pc", 37, 1, NULL, 32, "int");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.mips.cp0");
+  tdesc_create_reg (feature, "status", 32, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "badvaddr", 35, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "cause", 36, 1, NULL, 32, "int");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.mips.fpu");
+  tdesc_create_reg (feature, "f0", 37, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f1", 38, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f2", 39, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f3", 40, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f4", 41, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f5", 42, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f6", 43, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f7", 44, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f8", 45, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f9", 46, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f10", 47, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f11", 48, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f12", 49, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f13", 50, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f14", 51, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f15", 52, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f16", 53, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f17", 54, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f18", 55, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f19", 56, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f20", 57, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f21", 58, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f22", 59, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f23", 60, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f24", 61, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f25", 62, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f26", 63, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f27", 64, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f28", 65, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f29", 66, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f30", 67, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f31", 68, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "fcsr", 69, 1, "float", 32, "int");
+  tdesc_create_reg (feature, "fir", 70, 1, "float", 32, "int");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.mips.linux");
+  tdesc_create_reg (feature, "restart", 71, 1, "system", 32, "int");
+
+  tdesc_mips_linux = result;
+}
diff --git a/gdb/features/mips64-linux.c b/gdb/features/mips64-linux.c
new file mode 100644 (file)
index 0000000..85c99a6
--- /dev/null
@@ -0,0 +1,99 @@
+/* THIS FILE IS GENERATED.  Original: mips64-linux.xml */
+
+#include "defs.h"
+#include "gdbtypes.h"
+#include "target-descriptions.h"
+
+struct target_desc *tdesc_mips64_linux;
+static void
+initialize_tdesc_mips64_linux (void)
+{
+  struct target_desc *result = allocate_target_description ();
+  struct tdesc_feature *feature;
+  struct type *field_type, *type;
+
+  set_tdesc_architecture (result, bfd_scan_arch ("mips"));
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.mips.cpu");
+  tdesc_create_reg (feature, "r0", 0, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r1", 1, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r2", 2, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r3", 3, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r4", 4, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r5", 5, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r6", 6, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r7", 7, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r8", 8, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r9", 9, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r10", 10, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r11", 11, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r12", 12, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r13", 13, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r14", 14, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r15", 15, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r16", 16, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r17", 17, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r18", 18, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r19", 19, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r20", 20, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r21", 21, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r22", 22, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r23", 23, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r24", 24, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r25", 25, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r26", 26, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r27", 27, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r28", 28, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r29", 29, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r30", 30, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r31", 31, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "lo", 33, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "hi", 34, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "pc", 37, 1, NULL, 64, "int");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.mips.cp0");
+  tdesc_create_reg (feature, "status", 32, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "badvaddr", 35, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "cause", 36, 1, NULL, 64, "int");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.mips.fpu");
+  tdesc_create_reg (feature, "f0", 37, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f1", 38, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f2", 39, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f3", 40, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f4", 41, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f5", 42, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f6", 43, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f7", 44, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f8", 45, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f9", 46, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f10", 47, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f11", 48, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f12", 49, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f13", 50, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f14", 51, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f15", 52, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f16", 53, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f17", 54, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f18", 55, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f19", 56, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f20", 57, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f21", 58, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f22", 59, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f23", 60, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f24", 61, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f25", 62, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f26", 63, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f27", 64, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f28", 65, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f29", 66, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f30", 67, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f31", 68, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "fcsr", 69, 1, "float", 64, "int");
+  tdesc_create_reg (feature, "fir", 70, 1, "float", 64, "int");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.mips.linux");
+  tdesc_create_reg (feature, "restart", 71, 1, "system", 64, "int");
+
+  tdesc_mips64_linux = result;
+}
index 7d87c87e82d53a232f7e6db1a19db90496deacf5..fb44a7e0a481eec8ab10871793631c38d1f3257b 100644 (file)
@@ -26,7 +26,6 @@
 #include "linux-nat.h"
 #include "mips-linux-tdep.h"
 #include "target-descriptions.h"
-#include "xml-support.h"
 
 #include "gdb_proc_service.h"
 #include "gregset.h"
@@ -34,6 +33,9 @@
 #include <sgidefs.h>
 #include <sys/ptrace.h>
 
+#include "features/mips-linux.c"
+#include "features/mips64-linux.c"
+
 #ifndef PTRACE_GET_THREAD_AREA
 #define PTRACE_GET_THREAD_AREA 25
 #endif
@@ -342,34 +344,15 @@ mips_linux_register_u_offset (struct gdbarch *gdbarch, int regno, int store_p)
     return mips_linux_register_addr (gdbarch, regno, store_p);
 }
 
-static LONGEST (*super_xfer_partial) (struct target_ops *, enum target_object,
-                                     const char *, gdb_byte *, const gdb_byte *,
-                                     ULONGEST, LONGEST);
-
-static LONGEST
-mips_linux_xfer_partial (struct target_ops *ops,
-                        enum target_object object,
-                        const char *annex,
-                        gdb_byte *readbuf, const gdb_byte *writebuf,
-                        ULONGEST offset, LONGEST len)
+static const struct target_desc *
+mips_linux_read_description (struct target_ops *ops)
 {
-  if (object == TARGET_OBJECT_AVAILABLE_FEATURES)
-    {
-      if (annex != NULL && strcmp (annex, "target.xml") == 0)
-       {
-         /* Report that target registers are a size we know for sure
-            that we can get from ptrace.  */
-         if (_MIPS_SIM == _ABIO32)
-           annex = "mips-linux.xml";
-         else
-           annex = "mips64-linux.xml";
-       }
-
-      return xml_builtin_xfer_partial (annex, readbuf, writebuf, offset, len);
-    }
-
-  return super_xfer_partial (ops, object, annex, readbuf, writebuf,
-                            offset, len);
+  /* Report that target registers are a size we know for sure
+     that we can get from ptrace.  */
+  if (_MIPS_SIM == _ABIO32)
+    return tdesc_mips_linux;
+  else
+    return tdesc_mips64_linux;
 }
 
 void _initialize_mips_linux_nat (void);
@@ -385,9 +368,11 @@ _initialize_mips_linux_nat (void)
   t->to_fetch_registers = mips64_linux_fetch_registers;
   t->to_store_registers = mips64_linux_store_registers;
 
-  /* Override the default to_xfer_partial.  */
-  super_xfer_partial = t->to_xfer_partial;
-  t->to_xfer_partial = mips_linux_xfer_partial;
+  t->to_read_description = mips_linux_read_description;
 
   linux_nat_add_target (t);
+
+  /* Initialize the standard target descriptions.  */
+  initialize_tdesc_mips_linux ();
+  initialize_tdesc_mips64_linux ();
 }
index 3d530e105477085a4174644492f99024908d60bd..2f1b82e4c557b06590e8c61ff523f1515676bbb4 100644 (file)
@@ -339,6 +339,28 @@ tdesc_feature_name (const struct tdesc_feature *feature)
   return feature->name;
 }
 
+/* Predefined types.  Note that none of these types depend on the
+   current architecture; some of the builtin_type_foo variables are
+   swapped based on the architecture.  */
+static struct
+{
+  const char *name;
+  struct type **type;
+} tdesc_predefined_types[] =
+  {
+    { "int8", &builtin_type_int8 },
+    { "int16", &builtin_type_int16 },
+    { "int32", &builtin_type_int32 },
+    { "int64", &builtin_type_int64 },
+    { "uint8", &builtin_type_uint8 },
+    { "uint16", &builtin_type_uint16 },
+    { "uint32", &builtin_type_uint32 },
+    { "uint64", &builtin_type_uint64 },
+    { "ieee_single", &builtin_type_ieee_single },
+    { "ieee_double", &builtin_type_ieee_double },
+    { "arm_fpa_ext", &builtin_type_arm_ext }
+  };
+
 /* Return the type associated with ID in the context of FEATURE, or
    NULL if none.  */
 
@@ -353,41 +375,10 @@ tdesc_named_type (const struct tdesc_feature *feature, const char *id)
     if (strcmp (TYPE_NAME (gdb_type), id) == 0)
       return gdb_type;
 
-  /* Next try some predefined types.  Note that none of these types
-     depend on the current architecture; some of the builtin_type_foo
-     variables are swapped based on the architecture.  */
-  if (strcmp (id, "int8") == 0)
-    return builtin_type_int8;
-
-  if (strcmp (id, "int16") == 0)
-    return builtin_type_int16;
-
-  if (strcmp (id, "int32") == 0)
-    return builtin_type_int32;
-
-  if (strcmp (id, "int64") == 0)
-    return builtin_type_int64;
-
-  if (strcmp (id, "uint8") == 0)
-    return builtin_type_uint8;
-
-  if (strcmp (id, "uint16") == 0)
-    return builtin_type_uint16;
-
-  if (strcmp (id, "uint32") == 0)
-    return builtin_type_uint32;
-
-  if (strcmp (id, "uint64") == 0)
-    return builtin_type_uint64;
-
-  if (strcmp (id, "ieee_single") == 0)
-    return builtin_type_ieee_single;
-
-  if (strcmp (id, "ieee_double") == 0)
-    return builtin_type_ieee_double;
-
-  if (strcmp (id, "arm_fpa_ext") == 0)
-    return builtin_type_arm_ext;
+  /* Next try the predefined types.  */
+  for (ix = 0; ix < ARRAY_SIZE (tdesc_predefined_types); ix++)
+    if (strcmp (tdesc_predefined_types[ix].name, id) == 0)
+      return *tdesc_predefined_types[ix].type;
 
   return NULL;
 }
@@ -960,6 +951,155 @@ unset_tdesc_filename_cmd (char *args, int from_tty)
   target_find_description ();
 }
 
+static const char *
+tdesc_type_id (struct type *type)
+{
+  int ix;
+
+  for (ix = 0; ix < ARRAY_SIZE (tdesc_predefined_types); ix++)
+    if (TYPE_MAIN_TYPE (*tdesc_predefined_types[ix].type)
+       == TYPE_MAIN_TYPE (type))
+      return tdesc_predefined_types[ix].name;
+
+  return TYPE_NAME (type);
+}
+
+static void
+maint_print_c_tdesc_cmd (char *args, int from_tty)
+{
+  const struct target_desc *tdesc;
+  const char *filename, *inp;
+  char *function, *outp;
+  struct property *prop;
+  struct tdesc_feature *feature;
+  struct tdesc_reg *reg;
+  struct type *type;
+  int ix, ix2, ix3;
+
+  /* Use the global target-supplied description, not the current
+     architecture's.  This lets a GDB for one architecture generate C
+     for another architecture's description, even though the gdbarch
+     initialization code will reject the new description.  */
+  tdesc = current_target_desc;
+  if (tdesc == NULL)
+    error (_("There is no target description to print."));
+
+  if (target_description_filename == NULL)
+    error (_("The current target description did not come from an XML file."));
+
+  filename = lbasename (target_description_filename);
+  function = xmalloc (strlen (filename) + 1);
+  for (inp = filename, outp = function; *inp != '\0'; inp++)
+    if (*inp == '.')
+      break;
+    else if (*inp == '-')
+      *outp++ = '_';
+    else
+      *outp++ = *inp;
+  *outp = '\0';
+
+  /* Standard boilerplate.  */
+  printf_unfiltered ("/* THIS FILE IS GENERATED.  Original: %s */\n\n",
+                    filename);
+  printf_unfiltered ("#include \"defs.h\"\n");
+  printf_unfiltered ("#include \"gdbtypes.h\"\n");
+  printf_unfiltered ("#include \"target-descriptions.h\"\n");
+  printf_unfiltered ("\n");
+
+  printf_unfiltered ("struct target_desc *tdesc_%s;\n", function);
+  printf_unfiltered ("static void\n");
+  printf_unfiltered ("initialize_tdesc_%s (void)\n", function);
+  printf_unfiltered ("{\n");
+  printf_unfiltered
+    ("  struct target_desc *result = allocate_target_description ();\n");
+  printf_unfiltered ("  struct tdesc_feature *feature;\n");
+  printf_unfiltered ("  struct type *field_type, *type;\n");
+  printf_unfiltered ("\n");
+
+  if (tdesc_architecture (tdesc) != NULL)
+    {
+      printf_unfiltered
+       ("  set_tdesc_architecture (result, bfd_scan_arch (\"%s\"));\n",
+        tdesc_architecture (tdesc)->printable_name);
+      printf_unfiltered ("\n");
+    }
+
+  for (ix = 0; VEC_iterate (property_s, tdesc->properties, ix, prop);
+       ix++)
+    {
+      printf_unfiltered ("  set_tdesc_property (result, \"%s\", \"%s\");\n",
+             prop->key, prop->value);
+    }
+
+  for (ix = 0;
+       VEC_iterate (tdesc_feature_p, tdesc->features, ix, feature);
+       ix++)
+    {
+      printf_unfiltered ("  feature = tdesc_create_feature (result, \"%s\");\n",
+                        feature->name);
+
+      for (ix2 = 0;
+          VEC_iterate (type_p, feature->types, ix2, type);
+          ix2++)
+       {
+         switch (TYPE_CODE (type))
+           {
+           case TYPE_CODE_ARRAY:
+             printf_unfiltered
+               ("  field_type = tdesc_named_type (feature, \"%s\");\n",
+                tdesc_type_id (TYPE_TARGET_TYPE (type)));
+             printf_unfiltered
+               ("  type = init_vector_type (field_type, %d);\n",
+                TYPE_LENGTH (type) / TYPE_LENGTH (TYPE_TARGET_TYPE (type)));
+             printf_unfiltered
+               ("  TYPE_NAME (type) = xstrdup (\"%s\");\n", TYPE_NAME (type));
+             break;
+           case TYPE_CODE_UNION:
+             printf_unfiltered
+               ("  type = init_composite_type (NULL, TYPE_CODE_UNION);\n");
+             printf_unfiltered
+               ("  TYPE_NAME (type) = xstrdup (\"%s\");\n", TYPE_NAME (type));
+             for (ix3 = 0; ix3 < TYPE_NFIELDS (type); ix3++)
+               {
+                 printf_unfiltered
+                   ("  field_type = tdesc_named_type (feature, \"%s\");\n",
+                    tdesc_type_id (TYPE_FIELD_TYPE (type, ix3)));
+                 printf_unfiltered
+                   ("  append_composite_type_field (type, "
+                    "xstrdup (\"%s\"), field_type);\n",
+                    TYPE_FIELD_NAME (type, ix3));
+               }
+             if (TYPE_VECTOR (type))
+               printf_unfiltered
+                 ("  TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR;\n");
+             break;
+           default:
+             error (_("C output is not supported type \"%s\"."), TYPE_NAME (type));
+           }
+         printf_unfiltered ("  tdesc_record_type (feature, type);\n");
+         printf_unfiltered ("\n");
+       }
+
+      for (ix2 = 0;
+          VEC_iterate (tdesc_reg_p, feature->registers, ix2, reg);
+          ix2++)
+       {
+         printf_unfiltered ("  tdesc_create_reg (feature, \"%s\", %ld, %d, ",
+                            reg->name, reg->target_regnum, reg->save_restore);
+         if (reg->group)
+           printf_unfiltered ("\"%s\", ", reg->group);
+         else
+           printf_unfiltered ("NULL, ");
+         printf_unfiltered ("%d, \"%s\");\n", reg->bitsize, reg->type);
+       }
+
+      printf_unfiltered ("\n");
+    }
+
+  printf_unfiltered ("  tdesc_%s = result;\n", function);
+  printf_unfiltered ("}\n");
+}
+
 void
 _initialize_target_descriptions (void)
 {
@@ -993,4 +1133,8 @@ file instead of querying the remote target."),
 Unset the file to read for an XML target description.  When unset,\n\
 GDB will read the description from the target."),
           &tdesc_unset_cmdlist);
+
+  add_cmd ("c-tdesc", class_maintenance, maint_print_c_tdesc_cmd, _("\
+Print the current target description as a C source file."),
+          &maintenanceprintlist);
 }