Add initial type alignment support
This adds some basic type alignment support to gdb. It changes struct type to store the alignment, and updates dwarf2read.c to handle DW_AT_alignment. It also adds a new gdbarch method and updates i386-tdep.c. None of this new functionality is used anywhere yet, so tests will wait until the next patch. 2018-04-30 Tom Tromey <tom@tromey.com> * i386-tdep.c (i386_type_align): New function. (i386_gdbarch_init): Update. * gdbarch.sh (type_align): New method. * gdbarch.c, gdbarch.h: Rebuild. * arch-utils.h (default_type_align): Declare. * arch-utils.c (default_type_align): New function. * gdbtypes.h (TYPE_ALIGN_BITS): New define. (struct type) <align_log2>: New field. <instance_flags>: Now a bitfield. (TYPE_RAW_ALIGN): New macro. (type_align, type_raw_align, set_type_align): Declare. * gdbtypes.c (type_align, type_raw_align, set_type_align): New functions. * dwarf2read.c (quirk_rust_enum): Set type alignment. (get_alignment, maybe_set_alignment): New functions. (read_structure_type, read_enumeration_type, read_array_type) (read_set_type, read_tag_pointer_type, read_tag_reference_type) (read_subrange_type, read_base_type): Set type alignment.
This commit is contained in:
parent
fe944acf8f
commit
2b4424c35b
@ -1,3 +1,24 @@
|
||||
2018-04-30 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* i386-tdep.c (i386_type_align): New function.
|
||||
(i386_gdbarch_init): Update.
|
||||
* gdbarch.sh (type_align): New method.
|
||||
* gdbarch.c, gdbarch.h: Rebuild.
|
||||
* arch-utils.h (default_type_align): Declare.
|
||||
* arch-utils.c (default_type_align): New function.
|
||||
* gdbtypes.h (TYPE_ALIGN_BITS): New define.
|
||||
(struct type) <align_log2>: New field.
|
||||
<instance_flags>: Now a bitfield.
|
||||
(TYPE_RAW_ALIGN): New macro.
|
||||
(type_align, type_raw_align, set_type_align): Declare.
|
||||
* gdbtypes.c (type_align, type_raw_align, set_type_align): New
|
||||
functions.
|
||||
* dwarf2read.c (quirk_rust_enum): Set type alignment.
|
||||
(get_alignment, maybe_set_alignment): New functions.
|
||||
(read_structure_type, read_enumeration_type, read_array_type)
|
||||
(read_set_type, read_tag_pointer_type, read_tag_reference_type)
|
||||
(read_subrange_type, read_base_type): Set type alignment.
|
||||
|
||||
2018-04-30 Simon Marchi <simon.marchi@ericsson.com>
|
||||
|
||||
* dwarf2read.c (read_index_from_section): Use bool.
|
||||
|
@ -987,6 +987,14 @@ default_in_indirect_branch_thunk (gdbarch *gdbarch, CORE_ADDR pc)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* See arch-utils.h. */
|
||||
|
||||
ULONGEST
|
||||
default_type_align (struct gdbarch *gdbarch, struct type *type)
|
||||
{
|
||||
return TYPE_LENGTH (check_typedef (type));
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_gdbarch_utils (void)
|
||||
{
|
||||
|
@ -267,4 +267,8 @@ extern CORE_ADDR gdbarch_skip_prologue_noexcept (gdbarch *gdbarch,
|
||||
extern bool default_in_indirect_branch_thunk (gdbarch *gdbarch,
|
||||
CORE_ADDR pc);
|
||||
|
||||
/* Default implementation of gdbarch type_align method. */
|
||||
extern ULONGEST default_type_align (struct gdbarch *gdbarch,
|
||||
struct type *type);
|
||||
|
||||
#endif
|
||||
|
117
gdb/dwarf2read.c
117
gdb/dwarf2read.c
@ -9907,6 +9907,7 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
|
||||
TYPE_FIELDS (union_type)
|
||||
= (struct field *) TYPE_ZALLOC (type, 3 * sizeof (struct field));
|
||||
TYPE_LENGTH (union_type) = TYPE_LENGTH (type);
|
||||
set_type_align (union_type, TYPE_RAW_ALIGN (type));
|
||||
|
||||
/* Put the discriminant must at index 0. */
|
||||
TYPE_FIELD_TYPE (union_type, 0) = field_type;
|
||||
@ -9962,6 +9963,7 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
|
||||
TYPE_CODE (union_type) = TYPE_CODE_UNION;
|
||||
TYPE_NFIELDS (union_type) = TYPE_NFIELDS (type);
|
||||
TYPE_LENGTH (union_type) = TYPE_LENGTH (type);
|
||||
set_type_align (union_type, TYPE_RAW_ALIGN (type));
|
||||
TYPE_FIELDS (union_type) = TYPE_FIELDS (type);
|
||||
|
||||
struct type *field_type = TYPE_FIELD_TYPE (union_type, 0);
|
||||
@ -10027,6 +10029,7 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
|
||||
TYPE_CODE (union_type) = TYPE_CODE_UNION;
|
||||
TYPE_NFIELDS (union_type) = 1 + TYPE_NFIELDS (type);
|
||||
TYPE_LENGTH (union_type) = TYPE_LENGTH (type);
|
||||
set_type_align (union_type, TYPE_RAW_ALIGN (type));
|
||||
TYPE_FIELDS (union_type)
|
||||
= (struct field *) TYPE_ZALLOC (union_type,
|
||||
(TYPE_NFIELDS (union_type)
|
||||
@ -15578,6 +15581,82 @@ quirk_gcc_member_function_pointer (struct type *type, struct objfile *objfile)
|
||||
smash_to_methodptr_type (type, new_type);
|
||||
}
|
||||
|
||||
/* If the DIE has a DW_AT_alignment attribute, return its value, doing
|
||||
appropriate error checking and issuing complaints if there is a
|
||||
problem. */
|
||||
|
||||
static ULONGEST
|
||||
get_alignment (struct dwarf2_cu *cu, struct die_info *die)
|
||||
{
|
||||
struct attribute *attr = dwarf2_attr (die, DW_AT_alignment, cu);
|
||||
|
||||
if (attr == nullptr)
|
||||
return 0;
|
||||
|
||||
if (!attr_form_is_constant (attr))
|
||||
{
|
||||
complaint (&symfile_complaints,
|
||||
_("DW_AT_alignment must have constant form"
|
||||
" - DIE at %s [in module %s]"),
|
||||
sect_offset_str (die->sect_off),
|
||||
objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
|
||||
return 0;
|
||||
}
|
||||
|
||||
ULONGEST align;
|
||||
if (attr->form == DW_FORM_sdata)
|
||||
{
|
||||
LONGEST val = DW_SND (attr);
|
||||
if (val < 0)
|
||||
{
|
||||
complaint (&symfile_complaints,
|
||||
_("DW_AT_alignment value must not be negative"
|
||||
" - DIE at %s [in module %s]"),
|
||||
sect_offset_str (die->sect_off),
|
||||
objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
|
||||
return 0;
|
||||
}
|
||||
align = val;
|
||||
}
|
||||
else
|
||||
align = DW_UNSND (attr);
|
||||
|
||||
if (align == 0)
|
||||
{
|
||||
complaint (&symfile_complaints,
|
||||
_("DW_AT_alignment value must not be zero"
|
||||
" - DIE at %s [in module %s]"),
|
||||
sect_offset_str (die->sect_off),
|
||||
objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
|
||||
return 0;
|
||||
}
|
||||
if ((align & (align - 1)) != 0)
|
||||
{
|
||||
complaint (&symfile_complaints,
|
||||
_("DW_AT_alignment value must be a power of 2"
|
||||
" - DIE at %s [in module %s]"),
|
||||
sect_offset_str (die->sect_off),
|
||||
objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return align;
|
||||
}
|
||||
|
||||
/* If the DIE has a DW_AT_alignment attribute, use its value to set
|
||||
the alignment for TYPE. */
|
||||
|
||||
static void
|
||||
maybe_set_alignment (struct dwarf2_cu *cu, struct die_info *die,
|
||||
struct type *type)
|
||||
{
|
||||
if (!set_type_align (type, get_alignment (cu, die)))
|
||||
complaint (&symfile_complaints,
|
||||
_("DW_AT_alignment value too large"
|
||||
" - DIE at %s [in module %s]"),
|
||||
sect_offset_str (die->sect_off),
|
||||
objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
|
||||
}
|
||||
|
||||
/* Called when we find the DIE that starts a structure or union scope
|
||||
(definition) to create a type for the structure or union. Fill in
|
||||
@ -15688,6 +15767,8 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
|
||||
TYPE_LENGTH (type) = 0;
|
||||
}
|
||||
|
||||
maybe_set_alignment (cu, die, type);
|
||||
|
||||
if (producer_is_icc_lt_14 (cu) && (TYPE_LENGTH (type) == 0))
|
||||
{
|
||||
/* ICC<14 does not output the required DW_AT_declaration on
|
||||
@ -16132,6 +16213,8 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
|
||||
TYPE_LENGTH (type) = 0;
|
||||
}
|
||||
|
||||
maybe_set_alignment (cu, die, type);
|
||||
|
||||
/* The enumeration DIE can be incomplete. In Ada, any type can be
|
||||
declared as private in the package spec, and then defined only
|
||||
inside the package body. Such types are known as Taft Amendment
|
||||
@ -16157,6 +16240,9 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
|
||||
TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TYPE_TARGET_TYPE (type));
|
||||
if (TYPE_LENGTH (type) == 0)
|
||||
TYPE_LENGTH (type) = TYPE_LENGTH (TYPE_TARGET_TYPE (type));
|
||||
if (TYPE_RAW_ALIGN (type) == 0
|
||||
&& TYPE_RAW_ALIGN (TYPE_TARGET_TYPE (type)) != 0)
|
||||
set_type_align (type, TYPE_RAW_ALIGN (TYPE_TARGET_TYPE (type)));
|
||||
}
|
||||
|
||||
TYPE_DECLARED_CLASS (type) = dwarf2_flag_true_p (die, DW_AT_enum_class, cu);
|
||||
@ -16381,6 +16467,8 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
|
||||
if (name)
|
||||
TYPE_NAME (type) = name;
|
||||
|
||||
maybe_set_alignment (cu, die, type);
|
||||
|
||||
/* Install the type in the die. */
|
||||
set_die_type (die, type, cu);
|
||||
|
||||
@ -16445,6 +16533,8 @@ read_set_type (struct die_info *die, struct dwarf2_cu *cu)
|
||||
if (attr)
|
||||
TYPE_LENGTH (set_type) = DW_UNSND (attr);
|
||||
|
||||
maybe_set_alignment (cu, die, set_type);
|
||||
|
||||
return set_die_type (die, set_type, cu);
|
||||
}
|
||||
|
||||
@ -16816,10 +16906,15 @@ read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
|
||||
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)
|
||||
ULONGEST alignment = get_alignment (cu, die);
|
||||
|
||||
/* If the pointer size, alignment, 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
|
||||
|| (alignment != 0 && TYPE_RAW_ALIGN (type) != 0
|
||||
&& alignment != TYPE_RAW_ALIGN (type))
|
||||
|| addr_class != DW_ADDR_none)
|
||||
{
|
||||
if (gdbarch_address_class_type_flags_p (gdbarch))
|
||||
{
|
||||
@ -16836,6 +16931,14 @@ read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
|
||||
complaint (&symfile_complaints,
|
||||
_("invalid pointer size %d"), byte_size);
|
||||
}
|
||||
else if (TYPE_RAW_ALIGN (type) != alignment)
|
||||
{
|
||||
complaint (&symfile_complaints,
|
||||
_("Invalid DW_AT_alignment"
|
||||
" - DIE at %s [in module %s]"),
|
||||
sect_offset_str (die->sect_off),
|
||||
objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Should we also complain about unhandled address classes? */
|
||||
@ -16843,6 +16946,7 @@ read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
|
||||
}
|
||||
|
||||
TYPE_LENGTH (type) = byte_size;
|
||||
set_type_align (type, alignment);
|
||||
return set_die_type (die, type, cu);
|
||||
}
|
||||
|
||||
@ -16912,6 +17016,7 @@ read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu,
|
||||
{
|
||||
TYPE_LENGTH (type) = cu_header->addr_size;
|
||||
}
|
||||
maybe_set_alignment (cu, die, type);
|
||||
return set_die_type (die, type, cu);
|
||||
}
|
||||
|
||||
@ -17398,6 +17503,8 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
|
||||
if (name && strcmp (name, "char") == 0)
|
||||
TYPE_NOSIGN (type) = 1;
|
||||
|
||||
maybe_set_alignment (cu, die, type);
|
||||
|
||||
return set_die_type (die, type, cu);
|
||||
}
|
||||
|
||||
@ -17660,6 +17767,8 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
|
||||
if (attr)
|
||||
TYPE_LENGTH (range_type) = DW_UNSND (attr);
|
||||
|
||||
maybe_set_alignment (cu, die, range_type);
|
||||
|
||||
set_die_type (die, range_type, cu);
|
||||
|
||||
/* set_die_type should be already done. */
|
||||
|
@ -353,6 +353,7 @@ struct gdbarch
|
||||
gdbarch_addressable_memory_unit_size_ftype *addressable_memory_unit_size;
|
||||
char ** disassembler_options;
|
||||
const disasm_options_t * valid_disassembler_options;
|
||||
gdbarch_type_align_ftype *type_align;
|
||||
};
|
||||
|
||||
/* Create a new ``struct gdbarch'' based on information provided by
|
||||
@ -465,6 +466,7 @@ gdbarch_alloc (const struct gdbarch_info *info,
|
||||
gdbarch->gcc_target_options = default_gcc_target_options;
|
||||
gdbarch->gnu_triplet_regexp = default_gnu_triplet_regexp;
|
||||
gdbarch->addressable_memory_unit_size = default_addressable_memory_unit_size;
|
||||
gdbarch->type_align = default_type_align;
|
||||
/* gdbarch_alloc() */
|
||||
|
||||
return gdbarch;
|
||||
@ -716,6 +718,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
|
||||
/* Skip verify of addressable_memory_unit_size, invalid_p == 0 */
|
||||
/* Skip verify of disassembler_options, invalid_p == 0 */
|
||||
/* Skip verify of valid_disassembler_options, invalid_p == 0 */
|
||||
/* Skip verify of type_align, invalid_p == 0 */
|
||||
if (!log.empty ())
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("verify_gdbarch: the following are invalid ...%s"),
|
||||
@ -1441,6 +1444,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
|
||||
fprintf_unfiltered (file,
|
||||
"gdbarch_dump: target_desc = %s\n",
|
||||
host_address_to_string (gdbarch->target_desc));
|
||||
fprintf_unfiltered (file,
|
||||
"gdbarch_dump: type_align = <%s>\n",
|
||||
host_address_to_string (gdbarch->type_align));
|
||||
fprintf_unfiltered (file,
|
||||
"gdbarch_dump: gdbarch_unwind_pc_p() = %d\n",
|
||||
gdbarch_unwind_pc_p (gdbarch));
|
||||
@ -5100,6 +5106,23 @@ set_gdbarch_valid_disassembler_options (struct gdbarch *gdbarch,
|
||||
gdbarch->valid_disassembler_options = valid_disassembler_options;
|
||||
}
|
||||
|
||||
ULONGEST
|
||||
gdbarch_type_align (struct gdbarch *gdbarch, struct type *type)
|
||||
{
|
||||
gdb_assert (gdbarch != NULL);
|
||||
gdb_assert (gdbarch->type_align != NULL);
|
||||
if (gdbarch_debug >= 2)
|
||||
fprintf_unfiltered (gdb_stdlog, "gdbarch_type_align called\n");
|
||||
return gdbarch->type_align (gdbarch, type);
|
||||
}
|
||||
|
||||
void
|
||||
set_gdbarch_type_align (struct gdbarch *gdbarch,
|
||||
gdbarch_type_align_ftype type_align)
|
||||
{
|
||||
gdbarch->type_align = type_align;
|
||||
}
|
||||
|
||||
|
||||
/* Keep a registry of per-architecture data-pointers required by GDB
|
||||
modules. */
|
||||
|
@ -1560,6 +1560,12 @@ extern void set_gdbarch_disassembler_options (struct gdbarch *gdbarch, char ** d
|
||||
extern const disasm_options_t * gdbarch_valid_disassembler_options (struct gdbarch *gdbarch);
|
||||
extern void set_gdbarch_valid_disassembler_options (struct gdbarch *gdbarch, const disasm_options_t * valid_disassembler_options);
|
||||
|
||||
/* Type alignment. */
|
||||
|
||||
typedef ULONGEST (gdbarch_type_align_ftype) (struct gdbarch *gdbarch, struct type *type);
|
||||
extern ULONGEST gdbarch_type_align (struct gdbarch *gdbarch, struct type *type);
|
||||
extern void set_gdbarch_type_align (struct gdbarch *gdbarch, gdbarch_type_align_ftype *type_align);
|
||||
|
||||
/* Definition for an unknown syscall, used basically in error-cases. */
|
||||
#define UNKNOWN_SYSCALL (-1)
|
||||
|
||||
|
@ -1163,6 +1163,9 @@ m;int;addressable_memory_unit_size;void;;;default_addressable_memory_unit_size;;
|
||||
v;char **;disassembler_options;;;0;0;;0;pstring_ptr (gdbarch->disassembler_options)
|
||||
v;const disasm_options_t *;valid_disassembler_options;;;0;0;;0;host_address_to_string (gdbarch->valid_disassembler_options)
|
||||
|
||||
# Type alignment.
|
||||
m;ULONGEST;type_align;struct type *type;type;;default_type_align;;0
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
|
122
gdb/gdbtypes.c
122
gdb/gdbtypes.c
@ -3013,6 +3013,128 @@ init_pointer_type (struct objfile *objfile,
|
||||
return t;
|
||||
}
|
||||
|
||||
/* See gdbtypes.h. */
|
||||
|
||||
unsigned
|
||||
type_raw_align (struct type *type)
|
||||
{
|
||||
if (type->align_log2 != 0)
|
||||
return 1 << (type->align_log2 - 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* See gdbtypes.h. */
|
||||
|
||||
unsigned
|
||||
type_align (struct type *type)
|
||||
{
|
||||
unsigned raw_align = type_raw_align (type);
|
||||
if (raw_align != 0)
|
||||
return raw_align;
|
||||
|
||||
ULONGEST align = 0;
|
||||
switch (TYPE_CODE (type))
|
||||
{
|
||||
case TYPE_CODE_PTR:
|
||||
case TYPE_CODE_FUNC:
|
||||
case TYPE_CODE_FLAGS:
|
||||
case TYPE_CODE_INT:
|
||||
case TYPE_CODE_FLT:
|
||||
case TYPE_CODE_ENUM:
|
||||
case TYPE_CODE_REF:
|
||||
case TYPE_CODE_RVALUE_REF:
|
||||
case TYPE_CODE_CHAR:
|
||||
case TYPE_CODE_BOOL:
|
||||
case TYPE_CODE_DECFLOAT:
|
||||
{
|
||||
struct gdbarch *arch = get_type_arch (type);
|
||||
align = gdbarch_type_align (arch, type);
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_CODE_ARRAY:
|
||||
case TYPE_CODE_COMPLEX:
|
||||
case TYPE_CODE_TYPEDEF:
|
||||
align = type_align (TYPE_TARGET_TYPE (type));
|
||||
break;
|
||||
|
||||
case TYPE_CODE_STRUCT:
|
||||
case TYPE_CODE_UNION:
|
||||
{
|
||||
if (TYPE_NFIELDS (type) == 0)
|
||||
{
|
||||
/* An empty struct has alignment 1. */
|
||||
align = 1;
|
||||
break;
|
||||
}
|
||||
for (unsigned i = 0; i < TYPE_NFIELDS (type); ++i)
|
||||
{
|
||||
ULONGEST f_align = type_align (TYPE_FIELD_TYPE (type, i));
|
||||
if (f_align == 0)
|
||||
{
|
||||
/* Don't pretend we know something we don't. */
|
||||
align = 0;
|
||||
break;
|
||||
}
|
||||
if (f_align > align)
|
||||
align = f_align;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_CODE_SET:
|
||||
case TYPE_CODE_RANGE:
|
||||
case TYPE_CODE_STRING:
|
||||
/* Not sure what to do here, and these can't appear in C or C++
|
||||
anyway. */
|
||||
break;
|
||||
|
||||
case TYPE_CODE_METHODPTR:
|
||||
case TYPE_CODE_MEMBERPTR:
|
||||
align = TYPE_LENGTH (type);
|
||||
break;
|
||||
|
||||
case TYPE_CODE_VOID:
|
||||
align = 1;
|
||||
break;
|
||||
|
||||
case TYPE_CODE_ERROR:
|
||||
case TYPE_CODE_METHOD:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ((align & (align - 1)) != 0)
|
||||
{
|
||||
/* Not a power of 2, so pass. */
|
||||
align = 0;
|
||||
}
|
||||
|
||||
return align;
|
||||
}
|
||||
|
||||
/* See gdbtypes.h. */
|
||||
|
||||
bool
|
||||
set_type_align (struct type *type, ULONGEST align)
|
||||
{
|
||||
/* Must be a power of 2. Zero is ok. */
|
||||
gdb_assert ((align & (align - 1)) == 0);
|
||||
|
||||
unsigned result = 0;
|
||||
while (align != 0)
|
||||
{
|
||||
++result;
|
||||
align >>= 1;
|
||||
}
|
||||
|
||||
if (result >= (1 << TYPE_ALIGN_BITS))
|
||||
return false;
|
||||
|
||||
type->align_log2 = result;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Queries on types. */
|
||||
|
||||
|
@ -802,6 +802,10 @@ struct main_type
|
||||
struct dynamic_prop_list *dyn_prop_list;
|
||||
};
|
||||
|
||||
/* * Number of bits allocated for alignment. */
|
||||
|
||||
#define TYPE_ALIGN_BITS 8
|
||||
|
||||
/* * A ``struct type'' describes a particular instance of a type, with
|
||||
some particular qualification. */
|
||||
|
||||
@ -831,6 +835,14 @@ struct type
|
||||
|
||||
struct type *chain;
|
||||
|
||||
/* * The alignment for this type. Zero means that the alignment was
|
||||
not specified in the debug info. Note that this is stored in a
|
||||
funny way: as the log base 2 (plus 1) of the alignment; so a
|
||||
value of 1 means the alignment is 1, and a value of 9 means the
|
||||
alignment is 256. */
|
||||
|
||||
unsigned align_log2 : TYPE_ALIGN_BITS;
|
||||
|
||||
/* * Flags specific to this instance of the type, indicating where
|
||||
on the ring we are.
|
||||
|
||||
@ -841,7 +853,7 @@ struct type
|
||||
instance flags are completely inherited from the target type. No
|
||||
qualifiers can be cleared by the typedef. See also
|
||||
check_typedef. */
|
||||
int instance_flags;
|
||||
unsigned instance_flags : 9;
|
||||
|
||||
/* * Length of storage for a value of this type. The value is the
|
||||
expression in host bytes of what sizeof(type) would return. This
|
||||
@ -1292,6 +1304,26 @@ extern void allocate_gnat_aux_type (struct type *);
|
||||
so you only have to call check_typedef once. Since allocate_value
|
||||
calls check_typedef, TYPE_LENGTH (VALUE_TYPE (X)) is safe. */
|
||||
#define TYPE_LENGTH(thistype) (thistype)->length
|
||||
|
||||
/* * Return the alignment of the type in target addressable memory
|
||||
units, or 0 if no alignment was specified. */
|
||||
#define TYPE_RAW_ALIGN(thistype) type_raw_align (thistype)
|
||||
|
||||
/* * Return the alignment of the type in target addressable memory
|
||||
units, or 0 if no alignment was specified. */
|
||||
extern unsigned type_raw_align (struct type *);
|
||||
|
||||
/* * Return the alignment of the type in target addressable memory
|
||||
units. Return 0 if the alignment cannot be determined; but note
|
||||
that this makes an effort to compute the alignment even it it was
|
||||
not specified in the debug info. */
|
||||
extern unsigned type_align (struct type *);
|
||||
|
||||
/* * Set the alignment of the type. The alignment must be a power of
|
||||
2. Returns false if the given value does not fit in the available
|
||||
space in struct type. */
|
||||
extern bool set_type_align (struct type *, ULONGEST);
|
||||
|
||||
/* * Note that TYPE_CODE can be TYPE_CODE_TYPEDEF, so if you want the real
|
||||
type, you need to do TYPE_CODE (check_type (this_type)). */
|
||||
#define TYPE_CODE(thistype) TYPE_MAIN_TYPE(thistype)->code
|
||||
|
@ -8346,6 +8346,31 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep,
|
||||
return valid_p;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Implement the type_align gdbarch function. */
|
||||
|
||||
static ULONGEST
|
||||
i386_type_align (struct gdbarch *gdbarch, struct type *type)
|
||||
{
|
||||
type = check_typedef (type);
|
||||
|
||||
if (gdbarch_ptr_bit (gdbarch) == 32)
|
||||
{
|
||||
if ((TYPE_CODE (type) == TYPE_CODE_INT
|
||||
|| TYPE_CODE (type) == TYPE_CODE_FLT)
|
||||
&& TYPE_LENGTH (type) > 4)
|
||||
return 4;
|
||||
|
||||
/* Handle x86's funny long double. */
|
||||
if (TYPE_CODE (type) == TYPE_CODE_FLT
|
||||
&& gdbarch_long_double_bit (gdbarch) == TYPE_LENGTH (type) * 8)
|
||||
return 4;
|
||||
}
|
||||
|
||||
return TYPE_LENGTH (type);
|
||||
}
|
||||
|
||||
|
||||
/* Note: This is called for both i386 and amd64. */
|
||||
|
||||
@ -8405,6 +8430,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||
tdep->record_regmap = i386_record_regmap;
|
||||
|
||||
set_gdbarch_long_long_align_bit (gdbarch, 32);
|
||||
set_gdbarch_type_align (gdbarch, i386_type_align);
|
||||
|
||||
/* The format used for `long double' on almost all i386 targets is
|
||||
the i387 extended floating-point format. In fact, of all targets
|
||||
|
Loading…
x
Reference in New Issue
Block a user