]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Require targets to provide all their registers if an XML description
authorDaniel Jacobowitz <drow@false.org>
Thu, 23 Mar 2006 16:52:21 +0000 (16:52 +0000)
committerDaniel Jacobowitz <drow@false.org>
Thu, 23 Mar 2006 16:52:21 +0000 (16:52 +0000)
is used; fix various bugs this uncovered.  Allow ARM descriptions without
FPA.

gdb/Makefile.in
gdb/arm-tdep.c
gdb/arm-tdep.h
gdb/available.c
gdb/available.h
gdb/features/feature_to_c.sh
gdb/gdbarch.c
gdb/gdbarch.h
gdb/gdbarch.sh
gdb/parse-avail.c

index 3b13c5cfe69365afd9c6381099307bd7936fbbf9..323e00c85f9674210fd2ba48c85209f094734bff 100644 (file)
@@ -1686,21 +1686,7 @@ po/$(PACKAGE).pot: force
 xml-builtin.c: stamp-xml; @true
 stamp-xml: $(srcdir)/features/feature_to_c.sh Makefile $(XMLFILES)
        rm -f xml-builtin.tmp
-       for f in dummy $(XMLFILES); do \
-         if test $$f != dummy; then \
-           $(SHELL) $(srcdir)/features/feature_to_c.sh "$$f" xml-builtin.tmp; \
-         fi; \
-       done
-       echo "const char *const xml_builtin[][2] = {" >> xml-builtin.tmp
-       for f in dummy $(XMLFILES); do \
-         if test $$f != dummy; then \
-           basename=`echo $$f | sed 's,.*/,,'`; \
-            arrayname=xml_feature_`echo $$basename | sed 's/[-.]/_/g'`; \
-           echo "  { \"$$basename\", $$arrayname }," >> xml-builtin.tmp; \
-         fi; \
-       done
-       echo "  { 0, 0 }" >> xml-builtin.tmp
-       echo "};" >> xml-builtin.tmp
+       $(SHELL) $(srcdir)/features/feature_to_c.sh xml-builtin.tmp $(XMLFILES)
        $(SHELL) $(srcdir)/../move-if-change xml-builtin.tmp xml-builtin.c
        echo stamp > stamp-xml
 
@@ -1825,7 +1811,7 @@ auxv.o: auxv.c $(defs_h) $(target_h) $(gdbtypes_h) $(command_h) \
        $(inferior_h) $(valprint_h) $(gdb_assert_h) $(auxv_h) \
        $(elf_common_h)
 available.o: available.c $(defs_h) $(symfile_h) $(target_h) $(available_h) \
-       $(arch_utils_h) $(gdbtypes_h) $(sha1_h) \
+       $(arch_utils_h) $(exceptions_h) $(gdbtypes_h) $(sha1_h) \
        $(gdb_string) $(gdb_assert) $(gdb_obstack_h) $(gdb_stdint_h)
 avr-tdep.o: avr-tdep.c $(defs_h) $(frame_h) $(frame_unwind_h) \
        $(frame_base_h) $(trad_frame_h) $(gdbcmd_h) $(gdbcore_h) \
index a831b653fe507c1d2283c1df271c9ddb9b2d0102..8a0869072330ba8f528c92f6a95ce1adb39a9425 100644 (file)
@@ -805,13 +805,15 @@ arm_scan_prologue (struct frame_info *next_frame, struct arm_prologue_cache *cac
          imm = (imm >> rot) | (imm << (32 - rot));
          sp_offset -= imm;
        }
-      else if ((insn & 0xffff7fff) == 0xed6d0103)      /* stfe f?, [sp, -#c]! */
+      else if ((insn & 0xffff7fff) == 0xed6d0103       /* stfe f?, [sp, -#c]! */
+              && gdbarch_tdep (current_gdbarch)->have_fpa_registers)
        {
          sp_offset -= 12;
          regno = ARM_F0_REGNUM + ((insn >> 12) & 0x07);
          cache->saved_regs[regno].addr = sp_offset;
        }
