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


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

[16/19] address class support


Hello,

handling of architecture-specific address class flags is somewhat
problematical.

Current code uses gdbarch macros on current_gdbarch to translate
between an address space name and its numerical representation in
terms of type flags:

const char *
address_space_int_to_name (int space_flag)
{
  struct gdbarch *gdbarch = current_gdbarch;
  if (space_flag & TYPE_INSTANCE_FLAG_CODE_SPACE)
    return "code";
  else if (space_flag & TYPE_INSTANCE_FLAG_DATA_SPACE)
    return "data";
  else if ((space_flag & TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL)
           && gdbarch_address_class_type_flags_to_name_p (gdbarch))
    return gdbarch_address_class_type_flags_to_name (gdbarch, space_flag);
  else
    return NULL;
}

However, the caller of this routine in c-typeprint.c fundamentally
does not have an appropriate architecture available -- this routine
operates simply on a GDB types, and those are deliberately *not*
architecture specific.

It seems that if we want to have types that are not architecture-
specific, then the meaning of type flags cannot be architecture-
specific either, so the use of gdbarch routines to encode/decode
those flags cannot be appropriate.


This patch changes the code to use an architecture-independent
list of supported address class names instead.  An architecture
can install a new entry into this list -- but the resulting
number will still be valid throughout GDB.  (When building GDB
with different --enable-target flags, more or fewer or those
names will get installed and so the numbers may be different
between different GDB builds.)

Those numerical codes for address space names are then used
instead of type flags.  In fact, I'm simply using the four bits
in the type flag field as a single bit field holding up to 16
different values.  This should be plenty for now, as only 4
address space names are used (generic, the default "code" and
"data" names for harvard architectures, and "mode32" installed
by the s390 back-end -- the Cell/B.E. support will add a fifth).
If we ever are in danger of running out, we can add more bits.


In addition, the current code has some confusion on whether to
call it "address space" or "address class".  The patch renames
some existing routines to more consistently use the term "class".

Bye,
Ulrich

ChangeLog:

	* gdbtypes.h (TYPE_INSTANCE_FLAG_CODE_SPACE,
	TYPE_INSTANCE_FLAG_DATA_SPACE, TYPE_INSTANCE_FLAG_ADDRESS_CLASS_1,
	TYPE_INSTANCE_FLAG_ADDRESS_CLASS_2): Remove, replace by ...
	(TYPE_INSTANCE_FLAG_ADDRESS_CLASS_min,
	TYPE_INSTANCE_FLAG_ADDRESS_CLASS_max): ... these new flags.
	(TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL): Adapt.
	(TYPE_ADDRESS_CLASS_1, TYPE_ADDRESS_CLASS_2): Remove.
	(TYPE_ADDRESS_CLASS_ALL): Remove.
	(TYPE_ADDRESS_CLASS, TYPE_INSTANCE_FLAG_ADDRESS_CLASS): New macros.
	(TYPE_ADDRESS_CLASS_GENERIC, TYPE_ADDRESS_CLASS_CODE,
	TYPE_ADDRESS_CLASS_DATA, TYPE_ADDRESS_CLASS_MAX): New defines.
	(TYPE_CODE_SPACE, TYPE_DATA_SPACE): Update for TYPE_INSTANCE_FLAGS
	changes.
	(address_class_register_identifier): Add prototype.
	(address_space_name_to_int, address_space_int_to_name): Remove.
	(address_class_name_to_int, address_class_int_to_name): New prototypes.
	(make_type_with_address_space): Remove, replace by ...
	(make_type_with_address_class): ... this.

	* gdbtypes.c (address_class_identifier): New static variable.
	(address_class_register_identifier): New function.
	(address_space_name_to_int, address_space_int_to_name): Remove.
	(address_class_name_to_int, address_class_int_to_name): New functions.
	(make_type_with_address_space): Remove, replace by ...
	(make_type_with_address_class): ... this.
	(replace_type): Update for TYPE_INSTANCE_FLAGS changes.
	(recursive_dump_type): Likewise.

	* c-typeprint.c (c_type_print_modifier): Update to new name of
	address_class_int_to_name.  Pass TYPE_ADDRESS_CLASS instead of
	TYPE_INSTANCE_FLAGS.

	* gdbarch.sh (address_class_type_flags): Remove, replace by ...
	(type_address_class): ... this.
	(address_class_type_flags_to_name): Remove.
	(address_class_name_to_type_flags): Remove.
	* gdbarch.c, gdbarch.h: Regenerate.

	* dwarf2read.c (read_tag_pointer_type): Call gdbarch_type_address_class
	and make_type_with_address_class.

	* s390-tdep.c (s390_address_class_mode32): New static variable.
	(s390_address_class_type_flags): Remove.
	(s390_address_class_type_flags_to_name): Remove.
	(s390_address_class_name_to_type_flags): Remove.
	(s390_type_address_class): New function.
	(s390_gdbarch_init): Update.
	(_initialize_s390_tdep): Register address class identifier.

	* parser-defs.h (enum type_pieces): Rename tp_space_identifier to
	tp_address_class.
	(push_type_address_space): Rename to ...
	(push_type_address_class): ... this.
	* c-exp.y: Update to renamings.
	* parse.c (push_type_address_class): Likewise.
	(follow_types): Likewise.

doc/ChangeLog:

	* gdbint.texinfo (Address Classes): Updated.
	(Target Conditionals): Document gdbarch_type_address_class and
	address_class_register_identifier instead of
	gdbarch_address_class_type_flags,
	gdbarch_address_class_type_flags_to_name, and
	gdbarch_address_class_name_to_type_flags.


