From 185d2cdcb9b3af20ad0e9cce53ed7e5bafe2e962 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Thu, 30 Jun 2011 22:30:48 +0000 Subject: [PATCH] * Add model class TypeLookupConstraints. * Create and pass constraints to type lookup requests to ensure that the type we get back is in fact the one we wanted, and not a different one that happened to have a similar name. Resolves ticket #5495. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42348 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/debugger/Jamfile | 1 + .../debug_info/DebuggerImageDebugInfo.cpp | 3 +- .../debug_info/DebuggerImageDebugInfo.h | 4 +- .../debug_info/DwarfImageDebugInfo.cpp | 13 ++- .../debugger/debug_info/DwarfImageDebugInfo.h | 4 +- .../debugger/debug_info/DwarfTypeFactory.cpp | 9 ++- src/apps/debugger/debug_info/DwarfTypes.cpp | 78 ++++++++++++++++++ src/apps/debugger/debug_info/DwarfTypes.h | 5 ++ .../debugger/debug_info/GlobalTypeLookup.h | 5 +- .../debugger/debug_info/ImageDebugInfo.cpp | 5 +- src/apps/debugger/debug_info/ImageDebugInfo.h | 5 +- .../debug_info/SpecificImageDebugInfo.h | 5 +- .../debugger/debug_info/TeamDebugInfo.cpp | 5 +- src/apps/debugger/debug_info/TeamDebugInfo.h | 4 +- src/apps/debugger/model/Type.h | 8 ++ .../debugger/model/TypeLookupConstraints.cpp | 79 +++++++++++++++++++ .../debugger/model/TypeLookupConstraints.h | 36 +++++++++ 17 files changed, 256 insertions(+), 13 deletions(-) create mode 100644 src/apps/debugger/model/TypeLookupConstraints.cpp create mode 100644 src/apps/debugger/model/TypeLookupConstraints.h diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index 32cd00e265..d01647e4c8 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -134,6 +134,7 @@ Application Debugger : ThreadInfo.cpp Type.cpp TypeComponentPath.cpp + TypeLookupConstraints.cpp Variable.cpp # settings diff --git a/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp b/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp index faffbb2951..a9c761c1a9 100644 --- a/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp +++ b/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp @@ -80,7 +80,8 @@ DebuggerImageDebugInfo::GetFunctions(BObjectList& functions) status_t DebuggerImageDebugInfo::GetType(GlobalTypeCache* cache, - const BString& name, Type*& _type) + const BString& name, const TypeLookupConstraints& constraints, + Type*& _type) { return B_UNSUPPORTED; } diff --git a/src/apps/debugger/debug_info/DebuggerImageDebugInfo.h b/src/apps/debugger/debug_info/DebuggerImageDebugInfo.h index 563dc9ecf3..dbf70e9c8d 100644 --- a/src/apps/debugger/debug_info/DebuggerImageDebugInfo.h +++ b/src/apps/debugger/debug_info/DebuggerImageDebugInfo.h @@ -28,7 +28,9 @@ public: virtual status_t GetFunctions( BObjectList& functions); virtual status_t GetType(GlobalTypeCache* cache, - const BString& name, Type*& _type); + const BString& name, + const TypeLookupConstraints& constraints, + Type*& _type); virtual AddressSectionType GetAddressSectionType(target_addr_t address); virtual status_t CreateFrame(Image* image, FunctionInstance* functionInstance, diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp index 44a507d0cd..3a40299cd8 100644 --- a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp +++ b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp @@ -46,6 +46,7 @@ #include "TargetAddressRangeList.h" #include "TeamMemory.h" #include "Tracing.h" +#include "TypeLookupConstraints.h" #include "UnsupportedLanguage.h" #include "Variable.h" @@ -383,7 +384,8 @@ DwarfImageDebugInfo::GetFunctions(BObjectList& functions) status_t DwarfImageDebugInfo::GetType(GlobalTypeCache* cache, - const BString& name, Type*& _type) + const BString& name, const TypeLookupConstraints& constraints, + Type*& _type) { int32 registerCount = fArchitecture->CountRegisters(); const Register* registers = fArchitecture->Registers(); @@ -412,6 +414,15 @@ DwarfImageDebugInfo::GetType(GlobalTypeCache* cache, if (typeEntry->IsDeclaration()) continue; + if (constraints.HasTypeKind() + && dwarf_tag_to_type_kind(typeEntry->Tag()) + != constraints.TypeKind()) + continue; + if (constraints.HasSubtypeKind() + && dwarf_tag_to_subtype_kind(typeEntry->Tag()) + != constraints.SubtypeKind()) + continue; + BString typeEntryName; DwarfUtils::GetFullyQualifiedDIEName(typeEntry, typeEntryName); if (typeEntryName != name) diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfo.h b/src/apps/debugger/debug_info/DwarfImageDebugInfo.h index 74c49d905b..9c179b8b6b 100644 --- a/src/apps/debugger/debug_info/DwarfImageDebugInfo.h +++ b/src/apps/debugger/debug_info/DwarfImageDebugInfo.h @@ -51,7 +51,9 @@ public: virtual status_t GetFunctions( BObjectList& functions); virtual status_t GetType(GlobalTypeCache* cache, - const BString& name, Type*& _type); + const BString& name, + const TypeLookupConstraints& constraints, + Type*& _type); virtual AddressSectionType GetAddressSectionType(target_addr_t address); diff --git a/src/apps/debugger/debug_info/DwarfTypeFactory.cpp b/src/apps/debugger/debug_info/DwarfTypeFactory.cpp index c7d5dc2a23..017a9aeb38 100644 --- a/src/apps/debugger/debug_info/DwarfTypeFactory.cpp +++ b/src/apps/debugger/debug_info/DwarfTypeFactory.cpp @@ -27,6 +27,7 @@ #include "SourceLanguageInfo.h" #include "StringUtils.h" #include "Tracing.h" +#include "TypeLookupConstraints.h" #include "ValueLocation.h" @@ -314,8 +315,14 @@ DwarfTypeFactory::CreateType(DIEType* typeEntry, DwarfType*& _type) // If the type entry indicates a declaration only, we try to look the // type up globally first. + TypeLookupConstraints constraints( + dwarf_tag_to_type_kind(typeEntry->Tag())); + int32 subtypeKind = dwarf_tag_to_subtype_kind(typeEntry->Tag()); + if (subtypeKind >= 0) + constraints.SetSubtypeKind(subtypeKind); if (typeEntry->IsDeclaration() && name.Length() > 0 - && fTypeLookup->GetType(fTypeCache, name, globalType) + && fTypeLookup->GetType(fTypeCache, name, + constraints, globalType) == B_OK) { DwarfType* globalDwarfType = dynamic_cast(globalType); diff --git a/src/apps/debugger/debug_info/DwarfTypes.cpp b/src/apps/debugger/debug_info/DwarfTypes.cpp index 0794e500e9..328c2a61a0 100644 --- a/src/apps/debugger/debug_info/DwarfTypes.cpp +++ b/src/apps/debugger/debug_info/DwarfTypes.cpp @@ -50,6 +50,84 @@ struct HasByteStridePredicate { } // unnamed namespace +type_kind +dwarf_tag_to_type_kind(int32 tag) +{ + switch (tag) { + case DW_TAG_class_type: + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_interface_type: + return TYPE_COMPOUND; + + case DW_TAG_base_type: + return TYPE_PRIMITIVE; + + case DW_TAG_pointer_type: + case DW_TAG_reference_type: + return TYPE_ADDRESS; + + case DW_TAG_const_type: + case DW_TAG_packed_type: + case DW_TAG_volatile_type: + case DW_TAG_restrict_type: + case DW_TAG_shared_type: + return TYPE_MODIFIED; + + case DW_TAG_typedef: + return TYPE_TYPEDEF; + + case DW_TAG_array_type: + return TYPE_ARRAY; + + case DW_TAG_enumeration_type: + return TYPE_ENUMERATION; + + case DW_TAG_subrange_type: + return TYPE_SUBRANGE; + + case DW_TAG_unspecified_type: + return TYPE_UNSPECIFIED; + + case DW_TAG_subroutine_type: + return TYPE_FUNCTION; + + case DW_TAG_ptr_to_member_type: + return TYPE_POINTER_TO_MEMBER; + + } + + return TYPE_UNSPECIFIED; +} + + +int32 +dwarf_tag_to_subtype_kind(int32 tag) +{ + switch (tag) { + case DW_TAG_class_type: + return COMPOUND_TYPE_CLASS; + + case DW_TAG_structure_type: + return COMPOUND_TYPE_STRUCT; + + case DW_TAG_union_type: + return COMPOUND_TYPE_UNION; + + case DW_TAG_interface_type: + return COMPOUND_TYPE_INTERFACE; + + case DW_TAG_pointer_type: + return DERIVED_TYPE_POINTER; + + case DW_TAG_reference_type: + return DERIVED_TYPE_REFERENCE; + } + + return -1; +} + + // #pragma mark - DwarfTypeContext diff --git a/src/apps/debugger/debug_info/DwarfTypes.h b/src/apps/debugger/debug_info/DwarfTypes.h index 9c5e05d104..5464c109e5 100644 --- a/src/apps/debugger/debug_info/DwarfTypes.h +++ b/src/apps/debugger/debug_info/DwarfTypes.h @@ -41,6 +41,11 @@ class RegisterMap; class ValueLocation; +// conversion functions between model types and dwarf types +type_kind dwarf_tag_to_type_kind(int32 tag); +int32 dwarf_tag_to_subtype_kind(int32 tag); + + class DwarfTypeContext : public BReferenceable { public: DwarfTypeContext(Architecture* architecture, diff --git a/src/apps/debugger/debug_info/GlobalTypeLookup.h b/src/apps/debugger/debug_info/GlobalTypeLookup.h index a9727b7e7b..c045d3789c 100644 --- a/src/apps/debugger/debug_info/GlobalTypeLookup.h +++ b/src/apps/debugger/debug_info/GlobalTypeLookup.h @@ -15,6 +15,7 @@ class BString; class Type; +class TypeLookupConstraints; enum global_type_cache_scope { @@ -62,7 +63,9 @@ public: virtual ~GlobalTypeLookup(); virtual status_t GetType(GlobalTypeCache* cache, - const BString& name, Type*& _type) = 0; + const BString& name, + const TypeLookupConstraints& constraints, + Type*& _type) = 0; // returns a reference }; diff --git a/src/apps/debugger/debug_info/ImageDebugInfo.cpp b/src/apps/debugger/debug_info/ImageDebugInfo.cpp index 73f52d72d1..2a39419a19 100644 --- a/src/apps/debugger/debug_info/ImageDebugInfo.cpp +++ b/src/apps/debugger/debug_info/ImageDebugInfo.cpp @@ -78,11 +78,12 @@ ImageDebugInfo::FinishInit() status_t ImageDebugInfo::GetType(GlobalTypeCache* cache, const BString& name, - Type*& _type) + const TypeLookupConstraints& constraints, Type*& _type) { for (int32 i = 0; SpecificImageDebugInfo* specificInfo = fSpecificInfos.ItemAt(i); i++) { - status_t error = specificInfo->GetType(cache, name, _type); + status_t error = specificInfo->GetType(cache, name, constraints, + _type); if (error == B_OK || error == B_NO_MEMORY) return error; } diff --git a/src/apps/debugger/debug_info/ImageDebugInfo.h b/src/apps/debugger/debug_info/ImageDebugInfo.h index e2fd75ca89..5f30ace950 100644 --- a/src/apps/debugger/debug_info/ImageDebugInfo.h +++ b/src/apps/debugger/debug_info/ImageDebugInfo.h @@ -26,6 +26,7 @@ class GlobalTypeCache; class LocatableFile; class SpecificImageDebugInfo; class Type; +class TypeLookupConstraints; class ImageDebugInfo : public BReferenceable { @@ -39,7 +40,9 @@ public: status_t FinishInit(); status_t GetType(GlobalTypeCache* cache, - const BString& name, Type*& _type); + const BString& name, + const TypeLookupConstraints& constraints, + Type*& _type); // returns a reference AddressSectionType GetAddressSectionType(target_addr_t address) const; diff --git a/src/apps/debugger/debug_info/SpecificImageDebugInfo.h b/src/apps/debugger/debug_info/SpecificImageDebugInfo.h index 779f16e19f..2778c887f5 100644 --- a/src/apps/debugger/debug_info/SpecificImageDebugInfo.h +++ b/src/apps/debugger/debug_info/SpecificImageDebugInfo.h @@ -29,6 +29,7 @@ class SourceLocation; class StackFrame; class Statement; class Type; +class TypeLookupConstraints; class ValueLocation; @@ -42,7 +43,9 @@ public: // returns references virtual status_t GetType(GlobalTypeCache* cache, - const BString& name, Type*& _type) = 0; + const BString& name, + const TypeLookupConstraints& constraints, + Type*& _type) = 0; // returns a reference virtual AddressSectionType GetAddressSectionType(target_addr_t address) = 0; diff --git a/src/apps/debugger/debug_info/TeamDebugInfo.cpp b/src/apps/debugger/debug_info/TeamDebugInfo.cpp index 87096e8fb9..6a766c6180 100644 --- a/src/apps/debugger/debug_info/TeamDebugInfo.cpp +++ b/src/apps/debugger/debug_info/TeamDebugInfo.cpp @@ -29,6 +29,7 @@ #include "SpecificImageDebugInfo.h" #include "StringUtils.h" #include "Type.h" +#include "TypeLookupConstraints.h" // #pragma mark - FunctionHashDefinition @@ -362,7 +363,7 @@ TeamDebugInfo::Init() status_t TeamDebugInfo::GetType(GlobalTypeCache* cache, const BString& name, - Type*& _type) + const TypeLookupConstraints& constraints, Type*& _type) { // maybe the type is already cached AutoLocker cacheLocker(cache); @@ -390,7 +391,7 @@ TeamDebugInfo::GetType(GlobalTypeCache* cache, const BString& name, // get the type status_t error = B_ENTRY_NOT_FOUND; for (int32 i = 0; ImageDebugInfo* imageDebugInfo = images.ItemAt(i); i++) { - error = imageDebugInfo->GetType(cache, name, type); + error = imageDebugInfo->GetType(cache, name, constraints, type); if (error == B_OK) { _type = type; break; diff --git a/src/apps/debugger/debug_info/TeamDebugInfo.h b/src/apps/debugger/debug_info/TeamDebugInfo.h index d2ff0f6e99..adffe2df16 100644 --- a/src/apps/debugger/debug_info/TeamDebugInfo.h +++ b/src/apps/debugger/debug_info/TeamDebugInfo.h @@ -43,7 +43,9 @@ public: status_t Init(); virtual status_t GetType(GlobalTypeCache* cache, - const BString& name, Type*& _type); + const BString& name, + const TypeLookupConstraints& constraints, + Type*& _type); status_t LoadImageDebugInfo(const ImageInfo& imageInfo, LocatableFile* imageFile, diff --git a/src/apps/debugger/model/Type.h b/src/apps/debugger/model/Type.h index 6494d922ce..50eec701f5 100644 --- a/src/apps/debugger/model/Type.h +++ b/src/apps/debugger/model/Type.h @@ -29,6 +29,14 @@ enum type_kind { }; +enum compound_type_kind { + COMPOUND_TYPE_CLASS, + COMPOUND_TYPE_STRUCT, + COMPOUND_TYPE_UNION, + COMPOUND_TYPE_INTERFACE +}; + + enum address_type_kind { DERIVED_TYPE_POINTER, DERIVED_TYPE_REFERENCE diff --git a/src/apps/debugger/model/TypeLookupConstraints.cpp b/src/apps/debugger/model/TypeLookupConstraints.cpp new file mode 100644 index 0000000000..1e3a0db3bf --- /dev/null +++ b/src/apps/debugger/model/TypeLookupConstraints.cpp @@ -0,0 +1,79 @@ +/* + * Copyright 2011, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ + + +#include "TypeLookupConstraints.h" + + +TypeLookupConstraints::TypeLookupConstraints() + : + fTypeKindGiven(false), + fSubtypeKindGiven(false) +{ +} + + +TypeLookupConstraints::TypeLookupConstraints(type_kind typeKind) + : + fTypeKind(typeKind), + fTypeKindGiven(true), + fSubtypeKindGiven(false) +{ +} + + +TypeLookupConstraints::TypeLookupConstraints(type_kind typeKind, + int32 subTypeKind) + : + fTypeKind(typeKind), + fSubtypeKind(subTypeKind), + fTypeKindGiven(true), + fSubtypeKindGiven(true) +{ +} + + +bool +TypeLookupConstraints::HasTypeKind() const +{ + return fTypeKindGiven; +} + + +bool +TypeLookupConstraints::HasSubtypeKind() const +{ + return fSubtypeKindGiven; +} + + +type_kind +TypeLookupConstraints::TypeKind() const +{ + return fTypeKind; +} + + +int32 +TypeLookupConstraints::SubtypeKind() const +{ + return fSubtypeKind; +} + + +void +TypeLookupConstraints::SetTypeKind(type_kind typeKind) +{ + fTypeKind = typeKind; + fTypeKindGiven = true; +} + + +void +TypeLookupConstraints::SetSubtypeKind(int32 subtypeKind) +{ + fSubtypeKind = subtypeKind; + fSubtypeKindGiven = true; +} diff --git a/src/apps/debugger/model/TypeLookupConstraints.h b/src/apps/debugger/model/TypeLookupConstraints.h new file mode 100644 index 0000000000..637df3f506 --- /dev/null +++ b/src/apps/debugger/model/TypeLookupConstraints.h @@ -0,0 +1,36 @@ +/* + * Copyright 2011, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef TYPE_LOOKUP_CONSTRAINTS_H +#define TYPE_LOOKUP_CONSTRAINTS_H + + +#include "Type.h" + + +class TypeLookupConstraints { +public: + TypeLookupConstraints(); + // no constraints + TypeLookupConstraints(type_kind typeKind); + // constrain on type only + TypeLookupConstraints(type_kind typeKind, + int32 subtypeKind); + + bool HasTypeKind() const; + bool HasSubtypeKind() const; + type_kind TypeKind() const; + int32 SubtypeKind() const; + + void SetTypeKind(type_kind typeKind); + void SetSubtypeKind(int32 subtypeKind); + +private: + type_kind fTypeKind; + int32 fSubtypeKind; + bool fTypeKindGiven; + bool fSubtypeKindGiven; +}; + +#endif // TYPE_LOOKUP_CONSTRAINTS_H