2001-04-03 David Mosberger <davidm@hpl.hp.com>
[deliverable/binutils-gdb.git] / gdb / gdbarch.sh
index 541250f236acc50972a971fa0b1653566cd4f9a2..991ea132415663e3ebf83d0a38e72faadb447c2d 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh -u
 
 # Architecture commands for GDB, the GNU debugger.
-# Copyright 1998-2000 Free Software Foundation, Inc.
+# Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
 #
 # This file is part of GDB.
 #
@@ -137,22 +137,42 @@ fallback_default_p ()
 
 class_is_variable_p ()
 {
-    [ "${class}" = "v" -o "${class}" = "V" ]
+    case "${class}" in
+       *v* | *V* ) true ;;
+       * ) false ;;
+    esac
 }
 
 class_is_function_p ()
 {
-    [ "${class}" = "f" -o "${class}" = "F" ]
+    case "${class}" in
+       *f* | *F* | *m* | *M* ) true ;;
+       * ) false ;;
+    esac
+}
+
+class_is_multiarch_p ()
+{
+    case "${class}" in
+       *m* | *M* ) true ;;
+       * ) false ;;
+    esac
 }
 
 class_is_predicate_p ()
 {
-    [ "${class}" = "F" -o "${class}" = "V" ]
+    case "${class}" in
+       *F* | *V* | *M* ) true ;;
+       * ) false ;;
+    esac
 }
 
 class_is_info_p ()
 {
-    [ "${class}" = "i" ]
+    case "${class}" in
+       *i* ) true ;;
+       * ) false ;;
+    esac
 }
 
 
@@ -174,6 +194,10 @@ do
        #   hiding a variable + predicate to test variables validity
        # i -> set from info
        #   hiding something from the ``struct info'' object
+       # m -> multi-arch function
+       #   hiding a multi-arch function (parameterised with the architecture)
+        # M -> multi-arch function + predicate
+       #   hiding a multi-arch function + predicate to test function validity
 
     level ) : ;;
 
@@ -359,6 +383,9 @@ f::TARGET_WRITE_FP:void:write_fp:CORE_ADDR val:val::0:generic_target_write_fp::0
 f::TARGET_READ_SP:CORE_ADDR:read_sp:void:::0:generic_target_read_sp::0
 f::TARGET_WRITE_SP:void:write_sp:CORE_ADDR val:val::0:generic_target_write_sp::0
 #
+M:::void:register_read:int regnum, char *buf:regnum, buf:
+M:::void:register_write:int regnum, char *buf:regnum, buf:
+#
 v:2:NUM_REGS:int:num_regs::::0:-1
 # This macro gives the number of pseudo-registers that live in the
 # register namespace but do not get fetched or stored on the target.
@@ -371,6 +398,17 @@ v:2:PC_REGNUM:int:pc_regnum::::0:-1
 v:2:FP0_REGNUM:int:fp0_regnum::::0:-1::0
 v:2:NPC_REGNUM:int:npc_regnum::::0:-1::0
 v:2:NNPC_REGNUM:int:nnpc_regnum::::0:-1::0
+# Convert stab register number (from \`r\' declaration) to a gdb REGNUM.
+f:2:STAB_REG_TO_REGNUM:int:stab_reg_to_regnum:int stab_regnr:stab_regnr:::no_op_reg_to_regnum::0
+# Provide a default mapping from a ecoff register number to a gdb REGNUM.
+f:2:ECOFF_REG_TO_REGNUM:int:ecoff_reg_to_regnum:int ecoff_regnr:ecoff_regnr:::no_op_reg_to_regnum::0
+# Provide a default mapping from a DWARF register number to a gdb REGNUM.
+f:2:DWARF_REG_TO_REGNUM:int:dwarf_reg_to_regnum:int dwarf_regnr:dwarf_regnr:::no_op_reg_to_regnum::0
+# Convert from an sdb register number to an internal gdb register number.
+# This should be defined in tm.h, if REGISTER_NAMES is not set up
+# to map one to one onto the sdb register numbers.
+f:2:SDB_REG_TO_REGNUM:int:sdb_reg_to_regnum:int sdb_regnr:sdb_regnr:::no_op_reg_to_regnum::0
+f:2:DWARF2_REG_TO_REGNUM:int:dwarf2_reg_to_regnum:int dwarf2_regnr:dwarf2_regnr:::no_op_reg_to_regnum::0
 f:2:REGISTER_NAME:char *:register_name:int regnr:regnr:::legacy_register_name::0
 v:2:REGISTER_SIZE:int:register_size::::0:-1
 v:2:REGISTER_BYTES:int:register_bytes::::0:-1