Index: gdb-head/gdb/c-typeprint.c
===================================================================
--- gdb-head.orig/gdb/c-typeprint.c
+++ gdb-head/gdb/c-typeprint.c
@@ -316,7 +316,7 @@ c_type_print_modifier (struct type *type
 		       int need_pre_space, int need_post_space)
 {
   int did_print_modifier = 0;
-  const char *address_space_id;
+  const char *address_class_id;
 
   /* We don't print `const' qualifiers for references --- since all
      operators affect the thing referenced, not the reference itself,
@@ -338,12 +338,12 @@ c_type_print_modifier (struct type *type
       did_print_modifier = 1;
     }
 
-  address_space_id = address_space_int_to_name (TYPE_INSTANCE_FLAGS (type));
-  if (address_space_id)
+  address_class_id = address_class_int_to_name (TYPE_ADDRESS_CLASS (type));
+  if (address_class_id)
     {
       if (did_print_modifier || need_pre_space)
 	fprintf_filtered (stream, " ");
-      fprintf_filtered (stream, "@%s", address_space_id);
+      fprintf_filtered (stream, "@%s", address_class_id);
       did_print_modifier = 1;
     }
 
Index: gdb-head/gdb/gdbarch.c
===================================================================
--- gdb-head.orig/gdb/gdbarch.c
+++ gdb-head/gdb/gdbarch.c
@@ -216,9 +216,7 @@ struct gdbarch
   gdbarch_coff_make_msymbol_special_ftype *coff_make_msymbol_special;
   int cannot_step_breakpoint;
   int have_nonsteppable_watchpoint;
-  gdbarch_address_class_type_flags_ftype *address_class_type_flags;
-  gdbarch_address_class_type_flags_to_name_ftype *address_class_type_flags_to_name;
-  gdbarch_address_class_name_to_type_flags_ftype *address_class_name_to_type_flags;
+  gdbarch_type_address_class_ftype *type_address_class;
   gdbarch_register_reggroup_p_ftype *register_reggroup_p;
   gdbarch_fetch_pointer_argument_ftype *fetch_pointer_argument;
   gdbarch_regset_from_core_section_ftype *regset_from_core_section;
@@ -352,9 +350,7 @@ struct gdbarch startup_gdbarch =
   0,  /* coff_make_msymbol_special */
   0,  /* cannot_step_breakpoint */
   0,  /* have_nonsteppable_watchpoint */
-  0,  /* address_class_type_flags */
-  0,  /* address_class_type_flags_to_name */
-  0,  /* address_class_name_to_type_flags */
+  0,  /* type_address_class */
   default_register_reggroup_p,  /* register_reggroup_p */
   0,  /* fetch_pointer_argument */
   0,  /* regset_from_core_section */
@@ -607,9 +603,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of coff_make_msymbol_special, invalid_p == 0 */
   /* Skip verify of cannot_step_breakpoint, invalid_p == 0 */
   /* Skip verify of have_nonsteppable_watchpoint, invalid_p == 0 */
-  /* Skip verify of address_class_type_flags, has predicate */
-  /* Skip verify of address_class_type_flags_to_name, has predicate */
-  /* Skip verify of address_class_name_to_type_flags, has predicate */
+  /* Skip verify of type_address_class, has predicate */
   /* Skip verify of register_reggroup_p, invalid_p == 0 */
   /* Skip verify of fetch_pointer_argument, has predicate */
   /* Skip verify of regset_from_core_section, has predicate */
@@ -666,24 +660,6 @@ gdbarch_dump (struct gdbarch *gdbarch, s
                       "gdbarch_dump: addr_bits_remove = <%s>\n",
                       host_address_to_string (gdbarch->addr_bits_remove));
   fprintf_unfiltered (file,
-                      "gdbarch_dump: gdbarch_address_class_name_to_type_flags_p() = %d\n",
-                      gdbarch_address_class_name_to_type_flags_p (gdbarch));
-  fprintf_unfiltered (file,
-                      "gdbarch_dump: address_class_name_to_type_flags = <%s>\n",
-                      host_address_to_string (gdbarch->address_class_name_to_type_flags));
-  fprintf_unfiltered (file,
-                      "gdbarch_dump: gdbarch_address_class_type_flags_p() = %d\n",
-                      gdbarch_address_class_type_flags_p (gdbarch));
-  fprintf_unfiltered (file,
-                      "gdbarch_dump: address_class_type_flags = <%s>\n",
-                      host_address_to_string (gdbarch->address_class_type_flags));
-  fprintf_unfiltered (file,
-                      "gdbarch_dump: gdbarch_address_class_type_flags_to_name_p() = %d\n",
-                      gdbarch_address_class_type_flags_to_name_p (gdbarch));
-  fprintf_unfiltered (file,
-                      "gdbarch_dump: address_class_type_flags_to_name = <%s>\n",
-                      host_address_to_string (gdbarch->address_class_type_flags_to_name));
-  fprintf_unfiltered (file,
                       "gdbarch_dump: address_to_pointer = <%s>\n",
                       host_address_to_string (gdbarch->address_to_pointer));
   fprintf_unfiltered (file,
@@ -1098,6 +1074,12 @@ gdbarch_dump (struct gdbarch *gdbarch, s
                       "gdbarch_dump: target_signal_to_host = <%s>\n",
                       host_address_to_string (gdbarch->target_signal_to_host));
   fprintf_unfiltered (file,
+                      "gdbarch_dump: gdbarch_type_address_class_p() = %d\n",
+                      gdbarch_type_address_class_p (gdbarch));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: type_address_class = <%s>\n",
+                      host_address_to_string (gdbarch->type_address_class));
+  fprintf_unfiltered (file,
                       "gdbarch_dump: gdbarch_unwind_pc_p() = %d\n",
                       gdbarch_unwind_pc_p (gdbarch));
   fprintf_unfiltered (file,
@@ -2769,75 +2751,27 @@ set_gdbarch_have_nonsteppable_watchpoint
 }
 
 int
-gdbarch_address_class_type_flags_p (struct gdbarch *gdbarch)
-{
-  gdb_assert (gdbarch != NULL);
-  return gdbarch->address_class_type_flags != NULL;
-}
-
-int
-gdbarch_address_class_type_flags (struct gdbarch *gdbarch, int byte_size, int dwarf2_addr_class)
-{
-  gdb_assert (gdbarch != NULL);
-  gdb_assert (gdbarch->address_class_type_flags != NULL);
-  if (gdbarch_debug >= 2)
-    fprintf_unfiltered (gdb_stdlog, "gdbarch_address_class_type_flags called\n");
-  return gdbarch->address_class_type_flags (byte_size, dwarf2_addr_class);
-}
-
-void
-set_gdbarch_address_class_type_flags (struct gdbarch *gdbarch,
-                                      gdbarch_address_class_type_flags_ftype address_class_type_flags)
-{
-  gdbarch->address_class_type_flags = address_class_type_flags;
-}
-
-int
-gdbarch_address_class_type_flags_to_name_p (struct gdbarch *gdbarch)
-{
-  gdb_assert (gdbarch != NULL);
-  return gdbarch->address_class_type_flags_to_name != NULL;
-}
-
-const char *
-gdbarch_address_class_type_flags_to_name (struct gdbarch *gdbarch, int type_flags)
-{
-  gdb_assert (gdbarch != NULL);
-  gdb_assert (gdbarch->address_class_type_flags_to_name != NULL);
-  if (gdbarch_debug >= 2)
-    fprintf_unfiltered (gdb_stdlog, "gdbarch_address_class_type_flags_to_name called\n");
-  return gdbarch->address_class_type_flags_to_name (gdbarch, type_flags);
-}
-
-void
-set_gdbarch_address_class_type_flags_to_name (struct gdbarch *gdbarch,
-                                              gdbarch_address_class_type_flags_to_name_ftype address_class_type_flags_to_name)
-{
-  gdbarch->address_class_type_flags_to_name = address_class_type_flags_to_name;
-}
-
-int
-gdbarch_address_class_name_to_type_flags_p (struct gdbarch *gdbarch)
+gdbarch_type_address_class_p (struct gdbarch *gdbarch)
 {
   gdb_assert (gdbarch != NULL);
-  return gdbarch->address_class_name_to_type_flags != NULL;
+  return gdbarch->type_address_class != NULL;
 }
 
 int
-gdbarch_address_class_name_to_type_flags (struct gdbarch *gdbarch, const char *name, int *type_flags_ptr)
+gdbarch_type_address_class (struct gdbarch *gdbarch, int byte_size, int dwarf2_addr_class)
 {
   gdb_assert (gdbarch != NULL);
-  gdb_assert (gdbarch->address_class_name_to_type_flags != NULL);
+  gdb_assert (gdbarch->type_address_class != NULL);
   if (gdbarch_debug >= 2)
-    fprintf_unfiltered (gdb_stdlog, "gdbarch_address_class_name_to_type_flags called\n");
-  return gdbarch->address_class_name_to_type_flags (gdbarch, name, type_flags_ptr);
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_type_address_class called\n");
+  return gdbarch->type_address_class (byte_size, dwarf2_addr_class);
 }
 
 void
-set_gdbarch_address_class_name_to_type_flags (struct gdbarch *gdbarch,
-                                              gdbarch_address_class_name_to_type_flags_ftype address_class_name_to_type_flags)
+set_gdbarch_type_address_class (struct gdbarch *gdbarch,
+                                gdbarch_type_address_class_ftype type_address_class)
 {
-  gdbarch->address_class_name_to_type_flags = address_class_name_to_type_flags;
+  gdbarch->type_address_class = type_address_class;
 }
 
 int
Index: gdb-head/gdb/gdbarch.h
===================================================================
--- gdb-head.orig/gdb/gdbarch.h
+++ gdb-head/gdb/gdbarch.h
@@ -595,23 +595,11 @@ extern void set_gdbarch_cannot_step_brea
 extern int gdbarch_have_nonsteppable_watchpoint (struct gdbarch *gdbarch);
 extern void set_gdbarch_have_nonsteppable_watchpoint (struct gdbarch *gdbarch, int have_nonsteppable_watchpoint);
 
-extern int gdbarch_address_class_type_flags_p (struct gdbarch *gdbarch);
+extern int gdbarch_type_address_class_p (struct gdbarch *gdbarch);
 
-typedef int (gdbarch_address_class_type_flags_ftype) (int byte_size, int dwarf2_addr_class);
-extern int gdbarch_address_class_type_flags (struct gdbarch *gdbarch, int byte_size, int dwarf2_addr_class);
-extern void set_gdbarch_address_class_type_flags (struct gdbarch *gdbarch, gdbarch_address_class_type_flags_ftype *address_class_type_flags);
-
-extern int gdbarch_address_class_type_flags_to_name_p (struct gdbarch *gdbarch);
-
-typedef const char * (gdbarch_address_class_type_flags_to_name_ftype) (struct gdbarch *gdbarch, int type_flags);
-extern const char * gdbarch_address_class_type_flags_to_name (struct gdbarch *gdbarch, int type_flags);
-extern void set_gdbarch_address_class_type_flags_to_name (struct gdbarch *gdbarch, gdbarch_address_class_type_flags_to_name_ftype *address_class_type_flags_to_name);
-
-extern int gdbarch_address_class_name_to_type_flags_p (struct gdbarch *gdbarch);
-
-typedef int (gdbarch_address_class_name_to_type_flags_ftype) (struct gdbarch *gdbarch, const char *name, int *type_flags_ptr);
-extern int gdbarch_address_class_name_to_type_flags (struct gdbarch *gdbarch, const char *name, int *type_flags_ptr);
-extern void set_gdbarch_address_class_name_to_type_flags (struct gdbarch *gdbarch, gdbarch_address_class_name_to_type_flags_ftype *address_class_name_to_type_flags);
+typedef int (gdbarch_type_address_class_ftype) (int byte_size, int dwarf2_addr_class);
+extern int gdbarch_type_address_class (struct gdbarch *gdbarch, int byte_size, int dwarf2_addr_class);
+extern void set_gdbarch_type_address_class (struct gdbarch *gdbarch, gdbarch_type_address_class_ftype *type_address_class);
 
 /* Is a register in a group */
 
Index: gdb-head/gdb/gdbarch.sh
===================================================================
--- gdb-head.orig/gdb/gdbarch.sh
+++ gdb-head/gdb/gdbarch.sh
@@ -579,9 +579,7 @@ f:void:elf_make_msymbol_special:asymbol 
 f:void:coff_make_msymbol_special:int val, struct minimal_symbol *msym:val, msym::default_coff_make_msymbol_special::0
 v:int:cannot_step_breakpoint:::0:0::0
 v:int:have_nonsteppable_watchpoint:::0:0::0
-F:int:address_class_type_flags:int byte_size, int dwarf2_addr_class:byte_size, dwarf2_addr_class
-M:const char *:address_class_type_flags_to_name:int type_flags:type_flags
-M:int:address_class_name_to_type_flags:const char *name, int *type_flags_ptr:name, type_flags_ptr
+F:int:type_address_class:int byte_size, int dwarf2_addr_class:byte_size, dwarf2_addr_class
 # Is a register in a group
 m:int:register_reggroup_p:int regnum, struct reggroup *reggroup:regnum, reggroup::default_register_reggroup_p::0
 # Fetch the pointer to the ith function argument.
Index: gdb-head/gdb/gdbtypes.c
===================================================================
--- gdb-head.orig/gdb/gdbtypes.c
+++ gdb-head/gdb/gdbtypes.c
@@ -418,41 +418,56 @@ lookup_function_type (struct type *type)
   return make_function_type (type, (struct type **) 0, TYPE_OBJFILE (type));
 }
 
