From 49093da7059f84451bd212b31f663be5d55d1c37 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Sun, 21 Jul 2013 00:00:23 -0400 Subject: [PATCH] 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. --- src/apps/debugger/debug_info/DwarfTypes.cpp | 34 +++++++++++++++------ src/apps/debugger/debug_info/DwarfTypes.h | 1 + src/apps/debugger/types/ValueLocation.cpp | 15 +++++++++ src/apps/debugger/types/ValueLocation.h | 3 ++ 4 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/apps/debugger/debug_info/DwarfTypes.cpp b/src/apps/debugger/debug_info/DwarfTypes.cpp index b7fabfdfb8..34b26e933b 100644 --- a/src/apps/debugger/debug_info/DwarfTypes.cpp +++ b/src/apps/debugger/debug_info/DwarfTypes.cpp @@ -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; diff --git a/src/apps/debugger/debug_info/DwarfTypes.h b/src/apps/debugger/debug_info/DwarfTypes.h index f95b1a640c..1e1705504a 100644 --- a/src/apps/debugger/debug_info/DwarfTypes.h +++ b/src/apps/debugger/debug_info/DwarfTypes.h @@ -328,6 +328,7 @@ private: DwarfType* memberType, const MemberLocation* memberLocation, const ValueLocation& parentLocation, + bool isBitField, ValueLocation*& _location); private: diff --git a/src/apps/debugger/types/ValueLocation.cpp b/src/apps/debugger/types/ValueLocation.cpp index 9a83c4dfe2..c8c0713017 100644 --- a/src/apps/debugger/types/ValueLocation.cpp +++ b/src/apps/debugger/types/ValueLocation.cpp @@ -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) diff --git a/src/apps/debugger/types/ValueLocation.h b/src/apps/debugger/types/ValueLocation.h index 25cb64a54f..ede62a8208 100644 --- a/src/apps/debugger/types/ValueLocation.h +++ b/src/apps/debugger/types/ValueLocation.h @@ -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);