@@ -384,6 +422,7 @@ f:2:DO_REGISTERS_INFO:void:do_registers_info:int reg_nr, int fpregs:reg_nr, fpre
 # MAP a GDB RAW register number onto a simulator register number.  See
 # also include/...-sim.h.
 f:2:REGISTER_SIM_REGNO:int:register_sim_regno:int reg_nr:reg_nr:::default_register_sim_regno::0
+F:2:REGISTER_BYTES_OK:int:register_bytes_ok:long nr_bytes:nr_bytes::0:0
 #
 v:1:USE_GENERIC_DUMMY_FRAMES:int:use_generic_dummy_frames::::0:-1
 v:2:CALL_DUMMY_LOCATION:int:call_dummy_location::::0:0
@@ -468,11 +507,21 @@ F:2:STACK_ALIGN:CORE_ADDR:stack_align:CORE_ADDR sp:sp::0:0
 v:1:EXTRA_STACK_ALIGNMENT_NEEDED:int:extra_stack_alignment_needed::::0:1::0:::
 F:2:REG_STRUCT_HAS_ADDR:int:reg_struct_has_addr:int gcc_p, struct type *type:gcc_p, type::0:0
 F:2:SAVE_DUMMY_FRAME_TOS:void:save_dummy_frame_tos:CORE_ADDR sp:sp::0:0
+v:2:PARM_BOUNDARY:int:parm_boundary
 #
 v:2:TARGET_FLOAT_FORMAT:const struct floatformat *:float_format::::::default_float_format (gdbarch)
 v:2:TARGET_DOUBLE_FORMAT:const struct floatformat *:double_format::::::default_double_format (gdbarch)
 v:2:TARGET_LONG_DOUBLE_FORMAT:const struct floatformat *:long_double_format::::::&floatformat_unknown
 f:2:CONVERT_FROM_FUNC_PTR_ADDR:CORE_ADDR:convert_from_func_ptr_addr:CORE_ADDR addr:addr:::default_convert_from_func_ptr_addr::0
+# FIXME/cagney/2001-01-18: This should be split in two.  A target method that indicates if
+# the target needs software single step.  An ISA method to implement it.
+#
+# FIXME/cagney/2001-01-18: This should be replaced with something that inserts breakpoints
+# using the breakpoint system instead of blatting memory directly (as with rs6000).
+#
+# FIXME/cagney/2001-01-18: The logic is backwards.  It should be asking if the target can
+# single step.  If not, then implement single step using breakpoints.
+F:2:SOFTWARE_SINGLE_STEP:void:software_single_step:enum target_signal sig, int insert_breakpoints_p:sig, insert_breakpoints_p::0:0
 EOF
 }
 
@@ -518,7 +567,7 @@ cat <<EOF
 /* *INDENT-OFF* */ /* THIS FILE IS GENERATED */
 
 /* Dynamic architecture support for GDB, the GNU debugger.
-   Copyright 1998-1999, Free Software Foundation, Inc.
+   Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -617,24 +666,35 @@ do
            -e '3,$ s,#,  ,' \
            -e '$ s,$, */,'
     fi
-    if class_is_predicate_p
+    if class_is_multiarch_p
     then