-/* Identify address space identifier by name --
-   return the integer flag defined in gdbtypes.h.  */
-extern int
-address_space_name_to_int (char *space_identifier)
+/* List of global address class identifiers.  */
+static const char *address_class_identifier[TYPE_ADDRESS_CLASS_MAX] =
+  {
+    NULL,    /* Generic address class.  */
+    "code",  /* Code space for Harvard architectures.  */
+    "data",  /* Data space for Harvard architectures.  */
+
+    /* Identifiers registered by address_class_register_identifiers.  */
+   };
+
+/* Register a new global address class identifier.  */
+int
+address_class_register_identifier (const char *class_identifier)
 {
-  struct gdbarch *gdbarch = current_gdbarch;
-  int type_flags;
-  /* Check for known address space delimiters.  */
-  if (!strcmp (space_identifier, "code"))
-    return TYPE_INSTANCE_FLAG_CODE_SPACE;
-  else if (!strcmp (space_identifier, "data"))
-    return TYPE_INSTANCE_FLAG_DATA_SPACE;
-  else if (gdbarch_address_class_name_to_type_flags_p (gdbarch)
-           && gdbarch_address_class_name_to_type_flags (gdbarch,
-							space_identifier,
-							&type_flags))
-    return type_flags;
-  else
-    error (_("Unknown address space specifier: \"%s\""), space_identifier);
+  int class_nr;
+
+  for (class_nr = 1; class_nr < TYPE_ADDRESS_CLASS_MAX; class_nr++)
+    if (address_class_identifier[class_nr] == NULL)
+      {
+	address_class_identifier[class_nr] = xstrdup (class_identifier);
+	return class_nr;
+      }
+
+  internal_error (__FILE__, __LINE__,
+		  "address_class_register_identifier: too many identifiers");
 }
 
