+2002-10-16 Kevin Buettner <kevinb@redhat.com>
+
+ * dwarf2read.c (dwarf2_invalid_pointer_size): New complaint.
+ (read_tag_pointer_type): Add address class support.
+ * gdbarch.sh (ADDRESS_CLASS_TYPE_FLAGS)
+ (ADDRESS_CLASS_TYPE_FLAGS_TO_NAME, ADDRESS_CLASS_NAME_TO_TYPE_FLAGS):
+ New methods.
+ * gdbarch.h, gdbarch.c: Regenerate.
+ * gdbtypes.c (address_space_name_to_int, address_space_int_to_name)
+ (make_type_with_address_space, recursive_type_dump): Add address
+ class support.
+ * gdbtypes.h (TYPE_FLAG_ADDRESS_CLASS_1, TYPE_FLAG_ADDRESS_CLASS_2)
+ (TYPE_FLAG_ADDRESS_CLASS_ALL, TYPE_ADDRESS_CLASS_1)
+ (TYPE_ADDRESS_CLASS_2, TYPE_ADDRESS_CLASS_ALL): New defines
+
2002-10-16 Klee Dienes <kdienes@apple.com>
* stabsread.c (read_tilde_fields): Use name[sizeof(vptr_name)-2]
{
"invalid attribute class or form for '%s' in '%s'", 0, 0
};
+static struct complaint dwarf2_invalid_pointer_size =
+{
+ "invalid pointer size %d", 0, 0
+};
/* local function prototypes */
const struct comp_unit_head *cu_header)
{
struct type *type;
- struct attribute *attr;
+ struct attribute *attr_byte_size;
+ struct attribute *attr_address_class;
+ int byte_size, addr_class;
if (die->type)
{
}
type = lookup_pointer_type (die_type (die, objfile, cu_header));
- attr = dwarf_attr (die, DW_AT_byte_size);
- if (attr)
- {
- TYPE_LENGTH (type) = DW_UNSND (attr);
- }
+
+ attr_byte_size = dwarf_attr (die, DW_AT_byte_size);
+ if (attr_byte_size)
+ byte_size = DW_UNSND (attr_byte_size);
+ else
+ byte_size = cu_header->addr_size;
+
+ attr_address_class = dwarf_attr (die, DW_AT_address_class);
+ if (attr_address_class)
+ addr_class = DW_UNSND (attr_address_class);
else
+ addr_class = DW_ADDR_none;
+
+ /* If the pointer size or address class is different than the
+ default, create a type variant marked as such and set the
+ length accordingly. */
+ if (TYPE_LENGTH (type) != byte_size || addr_class != DW_ADDR_none)
{
- TYPE_LENGTH (type) = cu_header->addr_size;
+ if (ADDRESS_CLASS_TYPE_FLAGS_P ())
+ {
+ int type_flags;
+
+ type_flags = ADDRESS_CLASS_TYPE_FLAGS (byte_size, addr_class);
+ gdb_assert ((type_flags & ~TYPE_FLAG_ADDRESS_CLASS_ALL) == 0);
+ type = make_type_with_address_space (type, type_flags);
+ }
+ else if (TYPE_LENGTH (type) != byte_size)
+ {
+ complain (&dwarf2_invalid_pointer_size, byte_size);
+ }
+ else {
+ /* Should we also complain about unhandled address classes? */
+ }
}
+
+ TYPE_LENGTH (type) = byte_size;
die->type = type;
}
const char * name_of_malloc;
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;
};
"malloc",
0,
0,
+ 0,
+ 0,
+ 0,
/* startup_gdbarch() */
};
/* Skip verify of name_of_malloc, 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 */
buf = ui_file_xstrdup (log, &dummy);
make_cleanup (xfree, buf);
if (strlen (buf) > 0)
fprintf_unfiltered (file,
"gdbarch_dump: pseudo_register_write = 0x%08lx\n",
(long) current_gdbarch->pseudo_register_write);
+#ifdef ADDRESS_CLASS_NAME_TO_TYPE_FLAGS
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "ADDRESS_CLASS_NAME_TO_TYPE_FLAGS(name, type_flags_ptr)",
+ XSTRING (ADDRESS_CLASS_NAME_TO_TYPE_FLAGS (name, type_flags_ptr)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: ADDRESS_CLASS_NAME_TO_TYPE_FLAGS = 0x%08lx\n",
+ (long) current_gdbarch->address_class_name_to_type_flags
+ /*ADDRESS_CLASS_NAME_TO_TYPE_FLAGS ()*/);
+#endif
+#ifdef ADDRESS_CLASS_TYPE_FLAGS
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "ADDRESS_CLASS_TYPE_FLAGS(byte_size, dwarf2_addr_class)",
+ XSTRING (ADDRESS_CLASS_TYPE_FLAGS (byte_size, dwarf2_addr_class)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: ADDRESS_CLASS_TYPE_FLAGS = 0x%08lx\n",
+ (long) current_gdbarch->address_class_type_flags
+ /*ADDRESS_CLASS_TYPE_FLAGS ()*/);
+#endif
+#ifdef ADDRESS_CLASS_TYPE_FLAGS_TO_NAME
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "ADDRESS_CLASS_TYPE_FLAGS_TO_NAME(type_flags)",
+ XSTRING (ADDRESS_CLASS_TYPE_FLAGS_TO_NAME (type_flags)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: ADDRESS_CLASS_TYPE_FLAGS_TO_NAME = 0x%08lx\n",
+ (long) current_gdbarch->address_class_type_flags_to_name
+ /*ADDRESS_CLASS_TYPE_FLAGS_TO_NAME ()*/);
+#endif
#ifdef ADDRESS_TO_POINTER
#if GDB_MULTI_ARCH
/* Macro might contain `[{}]' when not multi-arch */
gdbarch->have_nonsteppable_watchpoint = have_nonsteppable_watchpoint;
}
+int
+gdbarch_address_class_type_flags_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ return gdbarch->address_class_type_flags != 0;
+}
+
+int
+gdbarch_address_class_type_flags (struct gdbarch *gdbarch, int byte_size, int dwarf2_addr_class)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->address_class_type_flags == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_address_class_type_flags invalid");
+ 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 != 0;
+}
+
+char *
+gdbarch_address_class_type_flags_to_name (struct gdbarch *gdbarch, int type_flags)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->address_class_type_flags_to_name == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_address_class_type_flags_to_name invalid");
+ 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 (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)
+{
+ gdb_assert (gdbarch != NULL);
+ return gdbarch->address_class_name_to_type_flags != 0;
+}
+
+int
+gdbarch_address_class_name_to_type_flags (struct gdbarch *gdbarch, char *name, int *type_flags_ptr)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->address_class_name_to_type_flags == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_address_class_name_to_type_flags invalid");
+ 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 (name, type_flags_ptr);
+}
+
+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)
+{
+ gdbarch->address_class_name_to_type_flags = address_class_name_to_type_flags;
+}
+
/* Keep a registry of per-architecture data-pointers required by GDB
modules. */
#endif
#endif
+#if defined (ADDRESS_CLASS_TYPE_FLAGS)
+/* Legacy for systems yet to multi-arch ADDRESS_CLASS_TYPE_FLAGS */
+#if !defined (ADDRESS_CLASS_TYPE_FLAGS_P)
+#define ADDRESS_CLASS_TYPE_FLAGS_P() (1)
+#endif
+#endif
+
+/* Default predicate for non- multi-arch targets. */
+#if (!GDB_MULTI_ARCH) && !defined (ADDRESS_CLASS_TYPE_FLAGS_P)
+#define ADDRESS_CLASS_TYPE_FLAGS_P() (0)
+#endif
+
+extern int gdbarch_address_class_type_flags_p (struct gdbarch *gdbarch);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (ADDRESS_CLASS_TYPE_FLAGS_P)
+#error "Non multi-arch definition of ADDRESS_CLASS_TYPE_FLAGS"
+#endif
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (ADDRESS_CLASS_TYPE_FLAGS_P)
+#define ADDRESS_CLASS_TYPE_FLAGS_P() (gdbarch_address_class_type_flags_p (current_gdbarch))
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (ADDRESS_CLASS_TYPE_FLAGS)
+#define ADDRESS_CLASS_TYPE_FLAGS(byte_size, dwarf2_addr_class) (internal_error (__FILE__, __LINE__, "ADDRESS_CLASS_TYPE_FLAGS"), 0)
+#endif
+
+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);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (ADDRESS_CLASS_TYPE_FLAGS)
+#error "Non multi-arch definition of ADDRESS_CLASS_TYPE_FLAGS"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (ADDRESS_CLASS_TYPE_FLAGS)
+#define ADDRESS_CLASS_TYPE_FLAGS(byte_size, dwarf2_addr_class) (gdbarch_address_class_type_flags (current_gdbarch, byte_size, dwarf2_addr_class))
+#endif
+#endif
+
+#if defined (ADDRESS_CLASS_TYPE_FLAGS_TO_NAME)
+/* Legacy for systems yet to multi-arch ADDRESS_CLASS_TYPE_FLAGS_TO_NAME */
+#if !defined (ADDRESS_CLASS_TYPE_FLAGS_TO_NAME_P)
+#define ADDRESS_CLASS_TYPE_FLAGS_TO_NAME_P() (1)
+#endif
+#endif
+
+/* Default predicate for non- multi-arch targets. */
+#if (!GDB_MULTI_ARCH) && !defined (ADDRESS_CLASS_TYPE_FLAGS_TO_NAME_P)
+#define ADDRESS_CLASS_TYPE_FLAGS_TO_NAME_P() (0)
+#endif
+
+extern int gdbarch_address_class_type_flags_to_name_p (struct gdbarch *gdbarch);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (ADDRESS_CLASS_TYPE_FLAGS_TO_NAME_P)
+#error "Non multi-arch definition of ADDRESS_CLASS_TYPE_FLAGS_TO_NAME"
+#endif
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (ADDRESS_CLASS_TYPE_FLAGS_TO_NAME_P)
+#define ADDRESS_CLASS_TYPE_FLAGS_TO_NAME_P() (gdbarch_address_class_type_flags_to_name_p (current_gdbarch))
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (ADDRESS_CLASS_TYPE_FLAGS_TO_NAME)
+#define ADDRESS_CLASS_TYPE_FLAGS_TO_NAME(type_flags) (internal_error (__FILE__, __LINE__, "ADDRESS_CLASS_TYPE_FLAGS_TO_NAME"), 0)
+#endif
+
+typedef char * (gdbarch_address_class_type_flags_to_name_ftype) (int type_flags);
+extern 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);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (ADDRESS_CLASS_TYPE_FLAGS_TO_NAME)
+#error "Non multi-arch definition of ADDRESS_CLASS_TYPE_FLAGS_TO_NAME"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (ADDRESS_CLASS_TYPE_FLAGS_TO_NAME)
+#define ADDRESS_CLASS_TYPE_FLAGS_TO_NAME(type_flags) (gdbarch_address_class_type_flags_to_name (current_gdbarch, type_flags))
+#endif
+#endif
+
+#if defined (ADDRESS_CLASS_NAME_TO_TYPE_FLAGS)
+/* Legacy for systems yet to multi-arch ADDRESS_CLASS_NAME_TO_TYPE_FLAGS */
+#if !defined (ADDRESS_CLASS_NAME_TO_TYPE_FLAGS_P)
+#define ADDRESS_CLASS_NAME_TO_TYPE_FLAGS_P() (1)
+#endif
+#endif
+
+/* Default predicate for non- multi-arch targets. */
+#if (!GDB_MULTI_ARCH) && !defined (ADDRESS_CLASS_NAME_TO_TYPE_FLAGS_P)
+#define ADDRESS_CLASS_NAME_TO_TYPE_FLAGS_P() (0)
+#endif
+
+extern int gdbarch_address_class_name_to_type_flags_p (struct gdbarch *gdbarch);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (ADDRESS_CLASS_NAME_TO_TYPE_FLAGS_P)
+#error "Non multi-arch definition of ADDRESS_CLASS_NAME_TO_TYPE_FLAGS"
+#endif
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (ADDRESS_CLASS_NAME_TO_TYPE_FLAGS_P)
+#define ADDRESS_CLASS_NAME_TO_TYPE_FLAGS_P() (gdbarch_address_class_name_to_type_flags_p (current_gdbarch))
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (ADDRESS_CLASS_NAME_TO_TYPE_FLAGS)
+#define ADDRESS_CLASS_NAME_TO_TYPE_FLAGS(name, type_flags_ptr) (internal_error (__FILE__, __LINE__, "ADDRESS_CLASS_NAME_TO_TYPE_FLAGS"), 0)
+#endif
+
+typedef int (gdbarch_address_class_name_to_type_flags_ftype) (char *name, int *type_flags_ptr);
+extern int gdbarch_address_class_name_to_type_flags (struct gdbarch *gdbarch, 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);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (ADDRESS_CLASS_NAME_TO_TYPE_FLAGS)
+#error "Non multi-arch definition of ADDRESS_CLASS_NAME_TO_TYPE_FLAGS"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (ADDRESS_CLASS_NAME_TO_TYPE_FLAGS)
+#define ADDRESS_CLASS_NAME_TO_TYPE_FLAGS(name, type_flags_ptr) (gdbarch_address_class_name_to_type_flags (current_gdbarch, name, type_flags_ptr))
+#endif
+#endif
+
extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch);
v::NAME_OF_MALLOC:const char *:name_of_malloc::::"malloc":"malloc"::0
v::CANNOT_STEP_BREAKPOINT:int:cannot_step_breakpoint::::0:0::0
v::HAVE_NONSTEPPABLE_WATCHPOINT:int:have_nonsteppable_watchpoint::::0:0::0
+F:2:ADDRESS_CLASS_TYPE_FLAGS:int:address_class_type_flags:int byte_size, int dwarf2_addr_class:byte_size, dwarf2_addr_class
+F:2:ADDRESS_CLASS_TYPE_FLAGS_TO_NAME:char *:address_class_type_flags_to_name:int type_flags:type_flags
+F:2:ADDRESS_CLASS_NAME_TO_TYPE_FLAGS:int:address_class_name_to_type_flags:char *name, int *type_flags_ptr:name, type_flags_ptr
EOF
}
extern int
address_space_name_to_int (char *space_identifier)
{
+ int type_flags;
/* Check for known address space delimiters. */
if (!strcmp (space_identifier, "code"))
return TYPE_FLAG_CODE_SPACE;
else if (!strcmp (space_identifier, "data"))
return TYPE_FLAG_DATA_SPACE;
+ else if (ADDRESS_CLASS_NAME_TO_TYPE_FLAGS_P ()
+ && ADDRESS_CLASS_NAME_TO_TYPE_FLAGS (space_identifier, &type_flags))
+ return type_flags;
else
error ("Unknown address space specifier: \"%s\"", space_identifier);
}
return "code";
else if (space_flag & TYPE_FLAG_DATA_SPACE)
return "data";
+ else if ((space_flag & TYPE_FLAG_ADDRESS_CLASS_ALL)
+ && ADDRESS_CLASS_TYPE_FLAGS_TO_NAME_P ())
+ return ADDRESS_CLASS_TYPE_FLAGS_TO_NAME (space_flag);
else
return NULL;
}
is identical to the one supplied except that it has an address
space attribute attached to it (such as "code" or "data").
- This is for Harvard architectures. */
+ The space attributes "code" and "data" are for Harvard architectures.
+ The address space 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)
{
struct type *ntype;
int new_flags = ((TYPE_INSTANCE_FLAGS (type)
- & ~(TYPE_FLAG_CODE_SPACE | TYPE_FLAG_DATA_SPACE))
+ & ~(TYPE_FLAG_CODE_SPACE | TYPE_FLAG_DATA_SPACE
+ | TYPE_FLAG_ADDRESS_CLASS_ALL))
| space_flag);
return make_qualified_type (type, new_flags, NULL);
{
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))
+ {
+ puts_filtered (" TYPE_FLAG_ADDRESS_CLASS_2");
+ }
puts_filtered ("\n");
printfi_filtered (spaces, "flags 0x%x", TYPE_FLAGS (type));
if (TYPE_UNSIGNED (type))
#define TYPE_FLAG_VECTOR (1 << 12)
#define TYPE_VECTOR(t) (TYPE_FLAGS (t) & TYPE_FLAG_VECTOR)
+/* 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_FLAG_ADDRESS_CLASS_1 (1 << 13)
+#define TYPE_ADDRESS_CLASS_1(t) (TYPE_INSTANCE_FLAGS(t) \
+ & TYPE_FLAG_ADDRESS_CLASS_1)
+#define TYPE_FLAG_ADDRESS_CLASS_2 (1 << 14)
+#define TYPE_ADDRESS_CLASS_2(t) (TYPE_INSTANCE_FLAGS(t) \
+ & TYPE_FLAG_ADDRESS_CLASS_2)
+#define TYPE_FLAG_ADDRESS_CLASS_ALL (TYPE_FLAG_ADDRESS_CLASS_1 \
+ | TYPE_FLAG_ADDRESS_CLASS_2)
+#define TYPE_ADDRESS_CLASS_ALL(t) (TYPE_INSTANCE_FLAGS(t) \
+ & TYPE_FLAG_ADDRESS_CLASS_ALL)
+
struct main_type
{
/* Code for kind of type */