-       printf "\n"
-       printf "#if defined (${macro})\n"
-       printf "/* Legacy for systems yet to multi-arch ${macro} */\n"
-#      printf "#if (GDB_MULTI_ARCH <= GDB_MULTI_ARCH_PARTIAL) && defined (${macro})\n"
-       printf "#define ${macro}_P() (1)\n"
-       printf "#endif\n"
-       printf "\n"
-       printf "/* Default predicate for non- multi-arch targets. */\n"
-       printf "#if (!GDB_MULTI_ARCH) && !defined (${macro}_P)\n"
-       printf "#define ${macro}_P() (0)\n"
-       printf "#endif\n"
-       printf "\n"
-       printf "extern int gdbarch_${function}_p (struct gdbarch *gdbarch);\n"
-       printf "#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (${macro}_P)\n"
-       printf "#define ${macro}_P() (gdbarch_${function}_p (current_gdbarch))\n"
-       printf "#endif\n"
+       if class_is_predicate_p
+       then
+           printf "\n"
+           printf "extern int gdbarch_${function}_p (struct gdbarch *gdbarch);\n"
+       fi
+    else
+       if class_is_predicate_p
+       then
+           printf "\n"
+           printf "#if defined (${macro})\n"
+           printf "/* Legacy for systems yet to multi-arch ${macro} */\n"
+           #printf "#if (GDB_MULTI_ARCH <= GDB_MULTI_ARCH_PARTIAL) && defined (${macro})\n"
+           printf "#if !defined (${macro}_P)\n"
+           printf "#define ${macro}_P() (1)\n"
+           printf "#endif\n"
+           printf "#endif\n"
+           printf "\n"
+           printf "/* Default predicate for non- multi-arch targets. */\n"
+           printf "#if (!GDB_MULTI_ARCH) && !defined (${macro}_P)\n"
+           printf "#define ${macro}_P() (0)\n"
+           printf "#endif\n"
+           printf "\n"
+           printf "extern int gdbarch_${function}_p (struct gdbarch *gdbarch);\n"
+           printf "#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (${macro}_P)\n"
+           printf "#define ${macro}_P() (gdbarch_${function}_p (current_gdbarch))\n"
+           printf "#endif\n"
+       fi
     fi
     if class_is_variable_p
     then
@@ -658,14 +718,15 @@ do
     fi
     if class_is_function_p
     then
-       if fallback_default_p || class_is_predicate_p
+       if class_is_multiarch_p ; then :
+       elif fallback_default_p || class_is_predicate_p
        then
            printf "\n"
            printf "/* Default (function) for non- multi-arch platforms. */\n"
            printf "#if (!GDB_MULTI_ARCH) && !defined (${macro})\n"
            if [ "${fallbackdefault}" = "0" ]
            then
-               printf "#define ${macro}(${actual}) (internal_error (\"${macro}\"), 0)\n"
+               printf "#define ${macro}(${actual}) (internal_error (__FILE__, __LINE__, \"${macro}\"), 0)\n"
            else
                # FIXME: Should be passing current_gdbarch through!
                echo "#define ${macro}(${actual}) (${fallbackdefault} (${actual}))" \
@@ -674,7 +735,15 @@ do
            printf "#endif\n"
        fi
        printf "\n"
-       printf "typedef ${returntype} (gdbarch_${function}_ftype) (${formal});\n"
+       if [ "${formal}" = "void" ] && class_is_multiarch_p
+       then
+           printf "typedef ${returntype} (gdbarch_${function}_ftype) (struct gdbarch *gdbarch);\n"
+       elif class_is_multiarch_p
+       then
+           printf "typedef ${returntype} (gdbarch_${function}_ftype) (struct gdbarch *gdbarch, ${formal});\n"
+       else
+           printf "typedef ${returntype} (gdbarch_${function}_ftype) (${formal});\n"
+       fi
        if [ "${formal}" = "void" ]
        then
          printf "extern ${returntype} gdbarch_${function} (struct gdbarch *gdbarch);\n"
@@ -682,19 +751,22 @@ do
          printf "extern ${returntype} gdbarch_${function} (struct gdbarch *gdbarch, ${formal});\n"
        fi
        printf "extern void set_gdbarch_${function} (struct gdbarch *gdbarch, gdbarch_${function}_ftype *${function});\n"
-       printf "#if GDB_MULTI_ARCH\n"
-       printf "#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (${macro})\n"
-       if [ "${actual}" = "" ]
-       then
-         printf "#define ${macro}() (gdbarch_${function} (current_gdbarch))\n"
-       elif [ "${actual}" = "-" ]
-       then
-         printf "#define ${macro} (gdbarch_${function} (current_gdbarch))\n"
+       if class_is_multiarch_p ; then :
        else
