--- gcc/pdbout.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++-- gcc/pdbout.h | 8 +++++ 2 files changed, 99 insertions(+), 2 deletions(-)
diff --git a/gcc/pdbout.c b/gcc/pdbout.c index 7d493513e06..d3f251f22d2 100644 --- a/gcc/pdbout.c +++ b/gcc/pdbout.c @@ -85,6 +85,7 @@ static struct pdb_type *modifier_types = NULL; static struct pdb_type *fieldlist_types = NULL; static struct pdb_type *struct_types = NULL, *last_struct_type = NULL; static struct pdb_type *enum_types = NULL; +static struct pdb_type *bitfield_types = NULL; static struct pdb_type *array_types = NULL; static struct pdb_alias *aliases = NULL; static struct pdb_source_file *source_files = NULL, *last_source_file = NULL; @@ -1312,6 +1313,22 @@ write_modifier (struct pdb_modifier *t) fprintf (asm_out_file, "\t.short\t0\n"); // padding } +/* Output lfBitfield structure. */ +static void +write_bitfield (struct pdb_bitfield *t) +{ + fprintf (asm_out_file, "\t.short\t0xa\n"); + fprintf (asm_out_file, "\t.short\t0x%x\n", LF_BITFIELD); + fprintf (asm_out_file, "\t.short\t0x%x\n", + t->underlying_type ? t->underlying_type->id : 0); + fprintf (asm_out_file, "\t.short\t0\n"); // padding + fprintf (asm_out_file, "\t.byte\t0x%x\n", t->size); + fprintf (asm_out_file, "\t.byte\t0x%x\n", t->offset); + + fprintf (asm_out_file, "\t.byte\t0xf2\n"); // alignment + fprintf (asm_out_file, "\t.byte\t0xf1\n"); // alignment +} + /* Given a pdb_type, output its definition. */ static void write_type (struct pdb_type *t) @@ -1357,6 +1374,10 @@ write_type (struct pdb_type *t) case LF_MODIFIER: write_modifier ((struct pdb_modifier *) t->data); break; + + case LF_BITFIELD: + write_bitfield ((struct pdb_bitfield *) t->data); + break; } } @@ -1548,6 +1569,57 @@ pdbout_late_global_decl (tree var) global_vars = v; } +/* Allocate a new pdb_type for a bitfield. */ +static struct pdb_type * +find_type_bitfield (struct pdb_type *underlying_type, unsigned int size, + unsigned int offset) +{ + struct pdb_type *type, *last_entry = NULL; + struct pdb_bitfield *bf; + + type = bitfield_types; + while (type) + { + bf = (struct pdb_bitfield *) type->data; + + if (bf->underlying_type == underlying_type && bf->size == size + && bf->offset == offset) + return type; + + last_entry = type; + type = type->next2; + } + + type = + (struct pdb_type *) xmalloc (offsetof (struct pdb_type, data) + + sizeof (struct pdb_bitfield)); + + type->cv_type = LF_BITFIELD; + type->tree = NULL; + type->next = type->next2 = NULL; + type->id = 0; + + bf = (struct pdb_bitfield *) type->data; + + bf->underlying_type = underlying_type; + bf->size = size; + bf->offset = offset; + + if (last_entry) + last_entry->next2 = type; + else + bitfield_types = type; + + if (last_type) + last_type->next = type; + else + types = type; + + last_type = type; + + return type; +} + /* Allocate a pdb_type for a forward declaration for a struct. The debugger * will resolve this automatically, by searching for a substantive * struct definition with the same name. */ @@ -1844,8 +1916,25 @@ find_type_struct (tree t, bool is_union) ent->fld_attr = CV_FLDATTR_PUBLIC; ent->name = xstrdup (IDENTIFIER_POINTER (DECL_NAME (f))); - ent->type = find_type (TREE_TYPE (f)); - ent->offset = bit_offset / 8; + if (DECL_BIT_FIELD_TYPE (f)) + { + struct pdb_type *underlying_type = + find_type (DECL_BIT_FIELD_TYPE (f)); + + ent->type = + find_type_bitfield (underlying_type, + TREE_INT_CST_ELT (DECL_SIZE (f), + 0), + TREE_INT_CST_ELT + (DECL_FIELD_BIT_OFFSET (f), 0)); + ent->offset = + TREE_INT_CST_ELT (DECL_FIELD_OFFSET (f), 0); + } + else + { + ent->type = find_type (TREE_TYPE (f)); + ent->offset = bit_offset / 8; + } ent++; } diff --git a/gcc/pdbout.h b/gcc/pdbout.h index 09b3914d650..e12f1cf21a0 100644 --- a/gcc/pdbout.h +++ b/gcc/pdbout.h @@ -37,6 +37,7 @@ #define S_DEFRANGE_REGISTER_REL 0x1145 #define LF_ARGLIST 0x1201 #define LF_FIELDLIST 0x1203 +#define LF_BITFIELD 0x1205 #define LF_ENUMERATE 0x1502 #define LF_ARRAY 0x1503 #define LF_CLASS 0x1504 @@ -373,6 +374,13 @@ struct pdb_modifier uint16_t modifier; }; +struct pdb_bitfield +{ + struct pdb_type *underlying_type; + unsigned int size; + unsigned int offset; +}; + enum pdb_x86_register { CV_X86_NONE = 0, -- 2.26.2