-/* Identify address space identifier by integer flag as defined in 
-   gdbtypes.h -- return the string version of the adress space name.  */
+/* Identify address class identifier by name.  */
+extern int
+address_class_name_to_int (char *class_identifier)
+{
+  int class_nr;
+
+  for (class_nr = 1; class_nr < TYPE_ADDRESS_CLASS_MAX; class_nr++)
+    {
+      if (!address_class_identifier[class_nr])
+	break;
+      if (strcmp (address_class_identifier[class_nr], class_identifier) == 0)
+	return class_nr;
+    }
+
+  error (_("Unknown address class specifier: \"%s\""), class_identifier);
+}
 
+/* Identify address class identifier by integer.  */
 const char *
-address_space_int_to_name (int space_flag)
+address_class_int_to_name (int class_nr)
 {
-  struct gdbarch *gdbarch = current_gdbarch;
-  if (space_flag & TYPE_INSTANCE_FLAG_CODE_SPACE)
-    return "code";
-  else if (space_flag & TYPE_INSTANCE_FLAG_DATA_SPACE)
-    return "data";
-  else if ((space_flag & TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL)
-           && gdbarch_address_class_type_flags_to_name_p (gdbarch))
-    return gdbarch_address_class_type_flags_to_name (gdbarch, space_flag);
+  if (class_nr < TYPE_ADDRESS_CLASS_MAX)
+    return address_class_identifier[class_nr];
   else
     return NULL;
 }
@@ -511,24 +526,22 @@ make_qualified_type (struct type *type, 
   return ntype;
 }
 
-/* Make an address-space-delimited variant of a type -- a type that
+/* Make an address-class-delimited variant of a type -- a type that
    is identical to the one supplied except that it has an address
-   space attribute attached to it (such as "code" or "data").
+   class attribute attached to it (such as "code" or "data").
 
-   The space attributes "code" and "data" are for Harvard
-   architectures.  The address space attributes are for architectures
+   The address class attributes "code" and "data" are for Harvard
+   architectures.  Other address class attributes are for architectures
    which have alternately sized pointers or pointers with alternate
    representations.  */
 
 struct type *
-make_type_with_address_space (struct type *type, int space_flag)
+make_type_with_address_class (struct type *type, int class_nr)
 {
   struct type *ntype;
   int new_flags = ((TYPE_INSTANCE_FLAGS (type)
-		    & ~(TYPE_INSTANCE_FLAG_CODE_SPACE
-			| TYPE_INSTANCE_FLAG_DATA_SPACE
-		        | TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL))
-		   | space_flag);
+		    & ~TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL)
+		   | TYPE_INSTANCE_FLAG_ADDRESS_CLASS (class_nr));
 
   return make_qualified_type (type, new_flags, NULL);
 }