-      else if ((insn & 0xffbf0fff) == 0xec2d0200)      /* sfmfd f0, 4, [sp!] */
+      else if ((insn & 0xffbf0fff) == 0xec2d0200       /* sfmfd f0, 4, [sp!] */
+              && gdbarch_tdep (current_gdbarch)->have_fpa_registers)
        {
          int n_saved_fp_regs;
          unsigned int fp_start_reg, fp_bound_reg;
@@ -1352,6 +1354,9 @@ arm_register_type (struct gdbarch *gdbarch, int regnum)
 
   if (regnum >= ARM_F0_REGNUM && regnum < ARM_F0_REGNUM + NUM_FREGS)
     {
+      if (!gdbarch_tdep (gdbarch)->have_fpa_registers)
+       return builtin_type_void;
+
       if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
        return builtin_type_arm_ext_big;
       else
@@ -2458,11 +2463,20 @@ arm_register_name (int i)
 {
   const char *avail_name;
 
-  avail_name = available_register_name (current_gdbarch, i);
-  if (avail_name)
-    return avail_name;
+  /* Allow arm_register_names to override the names for standard
+     registers from the target, for "set arm disassembler".  */
+  if (i <= ARM_PC_REGNUM || i == ARM_PS_REGNUM)
+    return arm_register_names[i];
+  if (i <= ARM_FPS_REGNUM)
+    {
+      if (gdbarch_tdep (current_gdbarch)->have_fpa_registers)
+       return arm_register_names[i];
+      else
+       return "";
+    }
 
-  return arm_register_names[i];
+  /* Check for target-supplied register numbers.  */
+  return available_register_name (current_gdbarch, i);
 }
 
 static void
@@ -2571,6 +2585,51 @@ arm_elf_osabi_sniffer (bfd *abfd)
   return osabi;
 }
 
+static void
+arm_require_register (struct gdb_feature_set *feature_set,
+                     const char *name, int regnum)
+{
+  if (!available_find_named_register (feature_set, name, regnum))
+    error (_("target does not provide required register \"%s\""), name);
+}
+
+static void
+arm_check_feature_set (struct gdbarch *gdbarch,
+                      struct gdb_feature_set *feature_set)
+{
+  static const char *const arm_standard_names[] =
+    {
+      "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+      "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+      "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "fps",
+      "cpsr"
+    };
+  int i;
+
+  if (!available_find_named_feature (feature_set, "org.gnu.gdb.arm.core"))
+    error (_("target does not provide ARM core registers"));
+
+  for (i = 0; i < 16; i++)
+    arm_require_register (feature_set, arm_standard_names[i], i);
+
+  arm_require_register (feature_set, arm_standard_names[ARM_PS_REGNUM],
+                       ARM_PS_REGNUM);
+
+  /* If we have an FPA unit, require the FPA registers and assign them
+     fixed numbers.  If we don't have FPA, these register numbers will
+     remain unused, since various ARM subtargets hardcode the
+     numbering.  */
+
+  if (available_find_named_feature (feature_set, "org.gnu.gdb.arm.fpa"))
+    {
+      for (i = ARM_F0_REGNUM; i <= ARM_FPS_REGNUM; i++)
+       arm_require_register (feature_set, arm_standard_names[i], i);
+      gdbarch_tdep (gdbarch)->have_fpa_registers = 1;
+    }
+  else
+    gdbarch_tdep (gdbarch)->have_fpa_registers = 0;
+}
+
 \f
 /* Initialize the current architecture based on INFO.  If possible,
    re-use an architecture from ARCHES, which is a list of
@@ -2761,7 +2820,6 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_breakpoint_from_pc (gdbarch, arm_breakpoint_from_pc);
 
   /* Information about registers, etc.  */
-  set_gdbarch_print_float_info (gdbarch, arm_print_float_info);
   set_gdbarch_deprecated_fp_regnum (gdbarch, ARM_FP_REGNUM);   /* ??? */
   set_gdbarch_sp_regnum (gdbarch, ARM_SP_REGNUM);
   set_gdbarch_pc_regnum (gdbarch, ARM_PC_REGNUM);
@@ -2771,7 +2829,19 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_register_type (gdbarch, arm_register_type);
 
   if (info.feature_set)
-    record_available_features (gdbarch, info.feature_set);
+    {
+      arm_check_feature_set (gdbarch, info.feature_set);
+      record_available_features (gdbarch, info.feature_set);
+    }
+  else
+    /* The legacy layout of the remote "g" packet assumes we have
+       the FPA registers, as do some native targets.  */
+    gdbarch_tdep (gdbarch)->have_fpa_registers = 1;
+
+  /* This "info float" is FPA-specific.  Use the generic version if we
+     do not have FPA.  */
+  if (gdbarch_tdep (gdbarch)->have_fpa_registers)
+    set_gdbarch_print_float_info (gdbarch, arm_print_float_info);
 
   /* Internal <-> external register number maps.  */
   set_gdbarch_register_sim_regno (gdbarch, arm_register_sim_regno);
index 314105254cc9d8c88ae4b6871863fe8a7a7c280b..f02eeb1eeed49171c5084d3056623f1393dbe26f 100644 (file)
@@ -131,6 +131,8 @@ struct gdbarch_tdep
 
   enum arm_float_model fp_model; /* Floating point calling conventions.  */
 
+  int have_fpa_registers;      /* Does the target report the FPA registers?  */
+
   CORE_ADDR lowest_pc;         /* Lowest address at which instructions 
                                   will appear.  */
 
index ed6f2804b43cf56c51fed7238738da1fdd5a486b..0fa69a5dbf2ad476f25084384970544337f7bd75 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "defs.h"
 #include "arch-utils.h"
+#include "exceptions.h"
 #include "gdbtypes.h"
 #include "symfile.h"
 #include "target.h"
@@ -405,8 +406,6 @@ int
 features_same_p (const struct gdb_feature_set *lhs,
                 const struct gdb_feature_set *rhs)
 {
-  const struct gdb_available_feature *lhs_p, *rhs_p;
-
   /* Two feature sets are the same if and only if they are described
      by the same XML.  */
 
@@ -419,14 +418,23 @@ features_same_p (const struct gdb_feature_set *lhs,
 /* Switch the architecture (gdbarch) to one which supports FEATURES.  */
 
 void
-arch_set_available_features (const struct gdb_feature_set *features)
+arch_set_available_features (struct gdb_feature_set *features)
 {
+  volatile struct gdb_exception e;
   struct gdbarch_info info;
 
-  gdbarch_info_init (&info);
-  info.feature_set = features;
-  if (!gdbarch_update_p (info))
-    internal_error (__FILE__, __LINE__, "could not update architecture");
+  TRY_CATCH (e, RETURN_MASK_ERROR)
+    {
+      gdbarch_info_init (&info);
+      info.feature_set = features;
+
+      if (!gdbarch_update_p (info))
+       internal_error (__FILE__, __LINE__, "could not update architecture");
+    }
+
+  if (e.reason == RETURN_ERROR)
+    exception_fprintf (gdb_stderr, e,
+                      _("warning: could not use supplied target description: "));
 }
 
 static struct gdb_feature_set *
@@ -491,20 +499,20 @@ copy_features_to_obstack (struct obstack *obstack,
 /* Set an architecture's feature set.  Store BASE_FEATURES in GDBARCH,
    and on the correct obstack.
 
-   This function will update num_regs.  It is the architecture's
-   responsibility to handle this if it has pseudo registers.
-
-   FIXME: This interface may need to go away; what if we want to add
-   a single additional feature to that provided by the target?  */
+   This function will update GDBARCH's num_regs.  It is the
+   architecture's responsibility to handle this if it has pseudo
+   registers.  Before calling this function, num_regs should be
+   the number of fixed registers handled by the target code; all
+   unassigned registers will be given numbers above that point.  */
 
 void
 record_available_features (struct gdbarch *gdbarch,
-                          const struct gdb_feature_set *base_features)
+                          struct gdb_feature_set *base_features)
 {
   struct gdb_available_feature *feature;
   struct gdb_available_register *reg;
   struct gdb_feature_set *features;
-  int gdb_regnum, protocol_number;
+  int gdb_regnum;
 
   features = copy_features_to_obstack (gdbarch_obstack (gdbarch),
                                       base_features);
@@ -513,21 +521,16 @@ record_available_features (struct gdbarch *gdbarch,
   gdb_regnum = gdbarch_num_regs (gdbarch);
 
   for (feature = features->features; feature; feature = feature->next)
-    {
-      protocol_number = feature->protocol_number;
-      for (reg = feature->registers; reg; reg = reg->next)
-       {
-         reg->gdb_regnum = gdb_regnum++;
-         reg->protocol_number = protocol_number++;
-       }
-    }
+    for (reg = feature->registers; reg; reg = reg->next)
+      if (reg->gdb_regnum == -1)
+       reg->gdb_regnum = gdb_regnum++;
 
   set_gdbarch_num_regs (gdbarch, gdb_regnum);
 }
 
 /* Search FEATURES for a register with GDB register number REGNUM.  */
 
-struct gdb_available_register *
+static struct gdb_available_register *
 find_register (const struct gdb_feature_set *features, int regnum)
 {
   struct gdb_available_feature *feature;
@@ -544,6 +547,55 @@ find_register (const struct gdb_feature_set *features, int regnum)
   return NULL;
 }
 
+/* Search FEATURES for a register with target-specified name NAME,
+   and set its GDB register number to REGNUM.  Return 1 if the
+   register was found, and 0 if it was not.  This function should
+   only be used while initializing a gdbarch.  */
+
+int
+available_find_named_register (struct gdb_feature_set *features,
+                              const char *name, int regnum)
+{
+  struct gdb_available_feature *feature;
+  struct gdb_available_register *reg;
+
+  if (features == NULL)
+    return 0;
+
+  for (feature = features->features; feature; feature = feature->next)
+    for (reg = feature->registers; reg; reg = reg->next)
+      if (strcmp (reg->name, name) == 0)
+       {
+         reg->gdb_regnum = regnum;
+         return 1;
+       }
+
+  /* FIXME: Should we sanity check the target-supplied data here for
+     duplicate register names?  Right now GDB can't handle duplicated
+     register names at all, but in the future it may.  */
+
+  return 0;
+}
+
+/* Search FEATURES for a feature with the well-known name NAME,
+   which GDB may have special support for.  */
+
+int
+available_find_named_feature (struct gdb_feature_set *features,
+                             const char *name)
+{
+  struct gdb_available_feature *feature;
+
+  if (features == NULL)
+    return 0;
+
+  for (feature = features->features; feature; feature = feature->next)
+    if (strcmp (feature->name, name) == 0)
+      return 1;
+
+  return 0;
+}
+
 /* Return the type of target-described register REGNUM, if the feature set
    for GDBARCH describes that register.  Otherwise return NULL.  */
 
index c657a749bad8cc01291f63dbd4c8ce08c4a06bf6..7b35e40d8b268c48a8727cde126f577d95dd2195 100644 (file)
@@ -139,7 +139,7 @@ struct gdb_feature_set *available_features_from_target_object
 /* Standard method to update an architecture based on detected available
    features.  */
 
-void arch_set_available_features (const struct gdb_feature_set *);
+void arch_set_available_features (struct gdb_feature_set *);
 
 /* Compare two sets of available features.  */
 
@@ -149,7 +149,18 @@ int features_same_p (const struct gdb_feature_set *,
 /* Set an architecture's feature set.  */
 
 void record_available_features (struct gdbarch *,
-                               const struct gdb_feature_set *);
+                               struct gdb_feature_set *);
+
+/* Find a register with the given name, and set its internal register
+   number.  */
+
+int available_find_named_register (struct gdb_feature_set *,
+                                  const char *, int);
+
+/* Find a feature with the given name.  */
+
+int available_find_named_feature (struct gdb_feature_set *,
+                                 const char *);
 
 /* Find the type of a target-described register.  */
 
index 0617b05dd5087a9e8ec261cb33d7da1dd943c672..764297725ee5f04003a428159071db91762d5ed9 100644 (file)
@@ -1,37 +1,55 @@
 #!/bin/sh
 
-input=$1
-output=$2
+output=$1
+shift
 
-if test -z "$input" || test -z "$output"; then
-  echo "Usage: $0 INPUTFILE OUTPUTFILE"
+if test -z "$output" || test -z "$1"; then
+  echo "Usage: $0 OUTPUTFILE INPUTFILE..."
   exit 1
 fi
 
-arrayname=xml_feature_`echo $input | sed 's,.*/,,; s/[-.]/_/g'`
+for input in dummy "$@"; do
+  if test $input != dummy; then
+    arrayname=xml_feature_`echo $input | sed 's,.*/,,; s/[-.]/_/g'`
 
-gawk 'BEGIN { n = 0
-  print "static const char '$arrayname'[] = {"
-  for (i = 0; i < 255; i++)
-    _ord_[sprintf("%c", i)] = i
-} {
-  split($0, line, "");
-  printf "  "
-  for (i = 1; i <= length(line); i++) {
-    c = line[i]
-    if (c == "'\''") {
-      printf "'\''\\'\'''\'', "
-    } else if (c == "\\") {
-      printf "'\''\\\\'\'', "
-    } else if (match (c, "[[:print:]]") != 0) {
-      printf "'\''" c "'\'', "
-    } else {
-      printf "'\''\\%03o'\'', ", _ord_[c]
-    }
-    if (i % 10 == 0)
-      printf "\n   "
-  }
-  printf "'\''\\n'\'', \n"
-} END {
-  print "  0 };"
-}' < $input > $output
+    gawk 'BEGIN { n = 0
+      print "static const char '$arrayname'[] = {"
+      for (i = 0; i < 255; i++)
+        _ord_[sprintf("%c", i)] = i
+    } {
+      split($0, line, "");
+      printf "  "
+      for (i = 1; i <= length(line); i++) {
+        c = line[i]
+        if (c == "'\''") {
+          printf "'\''\\'\'''\'', "
+        } else if (c == "\\") {
+          printf "'\''\\\\'\'', "
+        } else if (match (c, "[[:print:]]") != 0) {
+          printf "'\''" c "'\'', "
+        } else {
+          printf "'\''\\%03o'\'', ", _ord_[c]
+        }
+        if (i % 10 == 0)
+          printf "\n   "
+      }
+      printf "'\''\\n'\'', \n"
+    } END {
+      print "  0 };"
+    }' < $input >> $output
+  fi
+done
+
+echo >> $output
+echo "const char *const xml_builtin[][2] = {" >> $output
+
+for input in dummy "$@"; do
+  if test $input != dummy; then
+    basename=`echo $input | sed 's,.*/,,'`
+    arrayname=xml_feature_`echo $input | sed 's,.*/,,; s/[-.]/_/g'`
+    echo "  { \"$basename\", $arrayname }," >> $output
+  fi
+done
+
+echo "  { 0, 0 }" >> $output
+echo "};" >> $output
index d5490845a87c345ff9045d5c921746fca851e63e..80aebec3af0a72411b33fb7191c553de2116d1ec 100644 (file)
@@ -238,7 +238,7 @@ struct gdbarch
   gdbarch_fetch_pointer_argument_ftype *fetch_pointer_argument;
   gdbarch_regset_from_core_section_ftype *regset_from_core_section;
   int available_features_support;
-  const struct gdb_feature_set * feature_set;
+  struct gdb_feature_set * feature_set;
 };
 
 
@@ -3750,7 +3750,7 @@ set_gdbarch_available_features_support (struct gdbarch *gdbarch,
   gdbarch->available_features_support = available_features_support;
 }
 
-const struct gdb_feature_set *
+struct gdb_feature_set *
 gdbarch_feature_set (struct gdbarch *gdbarch)
 {
   gdb_assert (gdbarch != NULL);
@@ -3761,7 +3761,7 @@ gdbarch_feature_set (struct gdbarch *gdbarch)
 
 void
 set_gdbarch_feature_set (struct gdbarch *gdbarch,
-                         const struct gdb_feature_set * feature_set)
+                         struct gdb_feature_set * feature_set)
 {
   gdbarch->feature_set = feature_set;
 }
@@ -3978,8 +3978,9 @@ current_gdbarch_swap_out_hack (void)
 }
 
 static void
