dbghelp: Correctly store and report bitfield information.

Bitfield information must be stored relative to first byte
of underlying integral type. We were storing the information
always relative to the first containing byte.

Signed-off-by: Eric Pouech <eric.pouech@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Eric Pouech 2021-08-30 09:24:23 +02:00 committed by Alexandre Julliard
parent 85557f361b
commit 3ed209e0d9
5 changed files with 17 additions and 24 deletions

View File

@ -194,7 +194,8 @@ struct symt_data
struct
{
LONG_PTR offset;
ULONG_PTR length;
ULONG_PTR bit_length;
ULONG_PTR bit_offset;
} member;
/* DataIsConstant */
VARIANT value;
@ -793,7 +794,7 @@ extern BOOL symt_add_udt_element(struct module* module,
struct symt_udt* udt_type,
const char* name,
struct symt* elt_type, unsigned offset,
unsigned size) DECLSPEC_HIDDEN;
unsigned bit_offset, unsigned bit_size) DECLSPEC_HIDDEN;
extern struct symt_enum*
symt_new_enum(struct module* module, const char* typename,
struct symt* basetype) DECLSPEC_HIDDEN;

View File

@ -1422,7 +1422,7 @@ static void dwarf2_parse_udt_member(dwarf2_parse_context_t* ctx,
}
else bit_offset.u.uvalue = 0;
symt_add_udt_element(ctx->module, parent, name.u.string, elt_type,
(loc.offset << 3) + bit_offset.u.uvalue,
loc.offset, bit_offset.u.uvalue,
bit_size.u.uvalue);
if (dwarf2_get_di_children(ctx, di)) FIXME("Unsupported children\n");

View File

@ -736,13 +736,13 @@ static void codeview_add_udt_element(struct codeview_type_parse* ctp,
case LF_BITFIELD_V1:
symt_add_udt_element(ctp->module, symt, name,
codeview_fetch_type(ctp, cv_type->bitfield_v1.type, FALSE),
(value << 3) + cv_type->bitfield_v1.bitoff,
value, cv_type->bitfield_v1.bitoff,
cv_type->bitfield_v1.nbits);
return;
case LF_BITFIELD_V2:
symt_add_udt_element(ctp->module, symt, name,
codeview_fetch_type(ctp, cv_type->bitfield_v2.type, FALSE),
(value << 3) + cv_type->bitfield_v2.bitoff,
value, cv_type->bitfield_v2.bitoff,
cv_type->bitfield_v2.nbits);
return;
}
@ -753,8 +753,7 @@ static void codeview_add_udt_element(struct codeview_type_parse* ctp,
{
DWORD64 elem_size = 0;
symt_get_info(ctp->module, subtype, TI_GET_LENGTH, &elem_size);
symt_add_udt_element(ctp->module, symt, name, subtype,
value << 3, (DWORD)elem_size << 3);
symt_add_udt_element(ctp->module, symt, name, subtype, value, 0, 0);
}
}

View File

@ -615,19 +615,11 @@ static inline int stabs_pts_read_aggregate(struct ParseTypedefData* ptd,
if (doadd && adt)
{
char tmp[256];
DWORD64 size;
strcpy(tmp, "__inherited_class_");
strcat(tmp, symt_get_name(adt));
/* FIXME: TI_GET_LENGTH will not always work, especially when adt
* has just been seen as a forward definition and not the real stuff
* yet.
* As we don't use much the size of members in structs, this may not
* be much of a problem
*/
symt_get_info(ptd->module, adt, TI_GET_LENGTH, &size);
symt_add_udt_element(ptd->module, sdt, tmp, adt, ofs, (DWORD)size * 8);
symt_add_udt_element(ptd->module, sdt, tmp, adt, ofs, 0, 0);
}
PTS_ABORTIF(ptd, *ptd->ptr++ != ';');
}
@ -701,7 +693,7 @@ static inline int stabs_pts_read_aggregate(struct ParseTypedefData* ptd,
PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &sz) == -1);
PTS_ABORTIF(ptd, *ptd->ptr++ != ';');
if (doadd) symt_add_udt_element(ptd->module, sdt, ptd->buf + idx, adt, ofs, sz);
if (doadd) symt_add_udt_element(ptd->module, sdt, ptd->buf + idx, adt, ofs, 0, 0);
break;
case ':':
{

View File

@ -261,7 +261,7 @@ BOOL symt_set_udt_size(struct module* module, struct symt_udt* udt, unsigned siz
*/
BOOL symt_add_udt_element(struct module* module, struct symt_udt* udt_type,
const char* name, struct symt* elt_type,
unsigned offset, unsigned size)
unsigned offset, unsigned bit_offset, unsigned bit_size)
{
struct symt_data* m;
struct symt** p;
@ -292,7 +292,8 @@ BOOL symt_add_udt_element(struct module* module, struct symt_udt* udt_type,
m->container = &udt_type->symt;
m->type = elt_type;
m->u.member.offset = offset;
m->u.member.length = ((offset & 7) || (size & 7)) ? size : 0;
m->u.member.bit_offset = bit_offset;
m->u.member.bit_length = bit_size;
p = vector_add(&udt_type->vchildren, &module->pool);
*p = &m->symt;
@ -580,8 +581,8 @@ BOOL symt_get_info(struct module* module, const struct symt* type,
case TI_GET_BITPOSITION:
if (type->tag == SymTagData &&
((const struct symt_data*)type)->kind == DataIsMember &&
((const struct symt_data*)type)->u.member.length != 0)
X(DWORD) = ((const struct symt_data*)type)->u.member.offset & 7;
((const struct symt_data*)type)->u.member.bit_length != 0)
X(DWORD) = ((const struct symt_data*)type)->u.member.bit_offset;
else return FALSE;
break;
@ -657,9 +658,9 @@ BOOL symt_get_info(struct module* module, const struct symt* type,
break;
case SymTagData:
if (((const struct symt_data*)type)->kind != DataIsMember ||
!((const struct symt_data*)type)->u.member.length)
!((const struct symt_data*)type)->u.member.bit_length)
return FALSE;
X(DWORD64) = ((const struct symt_data*)type)->u.member.length;
X(DWORD64) = ((const struct symt_data*)type)->u.member.bit_length;
break;
case SymTagArrayType:
if (!symt_get_info(module, ((const struct symt_array*)type)->base_type,
@ -735,7 +736,7 @@ BOOL symt_get_info(struct module* module, const struct symt* type,
X(ULONG) = ((const struct symt_data*)type)->u.var.offset;
break;
case DataIsMember:
X(ULONG) = ((const struct symt_data*)type)->u.member.offset >> 3;
X(ULONG) = ((const struct symt_data*)type)->u.member.offset;
break;
default:
FIXME("Unknown kind (%u) for get-offset\n",