@@ -621,7 +634,7 @@ replace_type (struct type *ntype, struct
 	 variants.  This assertion shouldn't ever be triggered because
 	 symbol readers which do construct address-class variants don't
 	 call replace_type().  */
-      gdb_assert (TYPE_ADDRESS_CLASS_ALL (chain) == 0);
+      gdb_assert (TYPE_ADDRESS_CLASS (chain) == TYPE_ADDRESS_CLASS_GENERIC);
 
       TYPE_LENGTH (chain) = TYPE_LENGTH (type);
       chain = TYPE_CHAIN (chain);
@@ -2738,21 +2751,9 @@ recursive_dump_type (struct type *type, 
     {
       puts_filtered (" TYPE_FLAG_VOLATILE");
     }
-  if (TYPE_CODE_SPACE (type))
-    {
-      puts_filtered (" TYPE_FLAG_CODE_SPACE");
-    }
-  if (TYPE_DATA_SPACE (type))
-    {
-      puts_filtered (" TYPE_FLAG_DATA_SPACE");
-    }
-  if (TYPE_ADDRESS_CLASS_1 (type))
-    {
-      puts_filtered (" TYPE_FLAG_ADDRESS_CLASS_1");
-    }
-  if (TYPE_ADDRESS_CLASS_2 (type))
+  if (TYPE_ADDRESS_CLASS (type) != TYPE_ADDRESS_CLASS_GENERIC)
     {
-      puts_filtered (" TYPE_FLAG_ADDRESS_CLASS_2");
+      printf_filtered (" (address class %d)", TYPE_ADDRESS_CLASS (type));
     }
   puts_filtered ("\n");
 
Index: gdb-head/gdb/gdbtypes.h
===================================================================
--- gdb-head.orig/gdb/gdbtypes.h
+++ gdb-head/gdb/gdbtypes.h
@@ -182,10 +182,10 @@ enum type_instance_flag_value
 {
   TYPE_INSTANCE_FLAG_CONST = (1 << 0),
   TYPE_INSTANCE_FLAG_VOLATILE = (1 << 1),
-  TYPE_INSTANCE_FLAG_CODE_SPACE = (1 << 2),
-  TYPE_INSTANCE_FLAG_DATA_SPACE = (1 << 3),
-  TYPE_INSTANCE_FLAG_ADDRESS_CLASS_1 = (1 << 4),
-  TYPE_INSTANCE_FLAG_ADDRESS_CLASS_2 = (1 << 5)
+  /* All bits between the next two flag values are used to encode the
+     type's address class as numerical value.  */
+  TYPE_INSTANCE_FLAG_ADDRESS_CLASS_min = (1 << 2),
+  TYPE_INSTANCE_FLAG_ADDRESS_CLASS_max = (1 << 5)
 };
 
 /* Unsigned integer type.  If this is not set for a TYPE_CODE_INT, the
@@ -282,44 +282,51 @@ enum type_instance_flag_value
 
 #define TYPE_VOLATILE(t) (TYPE_INSTANCE_FLAGS (t) & TYPE_INSTANCE_FLAG_VOLATILE)
 
-/* Instruction-space delimited type.  This is for Harvard architectures
-   which have separate instruction and data address spaces (and perhaps
-   others).
+/* Address class flags.  Some environments provide for pointers whose
+   size is different from that of a normal pointer or address types
+   where the bits are interpreted differently than normal addresses.
 
    GDB usually defines a flat address space that is a superset of the
    architecture's two (or more) address spaces, but this is an extension
    of the architecture's model.
 
-   If TYPE_FLAG_INST is set, an object of the corresponding type
-   resides in instruction memory, even if its address (in the extended
-   flat address space) does not reflect this.
-
-   Similarly, if TYPE_FLAG_DATA is set, then an object of the 
-   corresponding type resides in the data memory space, even if
-   this is not indicated by its (flat address space) address.
+   Two address classes are pre-defined for use with Harvard architectures:
 
-   If neither flag is set, the default space for functions / methods
-   is instruction space, and for data objects is data memory.  */
+	TYPE_ADDRESS_CLASS_CODE represents instruction memory
+	TYPE_ADDRESS_CLASS_DATA represents data memory
 
-#define TYPE_CODE_SPACE(t) \
-  (TYPE_INSTANCE_FLAGS (t) & TYPE_INSTANCE_FLAG_CODE_SPACE)
+   Architecture-specific code can register additional address classes
+   to be used on certain architectures.  However, as GDB types are
+   architecture-independent, all address classes used with all architectures
+   configured into a GDB build need to be encoded via different numbers.
+   These can be registered via address_class_register_identifier.  */
+
+#define TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL \
+	((TYPE_INSTANCE_FLAG_ADDRESS_CLASS_max * 2 - 1) \
+	 & ~(TYPE_INSTANCE_FLAG_ADDRESS_CLASS_min - 1))
+
+#define TYPE_ADDRESS_CLASS(t) ((TYPE_INSTANCE_FLAGS (t) \
+				& TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL) \
+			       / TYPE_INSTANCE_FLAG_ADDRESS_CLASS_min)
+
+#define TYPE_INSTANCE_FLAG_ADDRESS_CLASS(t) \
+	(((t) * TYPE_INSTANCE_FLAG_ADDRESS_CLASS_min) \
+	 & (TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL))
+
+/* Pre-defined address classes.  These must match the initializer
+   of "address_class_identifier" in gdbtypes.c.  */
+#define TYPE_ADDRESS_CLASS_GENERIC	0
+#define TYPE_ADDRESS_CLASS_CODE		1
+#define TYPE_ADDRESS_CLASS_DATA		2
+#define TYPE_ADDRESS_CLASS_MAX \
+	(TYPE_INSTANCE_FLAG_ADDRESS_CLASS_max * 2 \
+	 / TYPE_INSTANCE_FLAG_ADDRESS_CLASS_min)
 
+#define TYPE_CODE_SPACE(t) \
+	(TYPE_ADDRESS_CLASS (t) == TYPE_ADDRESS_CLASS_CODE)
 #define TYPE_DATA_SPACE(t) \
-  (TYPE_INSTANCE_FLAGS (t) & TYPE_INSTANCE_FLAG_DATA_SPACE)
+	(TYPE_ADDRESS_CLASS (t) == TYPE_ADDRESS_CLASS_DATA)
 