-current_gdbarch_swap_in_hack (struct gdbarch *new_gdbarch)
+current_gdbarch_swap_in_hack (void *argument)
 {
+  struct gdbarch *new_gdbarch = argument;
   struct gdbarch_swap *curr;
 
   gdb_assert (current_gdbarch == NULL);
@@ -4264,13 +4265,18 @@ gdbarch_find_by_info (struct gdbarch_info info)
      architecture of the same family is found at the head of the
      rego->arches list.  */
   struct gdbarch *old_gdbarch = current_gdbarch_swap_out_hack ();
+  struct cleanup *back_to;
+
+  /* Make sure we restore current_gdbarch on our way out if an error
+     occurs.  */
+  back_to = make_cleanup (current_gdbarch_swap_in_hack, old_gdbarch);
 
   /* Find the specified architecture.  */
   struct gdbarch *new_gdbarch = find_arch_by_info (old_gdbarch, info);
 
   /* Restore the existing architecture.  */
   gdb_assert (current_gdbarch == NULL);
-  current_gdbarch_swap_in_hack (old_gdbarch);
+  do_cleanups (back_to);
 
   return new_gdbarch;
 }
index 1d11fb70b06e1bd3cd75d903e22b860108a71b38..6a4d6885ab1b402ec533170196fca5e1c6d47777 100644 (file)
@@ -1421,8 +1421,8 @@ extern void set_gdbarch_available_features_support (struct gdbarch *gdbarch, int
 
 /* The architecture's currently associated feature set. */
 
-extern const struct gdb_feature_set * gdbarch_feature_set (struct gdbarch *gdbarch);
-extern void set_gdbarch_feature_set (struct gdbarch *gdbarch, const struct gdb_feature_set * feature_set);
+extern struct gdb_feature_set * gdbarch_feature_set (struct gdbarch *gdbarch);
+extern void set_gdbarch_feature_set (struct gdbarch *gdbarch, struct gdb_feature_set * feature_set);
 
 extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch);
 
