Debugger: Handle constant member offsets properly.
For DWARF4, gcc now sometimes emits member locations as constant offsets from their parent rather than as location expressions. We weren't handling this case properly, rather we were always assuming that a constant offset implied we were dealing with a bit field. Fixes struct/class members not always having correct values on version 4.
This commit is contained in:
@@ -725,7 +725,7 @@ DwarfCompoundType::ResolveBaseTypeLocation(BaseType* _baseType,
|
||||
return B_BAD_VALUE;
|
||||
|
||||
return _ResolveDataMemberLocation(baseType->GetDwarfType(),
|
||||
baseType->Entry()->Location(), parentLocation, _location);
|
||||
baseType->Entry()->Location(), parentLocation, false, _location);
|
||||
}
|
||||
|
||||
|
||||
@@ -738,17 +738,23 @@ DwarfCompoundType::ResolveDataMemberLocation(DataMember* _member,
|
||||
return B_BAD_VALUE;
|
||||
DwarfTypeContext* typeContext = TypeContext();
|
||||
|
||||
bool isBitField = true;
|
||||
DIEMember* memberEntry = member->Entry();
|
||||
// TODO: handle DW_AT_data_bit_offset
|
||||
if (!memberEntry->ByteSize()->IsValid()
|
||||
&& !memberEntry->BitOffset()->IsValid()
|
||||
&& !memberEntry->BitSize()->IsValid()) {
|
||||
isBitField = false;
|
||||
}
|
||||
|
||||
ValueLocation* location;
|
||||
status_t error = _ResolveDataMemberLocation(member->GetDwarfType(),
|
||||
member->Entry()->Location(), parentLocation, location);
|
||||
member->Entry()->Location(), parentLocation, isBitField, location);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// If the member isn't a bit field, we're done.
|
||||
DIEMember* memberEntry = member->Entry();
|
||||
if (!memberEntry->ByteSize()->IsValid()
|
||||
&& !memberEntry->BitOffset()->IsValid()
|
||||
&& !memberEntry->BitSize()->IsValid()) {
|
||||
if (!isBitField) {
|
||||
_location = location;
|
||||
return B_OK;
|
||||
}
|
||||
@@ -861,7 +867,8 @@ DwarfCompoundType::AddTemplateParameter(DwarfTemplateParameter* parameter)
|
||||
status_t
|
||||
DwarfCompoundType::_ResolveDataMemberLocation(DwarfType* memberType,
|
||||
const MemberLocation* memberLocation,
|
||||
const ValueLocation& parentLocation, ValueLocation*& _location)
|
||||
const ValueLocation& parentLocation, bool isBitField,
|
||||
ValueLocation*& _location)
|
||||
{
|
||||
// create the value location object for the member
|
||||
ValueLocation* location = new(std::nothrow) ValueLocation(
|
||||
@@ -873,9 +880,18 @@ DwarfCompoundType::_ResolveDataMemberLocation(DwarfType* memberType,
|
||||
switch (memberLocation->attributeClass) {
|
||||
case ATTRIBUTE_CLASS_CONSTANT:
|
||||
{
|
||||
if (!location->SetTo(parentLocation, memberLocation->constant * 8,
|
||||
if (isBitField) {
|
||||
if (!location->SetTo(parentLocation,
|
||||
memberLocation->constant * 8,
|
||||
memberType->ByteSize() * 8)) {
|
||||
return B_NO_MEMORY;
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
} else {
|
||||
if (!location->SetToByteOffset(parentLocation,
|
||||
memberLocation->constant,
|
||||
memberType->ByteSize())) {
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@@ -328,6 +328,7 @@ private:
|
||||
DwarfType* memberType,
|
||||
const MemberLocation* memberLocation,
|
||||
const ValueLocation& parentLocation,
|
||||
bool isBitField,
|
||||
ValueLocation*& _location);
|
||||
|
||||
private:
|
||||
|
||||
@@ -74,6 +74,21 @@ ValueLocation::ValueLocation(const ValueLocation& other)
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ValueLocation::SetToByteOffset(const ValueLocation& other, uint64 byteOffset,
|
||||
uint64 byteSize)
|
||||
{
|
||||
Clear();
|
||||
|
||||
fBigEndian = other.fBigEndian;
|
||||
ValuePieceLocation piece = other.PieceAt(0);
|
||||
piece.SetToMemory(piece.address + byteOffset);
|
||||
piece.SetSize(byteSize);
|
||||
|
||||
return AddPiece(piece);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ValueLocation::SetTo(const ValueLocation& other, uint64 bitOffset,
|
||||
uint64 bitSize)
|
||||
|
||||
@@ -109,6 +109,9 @@ public:
|
||||
const ValuePieceLocation& piece);
|
||||
ValueLocation(const ValueLocation& other);
|
||||
|
||||
bool SetToByteOffset(const ValueLocation& other,
|
||||
uint64 byteffset, uint64 Size);
|
||||
|
||||
bool SetTo(const ValueLocation& other,
|
||||
uint64 bitOffset, uint64 bitSize);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user