-/* Address class flags.  Some environments provide for pointers whose
-   size is different from that of a normal pointer or address types
-   where the bits are interpreted differently than normal addresses.  The
-   TYPE_FLAG_ADDRESS_CLASS_n flags may be used in target specific
-   ways to represent these different types of address classes.  */
-#define TYPE_ADDRESS_CLASS_1(t) (TYPE_INSTANCE_FLAGS(t) \
-                                 & TYPE_INSTANCE_FLAG_ADDRESS_CLASS_1)
-#define TYPE_ADDRESS_CLASS_2(t) (TYPE_INSTANCE_FLAGS(t) \
-				 & TYPE_INSTANCE_FLAG_ADDRESS_CLASS_2)
-#define TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL \
-  (TYPE_INSTANCE_FLAG_ADDRESS_CLASS_1 | TYPE_INSTANCE_FLAG_ADDRESS_CLASS_2)
-#define TYPE_ADDRESS_CLASS_ALL(t) (TYPE_INSTANCE_FLAGS(t) \
-				   & TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL)
 
 /* Determine which field of the union main_type.fields[x].loc is used.  */
 
@@ -545,9 +552,9 @@ struct type
 
   /* Variant chain.  This points to a type that differs from this one only
      in qualifiers and length.  Currently, the possible qualifiers are
-     const, volatile, code-space, data-space, and address class.  The
-     length may differ only when one of the address class flags are set.
-     The variants are linked in a circular ring and share MAIN_TYPE.  */
+     const, volatile, and address class.  The lengths may differ only for
+     different address classes.  The variants are linked in a circular
+     ring and share MAIN_TYPE.  */
   struct type *chain;
 
   /* Flags specific to this instance of the type, indicating where
@@ -1138,12 +1145,14 @@ extern struct type *make_cv_type (int, i
 
 extern void replace_type (struct type *, struct type *);
 
-extern int address_space_name_to_int (char *);
+extern int address_class_register_identifier (const char *);
+
+extern int address_class_name_to_int (char *);
 
-extern const char *address_space_int_to_name (int);
+extern const char *address_class_int_to_name (int);
 
-extern struct type *make_type_with_address_space (struct type *type, 
-						  int space_identifier);
+extern struct type *make_type_with_address_class (struct type *type,
+						  int class_nr);
 
 extern struct type *lookup_memberptr_type (struct type *, struct type *);
 
Index: gdb-head/gdb/s390-tdep.c
===================================================================
--- gdb-head.orig/gdb/s390-tdep.c
+++ gdb-head/gdb/s390-tdep.c
@@ -2274,35 +2274,15 @@ s390_addr_bits_remove (struct gdbarch *g
   return addr & 0x7fffffff;
 }
 
+static int s390_address_class_mode32;
+
 static int
-s390_address_class_type_flags (int byte_size, int dwarf2_addr_class)
+s390_type_address_class (int byte_size, int dwarf2_addr_class)
 {
   if (byte_size == 4)
-    return TYPE_INSTANCE_FLAG_ADDRESS_CLASS_1;
-  else
-    return 0;
-}
+    return s390_address_class_mode32;
 
-static const char *
-s390_address_class_type_flags_to_name (struct gdbarch *gdbarch, int type_flags)
-{
-  if (type_flags & TYPE_INSTANCE_FLAG_ADDRESS_CLASS_1)
-    return "mode32";
-  else
-    return NULL;
-}
-
-static int
-s390_address_class_name_to_type_flags (struct gdbarch *gdbarch, const char *name,
-				       int *type_flags_ptr)
-{
-  if (strcmp (name, "mode32") == 0)
-    {
-      *type_flags_ptr = TYPE_INSTANCE_FLAG_ADDRESS_CLASS_1;
-      return 1;
-    }
-  else
-    return 0;
+  return TYPE_ADDRESS_CLASS_GENERIC;
 }
 
 /* Set up gdbarch struct.  */
@@ -2408,12 +2388,7 @@ s390_gdbarch_init (struct gdbarch_info i
       set_gdbarch_pseudo_register_write (gdbarch, s390x_pseudo_register_write);
       set_solib_svr4_fetch_link_map_offsets
 	(gdbarch, svr4_lp64_fetch_link_map_offsets);
-      set_gdbarch_address_class_type_flags (gdbarch,
-                                            s390_address_class_type_flags);
-      set_gdbarch_address_class_type_flags_to_name (gdbarch,
-                                                    s390_address_class_type_flags_to_name);
-      set_gdbarch_address_class_name_to_type_flags (gdbarch,
-                                                    s390_address_class_name_to_type_flags);
+      set_gdbarch_type_address_class (gdbarch, s390_type_address_class);
       break;
     }
 
@@ -2435,7 +2410,9 @@ extern initialize_file_ftype _initialize
 void
 _initialize_s390_tdep (void)
 {
-
   /* Hook us into the gdbarch mechanism.  */
   register_gdbarch_init (bfd_arch_s390, s390_gdbarch_init);
+
+  /* Register the 32-bit address class.  */
+  s390_address_class_mode32 = address_class_register_identifier ("mode32");
 }