@@ -1511,7 +1511,7 @@ struct gdbarch_info
   enum gdb_osabi osabi;
 
   /* Use default: NULL.  */
-  const struct gdb_feature_set *feature_set;
+  struct gdb_feature_set *feature_set;
 };
 
 typedef struct gdbarch *(gdbarch_init_ftype) (struct gdbarch_info info, struct gdbarch_list *arches);
index fb26e901d7607d0a436765d5714602674577ba9f..6b022d49d841c4a033b189d027ce24865c8a6091 100755 (executable)
@@ -672,7 +672,7 @@ M::const struct regset *:regset_from_core_section:const char *sect_name, size_t
 v::int:available_features_support
 
 # The architecture's currently associated feature set.
-v::const struct gdb_feature_set *:feature_set:::::::paddr_nz ((long) current_gdbarch->feature_set)
+v::struct gdb_feature_set *:feature_set:::::::paddr_nz ((long) current_gdbarch->feature_set)
 EOF
 }
 
@@ -1001,7 +1001,7 @@ struct gdbarch_info
   enum gdb_osabi osabi;
 
   /* Use default: NULL.  */
-  const struct gdb_feature_set *feature_set;
+  struct gdb_feature_set *feature_set;
 };
 
 typedef struct gdbarch *(gdbarch_init_ftype) (struct gdbarch_info info, struct gdbarch_list *arches);