-         printf "#define ${macro}(${actual}) (gdbarch_${function} (current_gdbarch, ${actual}))\n"
+           printf "#if GDB_MULTI_ARCH\n"
+           printf "#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (${macro})\n"
+           if [ "${actual}" = "" ]
+           then
+               printf "#define ${macro}() (gdbarch_${function} (current_gdbarch))\n"
+           elif [ "${actual}" = "-" ]
+           then
+               printf "#define ${macro} (gdbarch_${function} (current_gdbarch))\n"
+           else
+               printf "#define ${macro}(${actual}) (gdbarch_${function} (current_gdbarch, ${actual}))\n"
+           fi
+           printf "#endif\n"
+           printf "#endif\n"
        fi
-       printf "#endif\n"
-       printf "#endif\n"
     fi
 done
 
@@ -842,29 +914,40 @@ extern int gdbarch_update_p (struct gdbarch_info info);
 
    Reserve space for a per-architecture data-pointer.  An identifier
    for the reserved data-pointer is returned.  That identifer should
-   be saved in a local static.
+   be saved in a local static variable.
+
+   The per-architecture data-pointer can be initialized in one of two
+   ways: The value can be set explicitly using a call to
+   set_gdbarch_data(); the value can be set implicitly using the value
+   returned by a non-NULL INIT() callback.  INIT(), when non-NULL is
+   called after the basic architecture vector has been created.
 
-   When a new architecture is selected, INIT() is called.  When a
-   previous architecture is re-selected, the per-architecture
-   data-pointer for that previous architecture is restored (INIT() is
-   not called).
+   When a previously created architecture is re-selected, the
+   per-architecture data-pointer for that previous architecture is
+   restored.  INIT() is not called.
 
-   INIT() shall return the initial value for the per-architecture
-   data-pointer for the current architecture.
+   During initialization, multiple assignments of the data-pointer are
+   allowed, non-NULL values are deleted by calling FREE().  If the
+   architecture is deleted using gdbarch_free() all non-NULL data
+   pointers are also deleted using FREE().
 
    Multiple registrarants for any architecture are allowed (and
    strongly encouraged).  */
 
-typedef void *(gdbarch_data_ftype) (void);
-extern struct gdbarch_data *register_gdbarch_data (gdbarch_data_ftype *init);
+struct gdbarch_data;
 
-/* Return the value of the per-architecture data-pointer for the
-   current architecture. */
+typedef void *(gdbarch_data_init_ftype) (struct gdbarch *gdbarch);
+typedef void (gdbarch_data_free_ftype) (struct gdbarch *gdbarch,
+                                       void *pointer);
+extern struct gdbarch_data *register_gdbarch_data (gdbarch_data_init_ftype *init,
+                                                  gdbarch_data_free_ftype *free);
+extern void set_gdbarch_data (struct gdbarch *gdbarch,
+                             struct gdbarch_data *data,
+                             void *pointer);
 
 extern void *gdbarch_data (struct gdbarch_data*);
 
 
-
 /* Register per-architecture memory region.
 
    Provide a memory-region swap mechanism.  Per-architecture memory
@@ -969,7 +1052,7 @@ extern disassemble_info tm_print_insn_info;
 /* Fallback definition for EXTRACT_STRUCT_VALUE_ADDRESS */
 #ifndef EXTRACT_STRUCT_VALUE_ADDRESS
 #define EXTRACT_STRUCT_VALUE_ADDRESS_P (0)
-#define EXTRACT_STRUCT_VALUE_ADDRESS(X) (internal_error ("gdbarch: EXTRACT_STRUCT_VALUE_ADDRESS"), 0)
+#define EXTRACT_STRUCT_VALUE_ADDRESS(X) (internal_error (__FILE__, __LINE__, "gdbarch: EXTRACT_STRUCT_VALUE_ADDRESS"), 0)
 #else
 #ifndef EXTRACT_STRUCT_VALUE_ADDRESS_P
 #define EXTRACT_STRUCT_VALUE_ADDRESS_P (1)