Index: gdb-head/gdb/dwarf2read.c
===================================================================
--- gdb-head.orig/gdb/dwarf2read.c
+++ gdb-head/gdb/dwarf2read.c
@@ -4964,15 +4964,11 @@ read_tag_pointer_type (struct die_info *
      length accordingly.  */
   if (TYPE_LENGTH (type) != byte_size || addr_class != DW_ADDR_none)
     {
-      if (gdbarch_address_class_type_flags_p (gdbarch))
+      if (gdbarch_type_address_class_p (gdbarch))
 	{
-	  int type_flags;
-
-	  type_flags = gdbarch_address_class_type_flags
-			 (gdbarch, byte_size, addr_class);
-	  gdb_assert ((type_flags & ~TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL)
-		      == 0);
-	  type = make_type_with_address_space (type, type_flags);
+	  int class_nr = gdbarch_type_address_class
+			  (gdbarch, byte_size, addr_class);
+	  type = make_type_with_address_class (type, class_nr);
 	}
       else if (TYPE_LENGTH (type) != byte_size)
 	{
Index: gdb-head/gdb/c-exp.y
===================================================================
--- gdb-head.orig/gdb/c-exp.y
+++ gdb-head/gdb/c-exp.y
@@ -822,8 +822,8 @@ variable:	name_not_typename
 	;
 
 space_identifier : '@' NAME
-		{ push_type_address_space (copy_name ($2.stoken));
-		  push_type (tp_space_identifier);
+		{ push_type_address_class (copy_name ($2.stoken));
+		  push_type (tp_address_class);
 		}
 	;
 
Index: gdb-head/gdb/parse.c
===================================================================
--- gdb-head.orig/gdb/parse.c
+++ gdb-head/gdb/parse.c
@@ -1225,9 +1225,9 @@ push_type_int (int n)
 }
 
 void
-push_type_address_space (char *string)
+push_type_address_class (char *string)
 {
-  push_type_int (address_space_name_to_int (string));
+  push_type_int (address_class_name_to_int (string));
 }
 
 enum type_pieces
@@ -1255,7 +1255,7 @@ follow_types (struct type *follow_type)
   int done = 0;
   int make_const = 0;
   int make_volatile = 0;
-  int make_addr_space = 0;
+  int make_addr_class = 0;
   int array_size;
   struct type *range_type;
 
@@ -1272,11 +1272,11 @@ follow_types (struct type *follow_type)
 	  follow_type = make_cv_type (TYPE_CONST (follow_type), 
 				      make_volatile, 
 				      follow_type, 0);
-	if (make_addr_space)
-	  follow_type = make_type_with_address_space (follow_type, 
-						      make_addr_space);
+	if (make_addr_class)
+	  follow_type = make_type_with_address_class (follow_type,
+						      make_addr_class);
 	make_const = make_volatile = 0;
-	make_addr_space = 0;
+	make_addr_class = 0;
 	break;
       case tp_const:
 	make_const = 1;
@@ -1284,8 +1284,8 @@ follow_types (struct type *follow_type)
       case tp_volatile:
 	make_volatile = 1;
 	break;
-      case tp_space_identifier:
-	make_addr_space = pop_type_int ();
+      case tp_address_class:
+	make_addr_class = pop_type_int ();
 	break;
       case tp_pointer:
 	follow_type = lookup_pointer_type (follow_type);
@@ -1297,11 +1297,11 @@ follow_types (struct type *follow_type)
 	  follow_type = make_cv_type (TYPE_CONST (follow_type), 
 				      make_volatile, 
 				      follow_type, 0);
-	if (make_addr_space)
-	  follow_type = make_type_with_address_space (follow_type, 
-						      make_addr_space);
+	if (make_addr_class)
+	  follow_type = make_type_with_address_class (follow_type,
+						      make_addr_class);
 	make_const = make_volatile = 0;
-	make_addr_space = 0;
+	make_addr_class = 0;
 	break;
       case tp_reference:
 	follow_type = lookup_reference_type (follow_type);
@@ -1313,11 +1313,11 @@ follow_types (struct type *follow_type)
 	  follow_type = make_cv_type (TYPE_CONST (follow_type), 
 				      make_volatile, 
 				      follow_type, 0);
-	if (make_addr_space)
-	  follow_type = make_type_with_address_space (follow_type, 
-						      make_addr_space);
+	if (make_addr_class)
+	  follow_type = make_type_with_address_class (follow_type,
+						      make_addr_class);
 	make_const = make_volatile = 0;
-	make_addr_space = 0;
+	make_addr_class = 0;
 	break;
       case tp_array:
 	array_size = pop_type_int ();
Index: gdb-head/gdb/parser-defs.h
===================================================================
--- gdb-head.orig/gdb/parser-defs.h
+++ gdb-head/gdb/parser-defs.h
@@ -117,7 +117,7 @@ enum type_pieces
     tp_function, 
     tp_const, 
     tp_volatile, 
-    tp_space_identifier
+    tp_address_class
   };
 /* The stack can contain either an enum type_pieces or an int.  */
 union type_stack_elt
@@ -172,7 +172,7 @@ extern void push_type (enum type_pieces)
 
 extern void push_type_int (int);
 
-extern void push_type_address_space (char *);
+extern void push_type_address_class (char *);
 
 extern enum type_pieces pop_type (void);
 
Index: gdb-head/gdb/doc/gdbint.texinfo
===================================================================
--- gdb-head.orig/gdb/doc/gdbint.texinfo
+++ gdb-head/gdb/doc/gdbint.texinfo
@@ -3342,67 +3342,58 @@ define addresses of several different si
 distinguishes these kinds of address classes through either the size
 info (e.g, @code{DW_AT_byte_size} in @w{DWARF 2}) or through an explicit
 address class attribute (e.g, @code{DW_AT_address_class} in @w{DWARF 2}), the
-following macros should be defined in order to disambiguate these
-types within @value{GDBN} as well as provide the added information to
-a @value{GDBN} user when printing type expressions.
-
-@deftypefun int gdbarch_address_class_type_flags (struct gdbarch *@var{gdbarch}, int @var{byte_size}, int @var{dwarf2_addr_class})
-Returns the type flags needed to construct a pointer type whose size
-is @var{byte_size} and whose address class is @var{dwarf2_addr_class}.
+following @code{gdbarch} function should be defined in order to disambiguate
+these types within @value{GDBN}.
+
+@deftypefun int gdbarch_type_address_class (struct gdbarch *@var{gdbarch}, int @var{byte_size}, int @var{dwarf2_addr_class})
+Returns the numerical address class identifier needed to construct
+a pointer type whose size is @var{byte_size} and whose address class
+is @var{dwarf2_addr_class}.
 This function is normally called from within a symbol reader.  See
 @file{dwarf2read.c}.
 @end deftypefun
 
-@deftypefun {char *} gdbarch_address_class_type_flags_to_name (struct gdbarch *@var{gdbarch}, int @var{type_flags})
-Given the type flags representing an address class qualifier, return
-its name.
-@end deftypefun
-@deftypefun int gdbarch_address_class_name_to_type_flags (struct gdbarch *@var{gdbarch}, int @var{name}, int *@var{type_flags_ptr})
-Given an address qualifier name, set the @code{int} referenced by @var{type_flags_ptr} to the type flags
-for that address class qualifier.
+Since the need for address classes is rather rare, this function
+is not defined by default.  A predicate functions is provided to
+detect when it is defined.
+
+Some address class identifiers are predefined by @value{GDBN}:
+@code{TYPE_ADDRESS_CLASS_GENERIC} identifies a default address, and
+@code{TYPE_ADDRESS_CLASS_CODE} and @code{TYPE_ADDRESS_CLASS_DATA}
+represent the code and data spaces of a Harvard architecture machine.
+Additional address classes can be registered by calling the following
+function:
+
+@deftypefun int address_class_register_identifier (char *@var{identifier})
+Register a string identifying an address class and return the associated
+numerical address class identifier.
 @end deftypefun
 
-Since the need for address classes is rather rare, none of
-the address class functions are defined by default.  Predicate
-functions are provided to detect when they are defined.
-
 Consider a hypothetical architecture in which addresses are normally
 32-bits wide, but 16-bit addresses are also supported.  Furthermore,
 suppose that the @w{DWARF 2} information for this architecture simply
 uses a @code{DW_AT_byte_size} value of 2 to indicate the use of one
 of these "short" pointers.  The following functions could be defined
-to implement the address class functions:
+to implement address class support:
 
 @smallexample
-somearch_address_class_type_flags (int byte_size,
-                                   int dwarf2_addr_class)
+static int somearch_addresss_class_short;
+
+static int
+somearch_type_address_class (int byte_size,
+                             int dwarf2_addr_class)
 @{
   if (byte_size == 2)
-    return TYPE_FLAG_ADDRESS_CLASS_1;
+    return somearch_address_class_short;
   else
-    return 0;
+    return TYPE_ADDRESS_CLASS_GENERIC;
 @}
 
-static char *
-somearch_address_class_type_flags_to_name (int type_flags)
+void
+_initialize_somearch_tdep (void)
 @{
-  if (type_flags & TYPE_FLAG_ADDRESS_CLASS_1)
-    return "short";
-  else
-    return NULL;
-@}
-
-int
-somearch_address_class_name_to_type_flags (char *name,
-                                           int *type_flags_ptr)
-@{
-  if (strcmp (name, "short") == 0)
-    @{
-      *type_flags_ptr = TYPE_FLAG_ADDRESS_CLASS_1;
-      return 1;
-    @}
-  else
-    return 0;
+  somearch_address_class_short
+    = address_class_register_identifier ("short");
 @}
 @end smallexample
 
@@ -4461,48 +4452,21 @@ arch_addr_bits_remove (CORE_ADDR addr)
 @}
 @end smallexample
 
-@item int address_class_name_to_type_flags (@var{gdbarch}, @var{name}, @var{type_flags_ptr})
-@findex address_class_name_to_type_flags
-If @var{name} is a valid address class qualifier name, set the @code{int}
-referenced by @var{type_flags_ptr} to the mask representing the qualifier
-and return 1.  If @var{name} is not a valid address class qualifier name,
-return 0.
-
-The value for @var{type_flags_ptr} should be one of
-@code{TYPE_FLAG_ADDRESS_CLASS_1}, @code{TYPE_FLAG_ADDRESS_CLASS_2}, or
-possibly some combination of these values or'd together.
+@item int gdbarch_type_address_class (@var{gdbarch}, @var{byte_size}, @var{dwarf2_addr_class})
+@findex gdbarch_type_address_class
+Given a pointer's byte size (as described by the debug information) and
+the possible @code{DW_AT_address_class} value, return the numerical
+identifier used by @value{GDBN} to represent this address class.  The value
+returned should either be one of @code{TYPE_ADDRESS_CLASS_GENERIC},
+@code{TYPE_ADDRESS_CLASS_CODE}, @code{TYPE_ADDRESS_CLASS_DATA}, or the
+return value of a prior call to @code{address_class_register_identifier}.
 @xref{Target Architecture Definition, , Address Classes}.
 
-@item int address_class_name_to_type_flags_p (@var{gdbarch})
-@findex address_class_name_to_type_flags_p
-Predicate which indicates whether @code{address_class_name_to_type_flags}
-has been defined.
-
-@item int gdbarch_address_class_type_flags (@var{gdbarch}, @var{byte_size}, @var{dwarf2_addr_class})
-@findex gdbarch_address_class_type_flags
-Given a pointers byte size (as described by the debug information) and
-the possible @code{DW_AT_address_class} value, return the type flags
-used by @value{GDBN} to represent this address class.  The value
-returned should be one of @code{TYPE_FLAG_ADDRESS_CLASS_1},
-@code{TYPE_FLAG_ADDRESS_CLASS_2}, or possibly some combination of these
-values or'd together.
-@xref{Target Architecture Definition, , Address Classes}.
-
-@item int gdbarch_address_class_type_flags_p (@var{gdbarch})
-@findex gdbarch_address_class_type_flags_p
-Predicate which indicates whether @code{gdbarch_address_class_type_flags_p} has
+@item int gdbarch_type_address_class_p (@var{gdbarch})
+@findex gdbarch_type_address_class_p
+Predicate which indicates whether @code{gdbarch_type_address_class} has
 been defined.
 
-@item const char *gdbarch_address_class_type_flags_to_name (@var{gdbarch}, @var{type_flags})
-@findex gdbarch_address_class_type_flags_to_name
-Return the name of the address class qualifier associated with the type
-flags given by @var{type_flags}.
-
-@item int gdbarch_address_class_type_flags_to_name_p (@var{gdbarch})
-@findex gdbarch_address_class_type_flags_to_name_p
-Predicate which indicates whether @code{gdbarch_address_class_type_flags_to_name} has been defined.
-@xref{Target Architecture Definition, , Address Classes}.
-
 @item void gdbarch_address_to_pointer (@var{gdbarch}, @var{type}, @var{buf}, @var{addr})
 @findex gdbarch_address_to_pointer
 Store in @var{buf} a pointer of type @var{type} representing the address

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


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