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:
Rene Gollent
2013-07-21 18:45:12 -04:00
parent f1fb804608
commit 49093da705
4 changed files with 44 additions and 9 deletions
+25 -9
View File
@@ -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:
+15
View File
@@ -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)
+3
View File
@@ -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);