@@ -1036,10 +1119,14 @@ cat <<EOF
 
 #include "floatformat.h"
 
+#include "gdb_assert.h"
+
 /* Static function declarations */
 
 static void verify_gdbarch (struct gdbarch *gdbarch);
+static void alloc_gdbarch_data (struct gdbarch *);
 static void init_gdbarch_data (struct gdbarch *);
+static void free_gdbarch_data (struct gdbarch *);
 static void init_gdbarch_swap (struct gdbarch *);
 static void swapout_gdbarch_swap (struct gdbarch *);
 static void swapin_gdbarch_swap (struct gdbarch *);
@@ -1080,7 +1167,7 @@ printf "  struct gdbarch_tdep *tdep;\n"
 printf "  gdbarch_dump_tdep_ftype *dump_tdep;\n"
 printf "\n"
 printf "  /* per-architecture data-pointers */\n"
-printf "  int nr_data;\n"
+printf "  unsigned nr_data;\n"
 printf "  void **data;\n"
 printf "\n"
 printf "  /* per-architecture swap-regions */\n"
@@ -1183,6 +1270,8 @@ gdbarch_alloc (const struct gdbarch_info *info,
   struct gdbarch *gdbarch = XMALLOC (struct gdbarch);
   memset (gdbarch, 0, sizeof (*gdbarch));
 
+  alloc_gdbarch_data (gdbarch);
+
   gdbarch->tdep = tdep;
 EOF
 printf "\n"
@@ -1225,8 +1314,9 @@ cat <<EOF
 void
 gdbarch_free (struct gdbarch *arch)
 {
-  /* At the moment, this is trivial.  */
-  free (arch);
+  gdb_assert (arch != NULL);
+  free_gdbarch_data (arch);
+  xfree (arch);
 }
 EOF
 
@@ -1244,9 +1334,11 @@ verify_gdbarch (struct gdbarch *gdbarch)
     return;
   /* fundamental */
   if (gdbarch->byte_order == 0)
-    internal_error ("verify_gdbarch: byte-order unset");
+    internal_error (__FILE__, __LINE__,
+                    "verify_gdbarch: byte-order unset");
   if (gdbarch->bfd_arch_info == NULL)
-    internal_error ("verify_gdbarch: bfd_arch_info unset");
+    internal_error (__FILE__, __LINE__,
+                    "verify_gdbarch: bfd_arch_info unset");
   /* Check those that need to be defined for the given multi-arch level. */
 EOF
 function_list | while do_read
@@ -1276,12 +1368,14 @@ do
        then
            printf "  if ((GDB_MULTI_ARCH >= ${level})\n"
            printf "      && (${invalid_p}))\n"
-           printf "    internal_error (\"gdbarch: verify_gdbarch: ${function} invalid\");\n"
+           printf "    internal_error (__FILE__, __LINE__,\n"
+           printf "                    \"gdbarch: verify_gdbarch: ${function} invalid\");\n"
        elif [ "${predefault}" ]
        then
            printf "  if ((GDB_MULTI_ARCH >= ${level})\n"
            printf "      && (gdbarch->${function} == ${predefault}))\n"
-           printf "    internal_error (\"gdbarch: verify_gdbarch: ${function} invalid\");\n"
+           printf "    internal_error (__FILE__, __LINE__,\n"
+           printf "                    \"gdbarch: verify_gdbarch: ${function} invalid\");\n"
        fi
     fi
 done
@@ -1310,6 +1404,8 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
 EOF
 function_list | while do_read
 do
+    # multiarch functions don't have macros.
+    class_is_multiarch_p && continue
     if [ "${returntype}" = "void" ]
     then
        printf "#if defined (${macro}) && GDB_MULTI_ARCH\n"
@@ -1332,16 +1428,24 @@ do
 done
 function_list | while do_read
 do
+    if class_is_multiarch_p
+    then
+       printf "  if (GDB_MULTI_ARCH)\n"
+       printf "    fprintf_unfiltered (file,\n"
+       printf "                        \"gdbarch_dump: ${function} = 0x%%08lx\\\\n\",\n"
+       printf "                        (long) current_gdbarch->${function});\n"
+       continue
+    fi
     printf "#ifdef ${macro}\n"
     if [ "${print_p}" = "()" ]
     then
-       printf "  gdbarch_dump_${function} (current_gdbarch);\n"
+        printf "  gdbarch_dump_${function} (current_gdbarch);\n"
     elif [ "${print_p}" = "0" ]
     then
-       printf "  /* skip print of ${macro}, print_p == 0. */\n"
+        printf "  /* skip print of ${macro}, print_p == 0. */\n"
     elif [ "${print_p}" ]
     then
-       printf "  if (${print_p})\n"
+        printf "  if (${print_p})\n"
        printf "    fprintf_unfiltered (file,\n"
        printf "                        \"gdbarch_dump: ${macro} = %s\\\\n\",\n" "${fmt}"
        printf "                        ${print});\n"
@@ -1406,15 +1510,31 @@ do
        fi
        printf "{\n"
         printf "  if (gdbarch->${function} == 0)\n"
-        printf "    internal_error (\"gdbarch: gdbarch_${function} invalid\");\n"
+        printf "    internal_error (__FILE__, __LINE__,\n"
+       printf "                    \"gdbarch: gdbarch_${function} invalid\");\n"
        printf "  if (gdbarch_debug >= 2)\n"
        printf "    fprintf_unfiltered (gdb_stdlog, \"gdbarch_${function} called\\\\n\");\n"
-        test "${actual}" = "-" && actual=""
+       if [ "${actual}" = "-" -o "${actual}" = "" ]
+       then
+           if class_is_multiarch_p
+           then
+               params="gdbarch"
+           else
+               params=""
+           fi
+       else
+           if class_is_multiarch_p
+           then
+               params="gdbarch, ${actual}"
+           else
+               params="${actual}"
+           fi
+        fi
                if [ "${returntype}" = "void" ]
        then
-         printf "  gdbarch->${function} (${actual});\n"
+         printf "  gdbarch->${function} (${params});\n"
        else
-         printf "  return gdbarch->${function} (${actual});\n"
+         printf "  return gdbarch->${function} (${params});\n"
        fi
        printf "}\n"
        printf "\n"
@@ -1436,11 +1556,13 @@ do
        elif [ "${invalid_p}" ]
        then
          printf "  if (${invalid_p})\n"
-         printf "    internal_error (\"gdbarch: gdbarch_${function} invalid\");\n"
+         printf "    internal_error (__FILE__, __LINE__,\n"
+         printf "                    \"gdbarch: gdbarch_${function} invalid\");\n"
        elif [ "${predefault}" ]
        then
          printf "  if (gdbarch->${function} == ${predefault})\n"
-         printf "    internal_error (\"gdbarch: gdbarch_${function} invalid\");\n"
+         printf "    internal_error (__FILE__, __LINE__,\n"
+         printf "                    \"gdbarch: gdbarch_${function} invalid\");\n"
        fi
        printf "  if (gdbarch_debug >= 2)\n"
        printf "    fprintf_unfiltered (gdb_stdlog, \"gdbarch_${function} called\\\\n\");\n"
@@ -1470,44 +1592,47 @@ done
 cat <<EOF
 
 
-/* Keep a registrary of per-architecture data-pointers required by GDB
+/* Keep a registry of per-architecture data-pointers required by GDB
    modules. */
 
 struct gdbarch_data
 {
-  int index;
+  unsigned index;
+  gdbarch_data_init_ftype *init;
+  gdbarch_data_free_ftype *free;
 };
 
 struct gdbarch_data_registration
 {
-  gdbarch_data_ftype *init;
   struct gdbarch_data *data;
   struct gdbarch_data_registration *next;
 };
 
-struct gdbarch_data_registrary
+struct gdbarch_data_registry
 {
-  int nr;
+  unsigned nr;
   struct gdbarch_data_registration *registrations;
 };
 
-struct gdbarch_data_registrary gdbarch_data_registrary =
+struct gdbarch_data_registry gdbarch_data_registry =
 {
   0, NULL,
 };
 
 struct gdbarch_data *
-register_gdbarch_data (gdbarch_data_ftype *init)
+register_gdbarch_data (gdbarch_data_init_ftype *init,
+                       gdbarch_data_free_ftype *free)
 {
   struct gdbarch_data_registration **curr;
-  for (curr = &gdbarch_data_registrary.registrations;
+  for (curr = &gdbarch_data_registry.registrations;
        (*curr) != NULL;
        curr = &(*curr)->next);
   (*curr) = XMALLOC (struct gdbarch_data_registration);
   (*curr)->next = NULL;
-  (*curr)->init = init;
   (*curr)->data = XMALLOC (struct gdbarch_data);
-  (*curr)->data->index = gdbarch_data_registrary.nr++;
+  (*curr)->data->index = gdbarch_data_registry.nr++;
+  (*curr)->data->init = init;
+  (*curr)->data->free = free;
   return (*curr)->data;
 }
 
@@ -1518,17 +1643,65 @@ static void
 init_gdbarch_data (struct gdbarch *gdbarch)
 {
   struct gdbarch_data_registration *rego;
-  gdbarch->nr_data = gdbarch_data_registrary.nr + 1;
-  gdbarch->data = xmalloc (sizeof (void*) * gdbarch->nr_data);
-  for (rego = gdbarch_data_registrary.registrations;
+  for (rego = gdbarch_data_registry.registrations;
        rego != NULL;
        rego = rego->next)
     {
-      if (rego->data->index < gdbarch->nr_data)
-       gdbarch->data[rego->data->index] = rego->init ();
+      struct gdbarch_data *data = rego->data;
+      gdb_assert (data->index < gdbarch->nr_data);
+      if (data->init != NULL)
+        {
+          void *pointer = data->init (gdbarch);
+          set_gdbarch_data (gdbarch, data, pointer);
+        }
     }
 }
 
+/* Create/delete the gdbarch data vector. */
+
+static void
+alloc_gdbarch_data (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch->data == NULL);
+  gdbarch->nr_data = gdbarch_data_registry.nr;
+  gdbarch->data = xcalloc (gdbarch->nr_data, sizeof (void*));
+}
+
+static void
+free_gdbarch_data (struct gdbarch *gdbarch)
+{
+  struct gdbarch_data_registration *rego;
+  gdb_assert (gdbarch->data != NULL);
+  for (rego = gdbarch_data_registry.registrations;
+       rego != NULL;
+       rego = rego->next)
+    {
+      struct gdbarch_data *data = rego->data;
+      gdb_assert (data->index < gdbarch->nr_data);
+      if (data->free != NULL && gdbarch->data[data->index] != NULL)
+        {
+          data->free (gdbarch, gdbarch->data[data->index]);
+          gdbarch->data[data->index] = NULL;
+        }
+    }
+  xfree (gdbarch->data);
+  gdbarch->data = NULL;
+}
+
+
+/* Initialize the current value of thee specified per-architecture
+   data-pointer. */
+
+void
+set_gdbarch_data (struct gdbarch *gdbarch,
+                  struct gdbarch_data *data,
+                  void *pointer)
+{
+  gdb_assert (data->index < gdbarch->nr_data);
+  if (data->free != NULL && gdbarch->data[data->index] != NULL)
+    data->free (gdbarch, gdbarch->data[data->index]);
+  gdbarch->data[data->index] = pointer;
+}
 
 /* Return the current value of the specified per-architecture
    data-pointer. */
@@ -1536,14 +1709,13 @@ init_gdbarch_data (struct gdbarch *gdbarch)
 void *
 gdbarch_data (struct gdbarch_data *data)
 {
-  if (data->index >= current_gdbarch->nr_data)
-    internal_error ("gdbarch_data: request for non-existant data.");
+  gdb_assert (data->index < current_gdbarch->nr_data);
   return current_gdbarch->data[data->index];
 }
 
 
 
-/* Keep a registrary of swapped data required by GDB modules. */
+/* Keep a registry of swapped data required by GDB modules. */
 
 struct gdbarch_swap
 {
@@ -1560,13 +1732,13 @@ struct gdbarch_swap_registration
   struct gdbarch_swap_registration *next;
 };
 
-struct gdbarch_swap_registrary
+struct gdbarch_swap_registry
 {
   int nr;
   struct gdbarch_swap_registration *registrations;
 };
 
-struct gdbarch_swap_registrary gdbarch_swap_registrary = 
+struct gdbarch_swap_registry gdbarch_swap_registry = 
 {
   0, NULL,
 };
@@ -1577,7 +1749,7 @@ register_gdbarch_swap (void *data,
                       gdbarch_swap_ftype *init)
 {
   struct gdbarch_swap_registration **rego;
-  for (rego = &gdbarch_swap_registrary.registrations;
+  for (rego = &gdbarch_swap_registry.registrations;
        (*rego) != NULL;
        rego = &(*rego)->next);
   (*rego) = XMALLOC (struct gdbarch_swap_registration);
@@ -1593,7 +1765,7 @@ init_gdbarch_swap (struct gdbarch *gdbarch)
 {
   struct gdbarch_swap_registration *rego;
   struct gdbarch_swap **curr = &gdbarch->swap;
-  for (rego = gdbarch_swap_registrary.registrations;
+  for (rego = gdbarch_swap_registry.registrations;
        rego != NULL;
        rego = rego->next)
     {
@@ -1632,7 +1804,7 @@ swapin_gdbarch_swap (struct gdbarch *gdbarch)
 }
 
 
-/* Keep a registrary of the architectures known by GDB. */
+/* Keep a registry of the architectures known by GDB. */
 
 struct gdbarch_registration
 {
@@ -1643,7 +1815,7 @@ struct gdbarch_registration
   struct gdbarch_registration *next;
 };
 
-static struct gdbarch_registration *gdbarch_registrary = NULL;
+static struct gdbarch_registration *gdbarch_registry = NULL;
 
 static void
 append_name (const char ***buf, int *nr, const char *name)
@@ -1664,14 +1836,15 @@ gdbarch_printable_names (void)
       int nr_arches = 0;
       const char **arches = NULL;
       struct gdbarch_registration *rego;
-      for (rego = gdbarch_registrary;
+      for (rego = gdbarch_registry;
           rego != NULL;
           rego = rego->next)
        {
          const struct bfd_arch_info *ap;
          ap = bfd_lookup_arch (rego->bfd_architecture, 0);
          if (ap == NULL)
-           internal_error ("gdbarch_architecture_names: multi-arch unknown");
+           internal_error (__FILE__, __LINE__,
+                            "gdbarch_architecture_names: multi-arch unknown");
          do
            {
              append_name (&arches, &nr_arches, ap->printable_name);
@@ -1700,16 +1873,19 @@ gdbarch_register (enum bfd_architecture bfd_architecture,
   bfd_arch_info = bfd_lookup_arch (bfd_architecture, 0);
   if (bfd_arch_info == NULL)
     {
-      internal_error ("gdbarch: Attempt to register unknown architecture (%d)", bfd_architecture);
+      internal_error (__FILE__, __LINE__,
+                      "gdbarch: Attempt to register unknown architecture (%d)",
+                      bfd_architecture);
     }
   /* Check that we haven't seen this architecture before */
-  for (curr = &gdbarch_registrary;
+  for (curr = &gdbarch_registry;
        (*curr) != NULL;
        curr = &(*curr)->next)
     {
       if (bfd_architecture == (*curr)->bfd_architecture)
-       internal_error ("gdbarch: Duplicate registraration of architecture (%s)",
-              bfd_arch_info->printable_name);
+       internal_error (__FILE__, __LINE__,
+                        "gdbarch: Duplicate registraration of architecture (%s)",
+                       bfd_arch_info->printable_name);
     }
   /* log it */
   if (gdbarch_debug)
@@ -1800,7 +1976,7 @@ gdbarch_update_p (struct gdbarch_info info)
   /* A default for abfd? */
 
   /* Find the target that knows about this architecture. */
-  for (rego = gdbarch_registrary;
+  for (rego = gdbarch_registry;
        rego != NULL;
        rego = rego->next)
     if (rego->bfd_architecture == info.bfd_architecture)
This page took 0.031527 seconds and 4 git commands to generate.