@@ -1938,8 +1938,9 @@ current_gdbarch_swap_out_hack (void)
 }
 
 static void
-current_gdbarch_swap_in_hack (struct gdbarch *new_gdbarch)
+current_gdbarch_swap_in_hack (void *argument)
 {
+  struct gdbarch *new_gdbarch = argument;
   struct gdbarch_swap *curr;
 
   gdb_assert (current_gdbarch == NULL);
@@ -2224,13 +2225,18 @@ gdbarch_find_by_info (struct gdbarch_info info)
      architecture of the same family is found at the head of the
      rego->arches list.  */
   struct gdbarch *old_gdbarch = current_gdbarch_swap_out_hack ();
+  struct cleanup *back_to;
+
+  /* Make sure we restore current_gdbarch on our way out if an error
+     occurs.  */
+  back_to = make_cleanup (current_gdbarch_swap_in_hack, old_gdbarch);
 
   /* Find the specified architecture.  */
   struct gdbarch *new_gdbarch = find_arch_by_info (old_gdbarch, info);
 
   /* Restore the existing architecture.  */
   gdb_assert (current_gdbarch == NULL);
-  current_gdbarch_swap_in_hack (old_gdbarch);
+  do_cleanups (back_to);
 
   return new_gdbarch;
 }
index f49fa020297de60a7d41441f6519b4e81d4c3516..b20e3ae0e36229681bdd70d69a09120c4fdb3985 100644 (file)
@@ -264,6 +264,7 @@ xml_start_reg (struct xml_feature_parse_data *data,
                       sizeof (struct gdb_available_register));
   memset (reg, 0, sizeof (struct gdb_available_register));
 
+  reg->gdb_regnum = -1;
   reg->protocol_number = -1;
   reg->bitsize = -1;
   reg->readonly = -1;