Address class support.

This commit is contained in:
Kevin Buettner 2002-10-16 20:50:22 +00:00
parent f52d1d6405
commit 8b2dbe47f3
7 changed files with 325 additions and 9 deletions

View file

@ -1,3 +1,18 @@
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]

View file

@ -683,6 +683,10 @@ static struct complaint dwarf2_invalid_attrib_class =
{
"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 */
@ -2925,7 +2929,9 @@ read_tag_pointer_type (struct die_info *die, struct objfile *objfile,
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)
{
@ -2933,15 +2939,42 @@ read_tag_pointer_type (struct die_info *die, struct objfile *objfile,
}
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;
}

View file

@ -271,6 +271,9 @@ struct gdbarch
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;
};
@ -431,6 +434,9 @@ struct gdbarch startup_gdbarch =
"malloc",
0,
0,
0,
0,
0,
/* startup_gdbarch() */
};
@ -810,6 +816,9 @@ verify_gdbarch (struct gdbarch *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)
@ -850,6 +859,39 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
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 */
@ -5080,6 +5122,84 @@ set_gdbarch_have_nonsteppable_watchpoint (struct gdbarch *gdbarch,
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. */

View file

@ -2611,6 +2611,117 @@ extern void set_gdbarch_have_nonsteppable_watchpoint (struct gdbarch *gdbarch, i
#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);

View file

@ -664,6 +664,9 @@ f:2:COFF_MAKE_MSYMBOL_SPECIAL:void:coff_make_msymbol_special:int val, struct min
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
}

View file

@ -397,11 +397,15 @@ lookup_function_type (struct type *type)
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);
}
@ -416,6 +420,9 @@ address_space_int_to_name (int space_flag)
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;
}
@ -465,14 +472,17 @@ make_qualified_type (struct type *type, int new_flags,
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);
@ -3140,6 +3150,14 @@ recursive_dump_type (struct type *type, int spaces)
{
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))

View file

@ -253,6 +253,22 @@ enum type_code
#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 */