Index: source/Plugins/SymbolFile/DWARF/CMakeLists.txt =================================================================== --- source/Plugins/SymbolFile/DWARF/CMakeLists.txt +++ source/Plugins/SymbolFile/DWARF/CMakeLists.txt @@ -21,6 +21,7 @@ DWARFFormValue.cpp DWARFLocationDescription.cpp DWARFLocationList.cpp + HashedNameToDIE.cpp LogChannelDWARF.cpp NameToDIE.cpp SymbolFileDWARF.cpp Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h +++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h @@ -114,9 +114,6 @@ DWARFDebugInfoEntry* GetDIEPtr (dw_offset_t die_offset); - const DWARFDebugInfoEntry* - GetDIEPtrContainingOffset (dw_offset_t die_offset); - static uint8_t GetAddressByteSize(const DWARFCompileUnit* cu); Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -576,40 +576,6 @@ return NULL; // Not found in any compile units } -//---------------------------------------------------------------------- -// GetDIEPtrContainingOffset() -// -// Get the DIE (Debug Information Entry) that contains the specified -// .debug_info offset. -//---------------------------------------------------------------------- -const DWARFDebugInfoEntry* -DWARFCompileUnit::GetDIEPtrContainingOffset(dw_offset_t die_offset) -{ - if (die_offset != DW_INVALID_OFFSET) - { - ExtractDIEsIfNeeded (false); - DWARFDebugInfoEntry compare_die; - compare_die.SetOffset(die_offset); - DWARFDebugInfoEntry::iterator end = m_die_array.end(); - DWARFDebugInfoEntry::iterator pos = lower_bound(m_die_array.begin(), end, compare_die, CompareDIEOffset); - if (pos != end) - { - if (die_offset >= (*pos).GetOffset()) - { - DWARFDebugInfoEntry::iterator next = pos + 1; - if (next != end) - { - if (die_offset < (*next).GetOffset()) - return &(*pos); - } - } - } - } - return NULL; // Not found in any compile units -} - - - size_t DWARFCompileUnit::AppendDIEsWithTag (const dw_tag_t tag, DWARFDIECollection& dies, uint32_t depth) const { Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h +++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h @@ -54,8 +54,6 @@ DWARFDebugInfoEntry* GetDIEPtr(dw_offset_t die_offset, DWARFCompileUnitSP* cu_sp_ptr); DWARFDebugInfoEntry* GetDIEPtrWithCompileUnitHint (dw_offset_t die_offset, DWARFCompileUnit**cu_handle); - const DWARFDebugInfoEntry* GetDIEPtrContainingOffset(dw_offset_t die_offset, DWARFCompileUnitSP* cu_sp_ptr); - void Dump(lldb_private::Stream *s, const uint32_t die_offset, const uint32_t recurse_depth); static void Parse(SymbolFileDWARF* parser, Callback callback, void* userData); static void Verify(lldb_private::Stream *s, SymbolFileDWARF* dwarf2Data); Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp @@ -328,20 +328,6 @@ return die; } - -const DWARFDebugInfoEntry* -DWARFDebugInfo::GetDIEPtrContainingOffset(dw_offset_t die_offset, DWARFCompileUnitSP* cu_sp_ptr) -{ - DWARFCompileUnitSP cu_sp(GetCompileUnitContainingDIE(die_offset)); - if (cu_sp_ptr) - *cu_sp_ptr = cu_sp; - if (cu_sp.get()) - return cu_sp->GetDIEPtrContainingOffset(die_offset); - - return NULL; // Not found in any compile units - -} - //---------------------------------------------------------------------- // AddCompileUnit //---------------------------------------------------------------------- Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h +++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h @@ -89,23 +89,6 @@ collection m_infos; }; - struct CompareState - { - CompareState() : - die_offset_pairs() - { - assert(sizeof(dw_offset_t)*2 == sizeof(uint64_t)); - } - - bool AddTypePair(dw_offset_t a, dw_offset_t b) - { - uint64_t a_b_offsets = (uint64_t)a << 32 | (uint64_t)b; - // Return true if this type was inserted, false otherwise - return die_offset_pairs.insert(a_b_offsets).second; - } - std::set< uint64_t > die_offset_pairs; - }; - DWARFDebugInfoEntry(): m_offset (DW_INVALID_OFFSET), m_parent_idx (0), @@ -258,22 +241,6 @@ const DWARFDebugInfoEntry::Attributes& attributes, std::string &storage) const; -// static int Compare( -// SymbolFileDWARF* dwarf2Data, -// dw_offset_t a_die_offset, -// dw_offset_t b_die_offset, -// CompareState &compare_state, -// bool compare_siblings, -// bool compare_children); -// -// static int Compare( -// SymbolFileDWARF* dwarf2Data, -// DWARFCompileUnit* a_cu, const DWARFDebugInfoEntry* a_die, -// DWARFCompileUnit* b_cu, const DWARFDebugInfoEntry* b_die, -// CompareState &compare_state, -// bool compare_siblings, -// bool compare_children); - static bool OffsetLessThan ( const DWARFDebugInfoEntry& a, const DWARFDebugInfoEntry& b); Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -460,276 +460,6 @@ } //---------------------------------------------------------------------- -// Compare two DIE by comparing all their attributes values, and -// following all DW_FORM_ref attributes and comparing their contents as -// well (except for DW_AT_sibling attributes. -// -// DWARFDebugInfoEntry::CompareState compare_state; -// int result = DWARFDebugInfoEntry::Compare(this, 0x00017ccb, 0x0001eb2b, compare_state, false, true); -//---------------------------------------------------------------------- -//int -//DWARFDebugInfoEntry::Compare -//( -// SymbolFileDWARF* dwarf2Data, -// dw_offset_t a_die_offset, -// dw_offset_t b_die_offset, -// CompareState &compare_state, -// bool compare_siblings, -// bool compare_children -//) -//{ -// if (a_die_offset == b_die_offset) -// return 0; -// -// DWARFCompileUnitSP a_cu_sp; -// DWARFCompileUnitSP b_cu_sp; -// const DWARFDebugInfoEntry* a_die = dwarf2Data->DebugInfo()->GetDIEPtr(a_die_offset, &a_cu_sp); -// const DWARFDebugInfoEntry* b_die = dwarf2Data->DebugInfo()->GetDIEPtr(b_die_offset, &b_cu_sp); -// -// return Compare(dwarf2Data, a_cu_sp.get(), a_die, b_cu_sp.get(), b_die, compare_state, compare_siblings, compare_children); -//} -// -//int -//DWARFDebugInfoEntry::Compare -//( -// SymbolFileDWARF* dwarf2Data, -// DWARFCompileUnit* a_cu, const DWARFDebugInfoEntry* a_die, -// DWARFCompileUnit* b_cu, const DWARFDebugInfoEntry* b_die, -// CompareState &compare_state, -// bool compare_siblings, -// bool compare_children -//) -//{ -// if (a_die == b_die) -// return 0; -// -// if (!compare_state.AddTypePair(a_die->GetOffset(), b_die->GetOffset())) -// { -// // We are already comparing both of these types, so let -// // compares complete for the real result -// return 0; -// } -// -// //printf("DWARFDebugInfoEntry::Compare(0x%8.8x, 0x%8.8x)\n", a_die->GetOffset(), b_die->GetOffset()); -// -// // Do we have two valid DIEs? -// if (a_die && b_die) -// { -// // Both DIE are valid -// int result = 0; -// -// const dw_tag_t a_tag = a_die->Tag(); -// const dw_tag_t b_tag = b_die->Tag(); -// if (a_tag == 0 && b_tag == 0) -// return 0; -// -// //printf(" comparing tags: %s and %s\n", DW_TAG_value_to_name(a_tag), DW_TAG_value_to_name(b_tag)); -// -// if (a_tag < b_tag) -// return -1; -// else if (a_tag > b_tag) -// return 1; -// -// DWARFDebugInfoEntry::Attributes a_attrs; -// DWARFDebugInfoEntry::Attributes b_attrs; -// size_t a_attr_count = a_die->GetAttributes(dwarf2Data, a_cu, a_attrs); -// size_t b_attr_count = b_die->GetAttributes(dwarf2Data, b_cu, b_attrs); -// if (a_attr_count != b_attr_count) -// { -// a_attrs.RemoveAttribute(DW_AT_sibling); -// b_attrs.RemoveAttribute(DW_AT_sibling); -// } -// -// a_attr_count = a_attrs.Size(); -// b_attr_count = b_attrs.Size(); -// -// DWARFFormValue a_form_value; -// DWARFFormValue b_form_value; -// -// if (a_attr_count != b_attr_count) -// { -// uint32_t is_decl_index = a_attrs.FindAttributeIndex(DW_AT_declaration); -// uint32_t a_name_index = UINT32_MAX; -// uint32_t b_name_index = UINT32_MAX; -// if (is_decl_index != UINT32_MAX) -// { -// if (a_attr_count == 2) -// { -// a_name_index = a_attrs.FindAttributeIndex(DW_AT_name); -// b_name_index = b_attrs.FindAttributeIndex(DW_AT_name); -// } -// } -// else -// { -// is_decl_index = b_attrs.FindAttributeIndex(DW_AT_declaration); -// if (is_decl_index != UINT32_MAX && a_attr_count == 2) -// { -// a_name_index = a_attrs.FindAttributeIndex(DW_AT_name); -// b_name_index = b_attrs.FindAttributeIndex(DW_AT_name); -// } -// } -// if (a_name_index != UINT32_MAX && b_name_index != UINT32_MAX) -// { -// if (a_attrs.ExtractFormValueAtIndex(dwarf2Data, a_name_index, a_form_value) && -// b_attrs.ExtractFormValueAtIndex(dwarf2Data, b_name_index, b_form_value)) -// { -// result = DWARFFormValue::Compare (a_form_value, b_form_value, a_cu, b_cu, &dwarf2Data->get_debug_str_data()); -// if (result == 0) -// { -// a_attr_count = b_attr_count = 0; -// compare_children = false; -// } -// } -// } -// } -// -// if (a_attr_count < b_attr_count) -// return -1; -// if (a_attr_count > b_attr_count) -// return 1; -// -// -// // The number of attributes are the same... -// if (a_attr_count > 0) -// { -// const DWARFDataExtractor* debug_str_data_ptr = &dwarf2Data->get_debug_str_data(); -// -// uint32_t i; -// for (i=0; i b_attr) -// return 1; -// -// switch (a_attr) -// { -// // Since we call a form of GetAttributes which inlines the -// // attributes from DW_AT_abstract_origin and DW_AT_specification -// // we don't care if their values mismatch... -// case DW_AT_abstract_origin: -// case DW_AT_specification: -// case DW_AT_sibling: -// case DW_AT_containing_type: -// //printf(" action = IGNORE\n"); -// result = 0; -// break; // ignore -// -// default: -// if (a_attrs.ExtractFormValueAtIndex(dwarf2Data, i, a_form_value) && -// b_attrs.ExtractFormValueAtIndex(dwarf2Data, i, b_form_value)) -// result = DWARFFormValue::Compare (a_form_value, b_form_value, a_cu, b_cu, debug_str_data_ptr); -// break; -// } -// -// //printf("\t result = %i\n", result); -// -// if (result != 0) -// { -// // Attributes weren't equal, lets see if we care? -// switch (a_attr) -// { -// case DW_AT_decl_file: -// // TODO: add the ability to compare files in two different compile units -// if (a_cu == b_cu) -// { -// //printf(" action = RETURN RESULT\n"); -// return result; // Only return the compare results when the compile units are the same and the decl_file attributes can be compared -// } -// else -// { -// result = 0; -// //printf(" action = IGNORE\n"); -// } -// break; -// -// default: -// switch (a_attrs.FormAtIndex(i)) -// { -// case DW_FORM_ref1: -// case DW_FORM_ref2: -// case DW_FORM_ref4: -// case DW_FORM_ref8: -// case DW_FORM_ref_udata: -// case DW_FORM_ref_addr: -// //printf(" action = COMPARE DIEs 0x%8.8x 0x%8.8x\n", (dw_offset_t)a_form_value.Reference(a_cu), (dw_offset_t)b_form_value.Reference(b_cu)); -// // These attribute values refer to other DIEs, so lets compare those instead of their DIE offsets... -// result = Compare(dwarf2Data, a_form_value.Reference(a_cu), b_form_value.Reference(b_cu), compare_state, false, true); -// if (result != 0) -// return result; -// break; -// -// default: -// // We do care that they were different, return this result... -// //printf(" action = RETURN RESULT\n"); -// return result; -// } -// } -// } -// } -// } -// //printf(" SUCCESS\n\t\t0x%8.8x: %s\n\t\t0x%8.8x: %s\n", a_die->GetOffset(), DW_TAG_value_to_name(a_tag), b_die->GetOffset(), DW_TAG_value_to_name(b_tag)); -// -// if (compare_children) -// { -// bool a_has_children = a_die->HasChildren(); -// bool b_has_children = b_die->HasChildren(); -// if (a_has_children == b_has_children) -// { -// // Both either have kids or don't -// if (a_has_children) -// result = Compare( dwarf2Data, -// a_cu, a_die->GetFirstChild(), -// b_cu, b_die->GetFirstChild(), -// compare_state, true, compare_children); -// else -// result = 0; -// } -// else if (!a_has_children) -// result = -1; // A doesn't have kids, but B does -// else -// result = 1; // A has kids, but B doesn't -// } -// -// if (compare_siblings) -// { -// result = Compare( dwarf2Data, -// a_cu, a_die->GetSibling(), -// b_cu, b_die->GetSibling(), -// compare_state, true, compare_children); -// } -// -// return result; -// } -// -// if (a_die == NULL) -// return -1; // a_die is NULL, yet b_die is non-NULL -// else -// return 1; // a_die is non-NULL, yet b_die is NULL -// -//} -// -// -//int -//DWARFDebugInfoEntry::Compare -//( -// SymbolFileDWARF* dwarf2Data, -// const DWARFCompileUnit* cu_a, -// const DWARFDebugInfoEntry* die_a, -// const DWARFCompileUnit* cu_a, -// const DWARFDebugInfoEntry* die_b, -// CompareState &compare_state -//) -//{ -//} - -//---------------------------------------------------------------------- // GetDIENamesAndRanges // // Gets the valid address ranges for a given DIE by looking for a Index: source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h =================================================================== --- source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h +++ source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h @@ -12,139 +12,36 @@ #include -#include "DWARFDefines.h" -#include "DWARFFormValue.h" - #include "lldb/lldb-defines.h" #include "lldb/Core/dwarf.h" #include "lldb/Core/RegularExpression.h" #include "lldb/Core/MappedHash.h" +#include "DWARFDefines.h" +#include "DWARFFormValue.h" +#include "NameToDIE.h" class SymbolFileDWARF; class DWARFCompileUnit; class DWARFDebugInfoEntry; -struct DWARFMappedHash +class DWARFMappedHash { - struct DIEInfo - { - dw_offset_t offset; // The DIE offset - dw_tag_t tag; - uint32_t type_flags; // Any flags for this DIEInfo - uint32_t qualified_name_hash; // A 32 bit hash of the fully qualified name - - DIEInfo () : - offset (DW_INVALID_OFFSET), - tag (0), - type_flags (0), - qualified_name_hash (0) - { - } - - DIEInfo (dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h) : - offset(o), - tag (t), - type_flags (f), - qualified_name_hash (h) - { - } - - void - Clear() - { - offset = DW_INVALID_OFFSET; - tag = 0; - type_flags = 0; - qualified_name_hash = 0; - } - }; - - typedef std::vector DIEInfoArray; - typedef std::vector DIEArray; - - static void - ExtractDIEArray (const DIEInfoArray &die_info_array, - DIEArray &die_offsets) - { - const size_t count = die_info_array.size(); - for (size_t i=0; i::iterator" would have a name of "iterator" // and a 32 bit hash for "std::vector::iterator" to allow us to not have to pull // in debug info for a type when we know the fully qualified name. }; - + // Bit definitions for the eAtomTypeTypeFlags flags enum TypeFlags { @@ -152,783 +49,172 @@ // @implementation for class eTypeFlagClassIsImplementation = ( 1u << 1 ) }; - - static void - ExtractClassOrStructDIEArray (const DIEInfoArray &die_info_array, - bool return_implementation_only_if_available, - DIEArray &die_offsets) + struct DIEInfo { - const size_t count = die_info_array.size(); - for (size_t i=0; i DIEInfoArray; typedef std::vector AtomArray; - - static uint32_t - GetTypeFlags (SymbolFileDWARF *dwarf2Data, - const DWARFCompileUnit* cu, - const DWARFDebugInfoEntry* die); - - static const char * - GetAtomTypeName (uint16_t atom) - { - switch (atom) - { - case eAtomTypeNULL: return "NULL"; - case eAtomTypeDIEOffset: return "die-offset"; - case eAtomTypeCUOffset: return "cu-offset"; - case eAtomTypeTag: return "die-tag"; - case eAtomTypeNameFlags: return "name-flags"; - case eAtomTypeTypeFlags: return "type-flags"; - case eAtomTypeQualNameHash: return "qualified-name-hash"; - } - return ""; - } - struct Prologue + class Prologue { - // DIE offset base so die offsets in hash_data can be CU relative - dw_offset_t die_base_offset; - AtomArray atoms; - uint32_t atom_mask; - size_t min_hash_data_byte_size; - bool hash_data_has_fixed_byte_size; - - Prologue (dw_offset_t _die_base_offset = 0) : - die_base_offset (_die_base_offset), - atoms(), - atom_mask (0), - min_hash_data_byte_size(0), - hash_data_has_fixed_byte_size(true) - { - // Define an array of DIE offsets by first defining an array, - // and then define the atom type for the array, in this case - // we have an array of DIE offsets - AppendAtom (eAtomTypeDIEOffset, DW_FORM_data4); - } - - virtual ~Prologue() - { - } + public: + Prologue (dw_offset_t _die_base_offset = 0); void - ClearAtoms () - { - hash_data_has_fixed_byte_size = true; - min_hash_data_byte_size = 0; - atom_mask = 0; - atoms.clear(); - } + ClearAtoms (); bool - ContainsAtom (AtomType atom_type) const - { - return (atom_mask & (1u << atom_type)) != 0; - } - - virtual void - Clear () - { - die_base_offset = 0; - ClearAtoms (); - } - + ContainsAtom (AtomType atom_type) const; + void - AppendAtom (AtomType type, dw_form_t form) - { - atoms.push_back (Atom(type, form)); - atom_mask |= 1u << type; - switch (form) - { - case DW_FORM_indirect: - case DW_FORM_exprloc: - case DW_FORM_flag_present: - case DW_FORM_ref_sig8: - assert (!"Unhandled atom form"); - break; - - case DW_FORM_string: - case DW_FORM_block: - case DW_FORM_block1: - case DW_FORM_sdata: - case DW_FORM_udata: - case DW_FORM_ref_udata: - case DW_FORM_GNU_addr_index: - case DW_FORM_GNU_str_index: - hash_data_has_fixed_byte_size = false; - // Fall through to the cases below... - case DW_FORM_flag: - case DW_FORM_data1: - case DW_FORM_ref1: - case DW_FORM_sec_offset: - min_hash_data_byte_size += 1; - break; - - case DW_FORM_block2: - hash_data_has_fixed_byte_size = false; - // Fall through to the cases below... - case DW_FORM_data2: - case DW_FORM_ref2: - min_hash_data_byte_size += 2; - break; - - case DW_FORM_block4: - hash_data_has_fixed_byte_size = false; - // Fall through to the cases below... - case DW_FORM_data4: - case DW_FORM_ref4: - case DW_FORM_addr: - case DW_FORM_ref_addr: - case DW_FORM_strp: - min_hash_data_byte_size += 4; - break; - - case DW_FORM_data8: - case DW_FORM_ref8: - min_hash_data_byte_size += 8; - break; - - } - } - -// void -// Dump (std::ostream* ostrm_ptr); - + Clear (); + + void + AppendAtom (AtomType type, dw_form_t form); + lldb::offset_t - Read (const lldb_private::DataExtractor &data, - lldb::offset_t offset) - { - ClearAtoms (); - - die_base_offset = data.GetU32 (&offset); - - const uint32_t atom_count = data.GetU32 (&offset); - if (atom_count == 0x00060003u) - { - // Old format, deal with contents of old pre-release format - while (data.GetU32(&offset)) - /* do nothing */; - - // Hardcode to the only known value for now. - AppendAtom (eAtomTypeDIEOffset, DW_FORM_data4); - } - else - { - for (uint32_t i=0; i + class Header : public MappedHash::Header { - Header (dw_offset_t _die_base_offset = 0) - { - } - - virtual - ~Header() - { - } - - virtual size_t - GetByteSize (const HeaderData &header_data) - { - return header_data.GetByteSize(); - } - - // virtual void - // Dump (std::ostream* ostrm_ptr); - // - virtual lldb::offset_t - Read (lldb_private::DataExtractor &data, lldb::offset_t offset) - { - offset = MappedHash::Header::Read (data, offset); - if (offset != UINT32_MAX) - { - offset = header_data.Read (data, offset); - } - return offset; - } - + public: + size_t + GetByteSize (const HeaderData &header_data) override; + + lldb::offset_t + Read (lldb_private::DataExtractor &data, lldb::offset_t offset) override; + bool Read (const lldb_private::DWARFDataExtractor &data, lldb::offset_t *offset_ptr, - DIEInfo &hash_data) const - { - const size_t num_atoms = header_data.atoms.size(); - if (num_atoms == 0) - return false; - - for (size_t i=0; i 0) - strm.PutCString (", "); - - DWARFFormValue form_value (NULL, header_data.atoms[i].form); - switch (header_data.atoms[i].type) - { - case eAtomTypeDIEOffset: // DIE offset, check form for encoding - strm.Printf ("{0x%8.8x}", hash_data.offset); - break; - - case eAtomTypeTag: // DW_TAG value for the DIE - { - const char *tag_cstr = lldb_private::DW_TAG_value_to_name (hash_data.tag); - if (tag_cstr) - strm.PutCString (tag_cstr); - else - strm.Printf ("DW_TAG_(0x%4.4x)", hash_data.tag); - } - break; - - case eAtomTypeTypeFlags: // Flags from enum TypeFlags - strm.Printf ("0x%2.2x", hash_data.type_flags); - if (hash_data.type_flags) - { - strm.PutCString (" ("); - if (hash_data.type_flags & eTypeFlagClassIsImplementation) - strm.PutCString (" implementation"); - strm.PutCString (" )"); - } - break; - - case eAtomTypeQualNameHash: // Flags from enum TypeFlags - strm.Printf ("0x%8.8x", hash_data.qualified_name_hash); - break; - - default: - strm.Printf ("AtomType(0x%x)", header_data.atoms[i].type); - break; - } - } - } + Dump (lldb_private::Stream& strm, const DIEInfo &hash_data) const; }; - -// class ExportTable -// { -// public: -// ExportTable (); -// -// void -// AppendNames (DWARFDebugPubnamesSet &pubnames_set, -// StringTable &string_table); -// -// void -// AppendNamesEntry (SymbolFileDWARF *dwarf2Data, -// const DWARFCompileUnit* cu, -// const DWARFDebugInfoEntry* die, -// StringTable &string_table); -// -// void -// AppendTypesEntry (DWARFData *dwarf2Data, -// const DWARFCompileUnit* cu, -// const DWARFDebugInfoEntry* die, -// StringTable &string_table); -// -// size_t -// Save (BinaryStreamBuf &names_data, const StringTable &string_table); -// -// void -// AppendName (const char *name, -// uint32_t die_offset, -// StringTable &string_table, -// dw_offset_t name_debug_str_offset = DW_INVALID_OFFSET); // If "name" has already been looked up, then it can be supplied -// void -// AppendType (const char *name, -// uint32_t die_offset, -// StringTable &string_table); -// -// -// protected: -// struct Entry -// { -// uint32_t hash; -// uint32_t str_offset; -// uint32_t die_offset; -// }; -// -// // Map uniqued .debug_str offset to the corresponding DIE offsets -// typedef std::map NameInfo; -// // Map a name hash to one or more name infos -// typedef std::map BucketEntry; -// -// static uint32_t -// GetByteSize (const NameInfo &name_info); -// -// typedef std::vector BucketEntryColl; -// typedef std::vector EntryColl; -// EntryColl m_entries; -// -// }; - - + // A class for reading and using a saved hash table from a block of data // in memory class MemoryTable : public MappedHash::MemoryTable { public: - MemoryTable (lldb_private::DWARFDataExtractor &table_data, const lldb_private::DWARFDataExtractor &string_table, - const char *name) : - MappedHash::MemoryTable (table_data), - m_data (table_data), - m_string_table (string_table), - m_name (name) - { - } - - virtual - ~MemoryTable () - { - } - - virtual const char * - GetStringForKeyType (KeyType key) const - { - // The key in the DWARF table is the .debug_str offset for the string - return m_string_table.PeekCStr (key); - } + const char *name); + + const char * + GetStringForKeyType (KeyType key) const override; - virtual bool - ReadHashData (uint32_t hash_data_offset, - HashData &hash_data) const - { - lldb::offset_t offset = hash_data_offset; - offset += 4; // Skip string table offset that contains offset of hash name in .debug_str - const uint32_t count = m_data.GetU32 (&offset); - if (count > 0) - { - hash_data.resize(count); - for (uint32_t i=0; i 0 && m_data.ValidOffsetForDataOfSize (*hash_data_offset_ptr, min_total_hash_data_size)) - { - // We have at least one HashData entry, and we have enough - // data to parse at least "count" HashData entries. - - // First make sure the entire C string matches... - const bool match = strcmp (name, strp_cstr) == 0; - - if (!match && m_header.header_data.HashDataHasFixedByteSize()) - { - // If the string doesn't match and we have fixed size data, - // we can just add the total byte size of all HashData objects - // to the hash data offset and be done... - *hash_data_offset_ptr += min_total_hash_data_size; - } - else - { - // If the string does match, or we don't have fixed size data - // then we need to read the hash data as a stream. If the - // string matches we also append all HashData objects to the - // value array. - for (uint32_t i=0; i 0 && m_data.ValidOffsetForDataOfSize (*hash_data_offset_ptr, min_total_hash_data_size)) - { - const bool match = regex.Execute(strp_cstr); - - if (!match && m_header.header_data.HashDataHasFixedByteSize()) - { - // If the regex doesn't match and we have fixed size data, - // we can just add the total byte size of all HashData objects - // to the hash data offset and be done... - *hash_data_offset_ptr += min_total_hash_data_size; - } - else - { - // If the string does match, or we don't have fixed size data - // then we need to read the hash data as a stream. If the - // string matches we also append all HashData objects to the - // value array. - for (uint32_t i=0; i"; +} + +DWARFMappedHash::DIEInfo::DIEInfo () : + offset (DW_INVALID_OFFSET), + tag (0), + type_flags (0), + qualified_name_hash (0) +{ +} + +DWARFMappedHash::DIEInfo::DIEInfo (dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h) : + offset (o), + tag (t), + type_flags (f), + qualified_name_hash (h) +{ +} + +DWARFMappedHash::Prologue::Prologue (dw_offset_t _die_base_offset) : + die_base_offset (_die_base_offset), + atoms(), + atom_mask (0), + min_hash_data_byte_size(0), + hash_data_has_fixed_byte_size(true) +{ + // Define an array of DIE offsets by first defining an array, + // and then define the atom type for the array, in this case + // we have an array of DIE offsets + AppendAtom (eAtomTypeDIEOffset, DW_FORM_data4); +} + +void +DWARFMappedHash::Prologue::ClearAtoms () +{ + hash_data_has_fixed_byte_size = true; + min_hash_data_byte_size = 0; + atom_mask = 0; + atoms.clear(); +} + +bool +DWARFMappedHash::Prologue::ContainsAtom (AtomType atom_type) const +{ + return (atom_mask & (1u << atom_type)) != 0; +} + +void +DWARFMappedHash::Prologue::Clear () +{ + die_base_offset = 0; + ClearAtoms (); +} + +void +DWARFMappedHash::Prologue::AppendAtom (AtomType type, dw_form_t form) +{ + atoms.push_back ({type, form}); + atom_mask |= 1u << type; + switch (form) + { + case DW_FORM_indirect: + case DW_FORM_exprloc: + case DW_FORM_flag_present: + case DW_FORM_ref_sig8: + assert (!"Unhandled atom form"); + break; + + case DW_FORM_string: + case DW_FORM_block: + case DW_FORM_block1: + case DW_FORM_sdata: + case DW_FORM_udata: + case DW_FORM_ref_udata: + case DW_FORM_GNU_addr_index: + case DW_FORM_GNU_str_index: + hash_data_has_fixed_byte_size = false; + // Fall through to the cases below... + case DW_FORM_flag: + case DW_FORM_data1: + case DW_FORM_ref1: + case DW_FORM_sec_offset: + min_hash_data_byte_size += 1; + break; + + case DW_FORM_block2: + hash_data_has_fixed_byte_size = false; + // Fall through to the cases below... + case DW_FORM_data2: + case DW_FORM_ref2: + min_hash_data_byte_size += 2; + break; + + case DW_FORM_block4: + hash_data_has_fixed_byte_size = false; + // Fall through to the cases below... + case DW_FORM_data4: + case DW_FORM_ref4: + case DW_FORM_addr: + case DW_FORM_ref_addr: + case DW_FORM_strp: + min_hash_data_byte_size += 4; + break; + + case DW_FORM_data8: + case DW_FORM_ref8: + min_hash_data_byte_size += 8; + break; + + } +} + +lldb::offset_t +DWARFMappedHash::Prologue::Read (const lldb_private::DataExtractor &data, + lldb::offset_t offset) +{ + ClearAtoms (); + + die_base_offset = data.GetU32 (&offset); + + const uint32_t atom_count = data.GetU32 (&offset); + if (atom_count == 0x00060003u) + { + // Old format, deal with contents of old pre-release format + while (data.GetU32(&offset)) + /* do nothing */; + + // Hardcode to the only known value for now. + AppendAtom (eAtomTypeDIEOffset, DW_FORM_data4); + } + else + { + for (uint32_t i=0; i::Read (data, offset); + if (offset != UINT32_MAX) + { + offset = header_data.Read (data, offset); + } + return offset; +} + +bool +DWARFMappedHash::Header::Read (const lldb_private::DWARFDataExtractor &data, + lldb::offset_t *offset_ptr, + DIEInfo &hash_data) const +{ + const size_t num_atoms = header_data.atoms.size(); + if (num_atoms == 0) + return false; + + for (size_t i=0; i 0) + strm.PutCString (", "); + + DWARFFormValue form_value (NULL, header_data.atoms[i].form); + switch (header_data.atoms[i].type) + { + case eAtomTypeDIEOffset: // DIE offset, check form for encoding + strm.Printf ("{0x%8.8x}", hash_data.offset); + break; + + case eAtomTypeTag: // DW_TAG value for the DIE + { + const char *tag_cstr = lldb_private::DW_TAG_value_to_name (hash_data.tag); + if (tag_cstr) + strm.PutCString (tag_cstr); + else + strm.Printf ("DW_TAG_(0x%4.4x)", hash_data.tag); + } + break; + + case eAtomTypeTypeFlags: // Flags from enum TypeFlags + strm.Printf ("0x%2.2x", hash_data.type_flags); + if (hash_data.type_flags) + { + strm.PutCString (" ("); + if (hash_data.type_flags & eTypeFlagClassIsImplementation) + strm.PutCString (" implementation"); + strm.PutCString (" )"); + } + break; + + case eAtomTypeQualNameHash: // Flags from enum TypeFlags + strm.Printf ("0x%8.8x", hash_data.qualified_name_hash); + break; + + default: + strm.Printf ("AtomType(0x%x)", header_data.atoms[i].type); + break; + } + } +} + +DWARFMappedHash::MemoryTable::MemoryTable (lldb_private::DWARFDataExtractor &table_data, + const lldb_private::DWARFDataExtractor &string_table, + const char *name) : + MappedHash::MemoryTable (table_data), + m_data (table_data), + m_string_table (string_table), + m_name (name) +{ +} + +const char * +DWARFMappedHash::MemoryTable::GetStringForKeyType (KeyType key) const +{ + // The key in the DWARF table is the .debug_str offset for the string + return m_string_table.PeekCStr (key); +} + +bool +DWARFMappedHash::MemoryTable::ReadHashData (uint32_t hash_data_offset, HashData &hash_data) const +{ + lldb::offset_t offset = hash_data_offset; + offset += 4; // Skip string table offset that contains offset of hash name in .debug_str + const uint32_t count = m_data.GetU32 (&offset); + if (count > 0) + { + hash_data.resize(count); + for (uint32_t i=0; i 0 && m_data.ValidOffsetForDataOfSize (*hash_data_offset_ptr, min_total_hash_data_size)) + { + // We have at least one HashData entry, and we have enough + // data to parse at least "count" HashData entries. + + // First make sure the entire C string matches... + const bool match = strcmp (name, strp_cstr) == 0; + + if (!match && m_header.header_data.HashDataHasFixedByteSize()) + { + // If the string doesn't match and we have fixed size data, + // we can just add the total byte size of all HashData objects + // to the hash data offset and be done... + *hash_data_offset_ptr += min_total_hash_data_size; + } + else + { + // If the string does match, or we don't have fixed size data + // then we need to read the hash data as a stream. If the + // string matches we also append all HashData objects to the + // value array. + for (uint32_t i=0; i 0 && m_data.ValidOffsetForDataOfSize (*hash_data_offset_ptr, min_total_hash_data_size)) + { + const bool match = regex.Execute(strp_cstr); + + if (!match && m_header.header_data.HashDataHasFixedByteSize()) + { + // If the regex doesn't match and we have fixed size data, + // we can just add the total byte size of all HashData objects + // to the hash data offset and be done... + *hash_data_offset_ptr += min_total_hash_data_size; + } + else + { + // If the string does match, or we don't have fixed size data + // then we need to read the hash data as a stream. If the + // string matches we also append all HashData objects to the + // value array. + for (uint32_t i=0; iTag()), type->GetName().AsCString()); assert (clang_type); - DWARFDebugInfoEntry::Attributes attributes; - - TypeSystem *type_system = GetTypeSystemForLanguage(dwarf_cu->GetLanguageType()); - if (type_system) return type_system->CompleteTypeFromDWARF (this, dwarf_cu, die, type, clang_type); @@ -2550,30 +2546,19 @@ // we can pull out the mips linkage name attribute: Mangled best_name; - DWARFDebugInfoEntry::Attributes attributes; - DWARFFormValue form_value; - die->GetAttributes(this, dwarf_cu, DWARFFormValue::FixedFormSizes(), attributes); - uint32_t idx = attributes.FindAttributeIndex(DW_AT_MIPS_linkage_name); - if (idx == UINT32_MAX) - idx = attributes.FindAttributeIndex(DW_AT_linkage_name); - if (idx != UINT32_MAX) - { - if (attributes.ExtractFormValueAtIndex(this, idx, form_value)) - { - const char *mangled_name = form_value.AsCString(this); - if (mangled_name) - best_name.SetValue (ConstString(mangled_name), true); - } - } + const char* name = nullptr; + + name = die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_MIPS_linkage_name, nullptr); + if (name == nullptr) + name = die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_linkage_name, nullptr); + if (name != nullptr) + best_name.SetValue(ConstString(name), true); if (!best_name) { - idx = attributes.FindAttributeIndex(DW_AT_name); - if (idx != UINT32_MAX && attributes.ExtractFormValueAtIndex(this, idx, form_value)) - { - const char *name = form_value.AsCString(this); - best_name.SetValue (ConstString(name), false); - } + name = die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_name, nullptr); + if (name != nullptr) + best_name.SetValue(ConstString(name), false); } const LanguageType cu_language = const_cast(dwarf_cu)->GetLanguageType(); Index: source/Symbol/ClangASTContext.cpp =================================================================== --- source/Symbol/ClangASTContext.cpp +++ source/Symbol/ClangASTContext.cpp @@ -9029,7 +9029,6 @@ DW_TAG_value_to_name(tag), type->GetName().AsCString()); assert (clang_type); - DWARFDebugInfoEntry::Attributes attributes; switch (tag) {