diff options
Diffstat (limited to 'source/Plugins/SymbolFile')
14 files changed, 289 insertions, 379 deletions
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp b/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp index bc2e7a62b76e..14fc2cea2329 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp @@ -73,14 +73,14 @@ DWARFAbbreviationDeclaration::Extract(const DWARFDataExtractor& data, lldb::offs void DWARFAbbreviationDeclaration::Dump(Stream *s) const { -// *ostrm_ptr << std::setfill(' ') << std::dec << '[' << std::setw(3) << std::right << m_code << ']' << ' ' << std::setw(30) << std::left << DW_TAG_value_to_name(m_tag) << DW_CHILDREN_value_to_name(m_has_children) << std::endl; -// -// DWARFAttribute::const_iterator pos; -// -// for (pos = m_attributes.begin(); pos != m_attributes.end(); ++pos) -// *ostrm_ptr << " " << std::setw(29) << std::left << DW_AT_value_to_name(pos->attr()) << ' ' << DW_FORM_value_to_name(pos->form()) << std::endl; -// -// *ostrm_ptr << std::endl; + s->Printf("Debug Abbreviation Declaration: code = 0x%4.4x, tag = %s, has_children = %s\n", m_code, DW_TAG_value_to_name(m_tag), DW_CHILDREN_value_to_name(m_has_children)); + + DWARFAttribute::const_iterator pos; + + for (pos = m_attributes.begin(); pos != m_attributes.end(); ++pos) + s->Printf(" attr = %s, form = %s\n", DW_AT_value_to_name(pos->get_attr()), DW_FORM_value_to_name(pos->get_form())); + + s->Printf("\n"); } diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp index b2e64ad9f8c8..067449a289be 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -49,7 +49,8 @@ DWARFCompileUnit::DWARFCompileUnit(SymbolFileDWARF* dwarf2Data) : m_producer (eProducerInvalid), m_producer_version_major (0), m_producer_version_minor (0), - m_producer_version_update (0) + m_producer_version_update (0), + m_is_dwarf64 (false) { } @@ -66,6 +67,7 @@ DWARFCompileUnit::Clear() m_func_aranges_ap.reset(); m_user_data = NULL; m_producer = eProducerInvalid; + m_is_dwarf64 = false; } bool @@ -79,9 +81,10 @@ DWARFCompileUnit::Extract(const DWARFDataExtractor &debug_info, lldb::offset_t * { dw_offset_t abbr_offset; const DWARFDebugAbbrev *abbr = m_dwarf2Data->DebugAbbrev(); - m_length = debug_info.GetU32(offset_ptr); + m_length = debug_info.GetDWARFInitialLength(offset_ptr); + m_is_dwarf64 = debug_info.IsDWARF64(); m_version = debug_info.GetU16(offset_ptr); - abbr_offset = debug_info.GetU32(offset_ptr); + abbr_offset = debug_info.GetDWARFOffset(offset_ptr); m_addr_size = debug_info.GetU8 (offset_ptr); bool length_OK = debug_info.ValidOffset(GetNextCompileUnitOffset()-1); @@ -168,7 +171,7 @@ DWARFCompileUnit::ExtractDIEsIfNeeded (bool cu_die_only) die_index_stack.reserve(32); die_index_stack.push_back(0); bool prev_die_had_children = false; - const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize()); + const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize(), m_is_dwarf64); while (offset < next_cu_offset && die.FastExtract (debug_info_data, this, fixed_form_sizes, &offset)) { @@ -347,6 +350,14 @@ DWARFCompileUnit::GetAddressByteSize(const DWARFCompileUnit* cu) return DWARFCompileUnit::GetDefaultAddressSize(); } +bool +DWARFCompileUnit::IsDWARF64(const DWARFCompileUnit* cu) +{ + if (cu) + return cu->IsDWARF64(); + return false; +} + uint8_t DWARFCompileUnit::GetDefaultAddressSize() { @@ -619,7 +630,7 @@ DWARFCompileUnit::Index (const uint32_t cu_idx, { const DWARFDataExtractor* debug_str = &m_dwarf2Data->get_debug_str_data(); - const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize()); + const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize(), m_is_dwarf64); Log *log (LogChannelDWARF::GetLogIfAll (DWARF_LOG_LOOKUPS)); @@ -761,7 +772,7 @@ DWARFCompileUnit::Index (const uint32_t cu_idx, case DW_AT_specification: if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) - specification_die_offset = form_value.Reference(this); + specification_die_offset = form_value.Reference(); break; } } @@ -1030,3 +1041,9 @@ DWARFCompileUnit::GetProducerVersionUpdate() return m_producer_version_update; } +bool +DWARFCompileUnit::IsDWARF64() const +{ + return m_is_dwarf64; +} + diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h index ed1894b8a9f6..3e904892dbd5 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h +++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h @@ -41,11 +41,11 @@ public: bool Verify(lldb_private::Stream *s) const; void Dump(lldb_private::Stream *s) const; dw_offset_t GetOffset() const { return m_offset; } - uint32_t Size() const { return 11; /* Size in bytes of the compile unit header */ } + uint32_t Size() const { return m_is_dwarf64 ? 23 : 11; /* Size in bytes of the compile unit header */ } bool ContainsDIEOffset(dw_offset_t die_offset) const { return die_offset >= GetFirstDIEOffset() && die_offset < GetNextCompileUnitOffset(); } dw_offset_t GetFirstDIEOffset() const { return m_offset + Size(); } - dw_offset_t GetNextCompileUnitOffset() const { return m_offset + m_length + 4; } - size_t GetDebugInfoSize() const { return m_length + 4 - Size(); /* Size in bytes of the .debug_info data associated with this compile unit. */ } + dw_offset_t GetNextCompileUnitOffset() const { return m_offset + m_length + (m_is_dwarf64 ? 12 : 4); } + size_t GetDebugInfoSize() const { return m_length + (m_is_dwarf64 ? 12 : 4) - Size(); /* Size in bytes of the .debug_info data associated with this compile unit. */ } uint32_t GetLength() const { return m_length; } uint16_t GetVersion() const { return m_version; } const DWARFAbbreviationDeclarationSet* GetAbbreviations() const { return m_abbrevs; } @@ -118,6 +118,9 @@ public: static uint8_t GetAddressByteSize(const DWARFCompileUnit* cu); + static bool + IsDWARF64(const DWARFCompileUnit* cu); + static uint8_t GetDefaultAddressSize(); @@ -183,6 +186,9 @@ public: uint32_t GetProducerVersionUpdate(); + bool + IsDWARF64() const; + protected: SymbolFileDWARF* m_dwarf2Data; const DWARFAbbreviationDeclarationSet *m_abbrevs; @@ -191,13 +197,14 @@ protected: std::unique_ptr<DWARFDebugAranges> m_func_aranges_ap; // A table similar to the .debug_aranges table, but this one points to the exact DW_TAG_subprogram DIEs dw_addr_t m_base_addr; dw_offset_t m_offset; - uint32_t m_length; + dw_offset_t m_length; uint16_t m_version; uint8_t m_addr_size; Producer m_producer; uint32_t m_producer_version_major; uint32_t m_producer_version_minor; uint32_t m_producer_version_update; + bool m_is_dwarf64; void ParseProducerInfo (); diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h b/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h index 6e5b974a71ff..ba2e8ad08acc 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h +++ b/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h @@ -33,6 +33,9 @@ public: size_t GetDWARFSizeofInitialLength() const { return m_is_dwarf64 ? 12 : 4; } + bool + IsDWARF64() const { return m_is_dwarf64; } + protected: mutable bool m_is_dwarf64; }; diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp index a8c553e2d2ca..393434800c01 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp @@ -555,8 +555,15 @@ static dw_offset_t DumpCallback if (dumpInfo->die_offset == DW_INVALID_OFFSET) { // We are dumping everything - cu->Dump(s); - return cu->GetFirstDIEOffset(); // Return true to parse all DIEs in this Compile Unit + if (cu) + { + cu->Dump(s); + return cu->GetFirstDIEOffset(); // Return true to parse all DIEs in this Compile Unit + } + else + { + return DW_INVALID_OFFSET; + } } else { @@ -568,7 +575,7 @@ static dw_offset_t DumpCallback // We are dumping only a single DIE possibly with it's children and // we must find it's compile unit before we can dump it properly - if (dumpInfo->die_offset < cu->GetFirstDIEOffset()) + if (cu && dumpInfo->die_offset < cu->GetFirstDIEOffset()) { // Not found, maybe the DIE offset provided wasn't correct? // *ostrm_ptr << "DIE at offset " << HEX32 << dumpInfo->die_offset << " was not found." << endl; @@ -577,7 +584,7 @@ static dw_offset_t DumpCallback else { // See if the DIE is in this compile unit? - if (dumpInfo->die_offset < cu->GetNextCompileUnitOffset()) + if (cu && dumpInfo->die_offset < cu->GetNextCompileUnitOffset()) { // This DIE is in this compile unit! if (s->GetVerbose()) @@ -590,7 +597,14 @@ static dw_offset_t DumpCallback else { // Skip to the next compile unit as the DIE isn't in the current one! - return cu->GetNextCompileUnitOffset(); + if (cu) + { + return cu->GetNextCompileUnitOffset(); + } + else + { + return DW_INVALID_OFFSET; + } } } } diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp index 856a7fa7a2ff..10b51ffe0a8a 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -88,9 +88,10 @@ DWARFDebugInfoEntry::Attributes::RemoveAttribute(dw_attr_t attr) bool DWARFDebugInfoEntry::Attributes::ExtractFormValueAtIndex (SymbolFileDWARF* dwarf2Data, uint32_t i, DWARFFormValue &form_value) const { + form_value.SetCompileUnit(CompileUnitAtIndex(i)); form_value.SetForm(FormAtIndex(i)); lldb::offset_t offset = DIEOffsetAtIndex(i); - return form_value.ExtractValue(dwarf2Data->get_debug_info_data(), &offset, CompileUnitAtIndex(i)); + return form_value.ExtractValue(dwarf2Data->get_debug_info_data(), &offset); } uint64_t @@ -107,7 +108,7 @@ DWARFDebugInfoEntry::Attributes::FormValueAsUnsignedAtIndex(SymbolFileDWARF* dwa { DWARFFormValue form_value; if (ExtractFormValueAtIndex(dwarf2Data, i, form_value)) - return form_value.Reference(CompileUnitAtIndex(i)); + return form_value.Reference(); return fail_value; } @@ -190,7 +191,7 @@ DWARFDebugInfoEntry::FastExtract if (cu->GetVersion() <= 2) form_size = cu->GetAddressByteSize(); else - form_size = 4; // 4 bytes for DWARF 32, 8 bytes for DWARF 64, but we don't support DWARF64 yet + form_size = cu->IsDWARF64() ? 8 : 4; break; // 0 sized form @@ -212,7 +213,6 @@ DWARFDebugInfoEntry::FastExtract break; // 4 byte values - case DW_FORM_strp : case DW_FORM_data4 : case DW_FORM_ref4 : form_size = 4; @@ -237,11 +237,12 @@ DWARFDebugInfoEntry::FastExtract form = debug_info_data.GetULEB128 (&offset); break; + case DW_FORM_strp : case DW_FORM_sec_offset : - if (cu->GetAddressByteSize () == 4) - debug_info_data.GetU32 (offset_ptr); - else + if (cu->IsDWARF64 ()) debug_info_data.GetU64 (offset_ptr); + else + debug_info_data.GetU32 (offset_ptr); break; default: @@ -284,7 +285,6 @@ DWARFDebugInfoEntry::Extract const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data(); // const DWARFDataExtractor& debug_str_data = dwarf2Data->get_debug_str_data(); const uint32_t cu_end_offset = cu->GetNextCompileUnitOffset(); - const uint8_t cu_addr_size = cu->GetAddressByteSize(); lldb::offset_t offset = *offset_ptr; // if (offset >= cu_end_offset) // Log::Error("DIE at offset 0x%8.8x is beyond the end of the current compile unit (0x%8.8x)", m_offset, cu_end_offset); @@ -319,8 +319,8 @@ DWARFDebugInfoEntry::Extract if (isCompileUnitTag && ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc))) { - DWARFFormValue form_value(form); - if (form_value.ExtractValue(debug_info_data, &offset, cu)) + DWARFFormValue form_value(cu, form); + if (form_value.ExtractValue(debug_info_data, &offset)) { if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc) ((DWARFCompileUnit*)cu)->SetBaseAddress(form_value.Unsigned()); @@ -348,13 +348,13 @@ DWARFDebugInfoEntry::Extract // Compile unit address sized values case DW_FORM_addr : - form_size = cu_addr_size; + form_size = cu->GetAddressByteSize(); break; case DW_FORM_ref_addr : if (cu->GetVersion() <= 2) - form_size = cu_addr_size; + form_size = cu->GetAddressByteSize(); else - form_size = 4; // 4 bytes for DWARF 32, 8 bytes for DWARF 64, but we don't support DWARF64 yet + form_size = cu->IsDWARF64() ? 8 : 4; break; // 0 sized form @@ -376,10 +376,6 @@ DWARFDebugInfoEntry::Extract break; // 4 byte values - case DW_FORM_strp : - form_size = 4; - break; - case DW_FORM_data4 : case DW_FORM_ref4 : form_size = 4; @@ -404,11 +400,12 @@ DWARFDebugInfoEntry::Extract form_is_indirect = true; break; + case DW_FORM_strp : case DW_FORM_sec_offset : - if (cu->GetAddressByteSize () == 4) - debug_info_data.GetU32 (offset_ptr); - else + if (cu->IsDWARF64 ()) debug_info_data.GetU64 (offset_ptr); + else + debug_info_data.GetU32 (offset_ptr); break; default: @@ -781,8 +778,8 @@ DWARFDebugInfoEntry::GetDIENamesAndRanges for (i=0; i<numAttributes; ++i) { abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form); - DWARFFormValue form_value(form); - if (form_value.ExtractValue(debug_info_data, &offset, cu)) + DWARFFormValue form_value(cu, form); + if (form_value.ExtractValue(debug_info_data, &offset)) { switch (attr) { @@ -832,11 +829,11 @@ DWARFDebugInfoEntry::GetDIENamesAndRanges break; case DW_AT_abstract_origin: - die_offsets.push_back(form_value.Reference(cu)); + die_offsets.push_back(form_value.Reference()); break; case DW_AT_specification: - die_offsets.push_back(form_value.Reference(cu)); + die_offsets.push_back(form_value.Reference()); break; case DW_AT_decl_file: @@ -1033,7 +1030,7 @@ DWARFDebugInfoEntry::DumpLocation const char *obj_file_name = NULL; ObjectFile *obj_file = dwarf2Data->GetObjectFile(); if (obj_file) - obj_file_name = obj_file->GetFileSpec().GetFilename().AsCString(); + obj_file_name = obj_file->GetFileSpec().GetFilename().AsCString("<Unknown>"); const char *die_name = GetName (dwarf2Data, cu); s.Printf ("0x%8.8x/0x%8.8x: %-30s (from %s in %s)", cu->GetOffset(), @@ -1077,9 +1074,9 @@ DWARFDebugInfoEntry::DumpAttribute s.Printf( "[%s", DW_FORM_value_to_name(form)); } - DWARFFormValue form_value(form); + DWARFFormValue form_value(cu, form); - if (!form_value.ExtractValue(debug_info_data, offset_ptr, cu)) + if (!form_value.ExtractValue(debug_info_data, offset_ptr)) return; if (show_form) @@ -1097,7 +1094,7 @@ DWARFDebugInfoEntry::DumpAttribute // Always dump form value if verbose is enabled if (verbose) { - form_value.Dump(s, debug_str_data, cu); + form_value.Dump(s, debug_str_data); } @@ -1130,7 +1127,7 @@ DWARFDebugInfoEntry::DumpAttribute if (blockData) { if (!verbose) - form_value.Dump(s, debug_str_data, cu); + form_value.Dump(s, debug_str_data); // Location description is inlined in data in the form value DWARFDataExtractor locationData(debug_info_data, (*offset_ptr) - form_value.Unsigned(), form_value.Unsigned()); @@ -1147,13 +1144,13 @@ DWARFDebugInfoEntry::DumpAttribute if (dwarf2Data) { if ( !verbose ) - form_value.Dump(s, debug_str_data, cu); + form_value.Dump(s, debug_str_data); DWARFLocationList::Dump(s, cu, dwarf2Data->get_debug_loc_data(), debug_loc_offset); } else { if ( !verbose ) - form_value.Dump(s, NULL, cu); + form_value.Dump(s, NULL); } } } @@ -1162,8 +1159,8 @@ DWARFDebugInfoEntry::DumpAttribute case DW_AT_abstract_origin: case DW_AT_specification: { - uint64_t abstract_die_offset = form_value.Reference(cu); - form_value.Dump(s, debug_str_data, cu); + uint64_t abstract_die_offset = form_value.Reference(); + form_value.Dump(s, debug_str_data); // *ostrm_ptr << HEX32 << abstract_die_offset << " ( "; if ( verbose ) s.PutCString(" ( "); GetName(dwarf2Data, cu, abstract_die_offset, s); @@ -1173,9 +1170,9 @@ DWARFDebugInfoEntry::DumpAttribute case DW_AT_type: { - uint64_t type_die_offset = form_value.Reference(cu); + uint64_t type_die_offset = form_value.Reference(); if (!verbose) - form_value.Dump(s, debug_str_data, cu); + form_value.Dump(s, debug_str_data); s.PutCString(" ( "); AppendTypeName(dwarf2Data, cu, type_die_offset, s); s.PutCString(" )"); @@ -1185,7 +1182,7 @@ DWARFDebugInfoEntry::DumpAttribute case DW_AT_ranges: { if ( !verbose ) - form_value.Dump(s, debug_str_data, cu); + form_value.Dump(s, debug_str_data); lldb::offset_t ranges_offset = form_value.Unsigned(); dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0; if (dwarf2Data) @@ -1195,7 +1192,7 @@ DWARFDebugInfoEntry::DumpAttribute default: if ( !verbose ) - form_value.Dump(s, debug_str_data, cu); + form_value.Dump(s, debug_str_data); break; } @@ -1226,13 +1223,12 @@ DWARFDebugInfoEntry::GetAttributes const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data(); if (fixed_form_sizes == NULL) - fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize(cu->GetAddressByteSize()); + fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize(cu->GetAddressByteSize(), cu->IsDWARF64()); const uint32_t num_attributes = abbrevDecl->NumAttributes(); uint32_t i; dw_attr_t attr; dw_form_t form; - DWARFFormValue form_value; for (i=0; i<num_attributes; ++i) { abbrevDecl->GetAttrAndFormByIndexUnchecked (i, attr, form); @@ -1259,11 +1255,11 @@ DWARFDebugInfoEntry::GetAttributes if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin)) { - form_value.SetForm(form); - if (form_value.ExtractValue(debug_info_data, &offset, cu)) + DWARFFormValue form_value (cu, form); + if (form_value.ExtractValue(debug_info_data, &offset)) { const DWARFDebugInfoEntry* die = NULL; - dw_offset_t die_offset = form_value.Reference(cu); + dw_offset_t die_offset = form_value.Reference(); if (cu->ContainsDIEOffset(die_offset)) { die = const_cast<DWARFCompileUnit*>(cu)->GetDIEPtr(die_offset); @@ -1331,8 +1327,9 @@ DWARFDebugInfoEntry::GetAttributeValue DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++), debug_info_data, &offset, cu); const dw_offset_t attr_offset = offset; + form_value.SetCompileUnit(cu); form_value.SetForm(abbrevDecl->GetFormByIndex(idx)); - if (form_value.ExtractValue(debug_info_data, &offset, cu)) + if (form_value.ExtractValue(debug_info_data, &offset)) { if (end_attr_offset_ptr) *end_attr_offset_ptr = offset; @@ -1423,7 +1420,7 @@ DWARFDebugInfoEntry::GetAttributeValueAsReference { DWARFFormValue form_value; if (GetAttributeValue(dwarf2Data, cu, attr, form_value)) - return form_value.Reference(cu); + return form_value.Reference(); return fail_value; } @@ -1590,7 +1587,7 @@ DWARFDebugInfoEntry::GetName if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value)) { DWARFCompileUnitSP cu_sp_ptr; - const DWARFDebugInfoEntry* die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(form_value.Reference(cu), &cu_sp_ptr); + const DWARFDebugInfoEntry* die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(form_value.Reference(), &cu_sp_ptr); if (die) return die->GetName(dwarf2Data, cu_sp_ptr.get()); } @@ -1661,7 +1658,7 @@ DWARFDebugInfoEntry::GetPubname // The specification DIE may be in another compile unit so we need // to get a die and its compile unit. DWARFCompileUnitSP cu_sp_ptr; - const DWARFDebugInfoEntry* die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(form_value.Reference(cu), &cu_sp_ptr); + const DWARFDebugInfoEntry* die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(form_value.Reference(), &cu_sp_ptr); if (die) return die->GetPubname(dwarf2Data, cu_sp_ptr.get()); } @@ -1798,7 +1795,7 @@ DWARFDebugInfoEntry::AppendTypeName DWARFFormValue form_value; if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_type, form_value)) { - uint64_t next_die_offset = form_value.Reference(cu); + uint64_t next_die_offset = form_value.Reference(); result = AppendTypeName(dwarf2Data, cu, next_die_offset, s); } diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp index 6a2649463b54..11589aede708 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp @@ -418,12 +418,16 @@ DWARFDebugLine::ParsePrologue(const DWARFDataExtractor& debug_line_data, lldb::o const char * s; prologue->total_length = debug_line_data.GetDWARFInitialLength(offset_ptr); prologue->version = debug_line_data.GetU16(offset_ptr); - if (prologue->version < 2 || prologue->version > 3) + if (prologue->version < 2 || prologue->version > 4) return false; prologue->prologue_length = debug_line_data.GetDWARFOffset(offset_ptr); const lldb::offset_t end_prologue_offset = prologue->prologue_length + *offset_ptr; prologue->min_inst_length = debug_line_data.GetU8(offset_ptr); + if (prologue->version >= 4) + prologue->maximum_operations_per_instruction = debug_line_data.GetU8(offset_ptr); + else + prologue->maximum_operations_per_instruction = 1; prologue->default_is_stmt = debug_line_data.GetU8(offset_ptr); prologue->line_base = debug_line_data.GetU8(offset_ptr); prologue->line_range = debug_line_data.GetU8(offset_ptr); @@ -486,13 +490,16 @@ DWARFDebugLine::ParseSupportFiles (const lldb::ModuleSP &module_sp, (void)debug_line_data.GetDWARFInitialLength(&offset); const char * s; uint32_t version = debug_line_data.GetU16(&offset); - if (version < 2 || version > 3) + if (version < 2 || version > 4) return false; const dw_offset_t end_prologue_offset = debug_line_data.GetDWARFOffset(&offset) + offset; - // Skip instruction length, default is stmt, line base, line range and - // opcode base, and all opcode lengths + // Skip instruction length, default is stmt, line base, line range offset += 4; + // For DWARF4, skip maximum operations per instruction + if (version >= 4) + offset += 1; + // Skip opcode base, and all opcode lengths const uint8_t opcode_base = debug_line_data.GetU8(&offset); offset += opcode_base - 1; std::vector<std::string> include_directories; @@ -650,7 +657,10 @@ DWARFDebugLine::ParseStatementTable // relocatable address. All of the other statement program opcodes // that affect the address register add a delta to it. This instruction // stores a relocatable value into it instead. - state.address = debug_line_data.GetAddress(offset_ptr); + if (arg_size == 4) + state.address = debug_line_data.GetU32(offset_ptr); + else // arg_size == 8 + state.address = debug_line_data.GetU64(offset_ptr); break; case DW_LNE_define_file: diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h index 0caaf596add5..7da0e76a22be 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h +++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h @@ -75,6 +75,7 @@ public: uint16_t version; // Version identifier for the statement information format. uint32_t prologue_length;// The number of bytes following the prologue_length field to the beginning of the first byte of the statement program itself. uint8_t min_inst_length;// The size in bytes of the smallest target machine instruction. Statement program opcodes that alter the address register first multiply their operands by this value. + uint8_t maximum_operations_per_instruction; // New in DWARF4. The maximum number of individual operations that may be encoded in an instruction. uint8_t default_is_stmt;// The initial value of theis_stmtregister. int8_t line_base; // This parameter affects the meaning of the special opcodes. See below. uint8_t line_range; // This parameter affects the meaning of the special opcodes. See below. diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp index 488e9820b6fa..8469b78d0dd5 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp @@ -87,7 +87,7 @@ DWARFDebugPubnames::GeneratePubnames(SymbolFileDWARF* dwarf2Data) DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx); - const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (cu->GetAddressByteSize()); + const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (cu->GetAddressByteSize(), cu->IsDWARF64()); bool clear_dies = cu->ExtractDIEsIfNeeded (false) > 1; diff --git a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp index ab8e68ab5516..a8c550e9176f 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp @@ -96,36 +96,92 @@ g_form_sizes_addr8[] = 8, // 0x20 DW_FORM_ref_sig8 }; +// Difference with g_form_sizes_addr8: +// DW_FORM_strp and DW_FORM_sec_offset are 8 instead of 4 +static uint8_t +g_form_sizes_addr8_dwarf64[] = +{ + 0, // 0x00 unused + 8, // 0x01 DW_FORM_addr + 0, // 0x02 unused + 0, // 0x03 DW_FORM_block2 + 0, // 0x04 DW_FORM_block4 + 2, // 0x05 DW_FORM_data2 + 4, // 0x06 DW_FORM_data4 + 8, // 0x07 DW_FORM_data8 + 0, // 0x08 DW_FORM_string + 0, // 0x09 DW_FORM_block + 0, // 0x0a DW_FORM_block1 + 1, // 0x0b DW_FORM_data1 + 1, // 0x0c DW_FORM_flag + 0, // 0x0d DW_FORM_sdata + 8, // 0x0e DW_FORM_strp + 0, // 0x0f DW_FORM_udata + 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for DWARF32, 8 bytes for DWARF32 in DWARF 3 and later + 1, // 0x11 DW_FORM_ref1 + 2, // 0x12 DW_FORM_ref2 + 4, // 0x13 DW_FORM_ref4 + 8, // 0x14 DW_FORM_ref8 + 0, // 0x15 DW_FORM_ref_udata + 0, // 0x16 DW_FORM_indirect + 8, // 0x17 DW_FORM_sec_offset + 0, // 0x18 DW_FORM_exprloc + 0, // 0x19 DW_FORM_flag_present + 0, // 0x1a + 0, // 0x1b + 0, // 0x1c + 0, // 0x1d + 0, // 0x1e + 0, // 0x1f + 8, // 0x20 DW_FORM_ref_sig8 +}; + const uint8_t * -DWARFFormValue::GetFixedFormSizesForAddressSize (uint8_t addr_size) +DWARFFormValue::GetFixedFormSizesForAddressSize (uint8_t addr_size, bool is_dwarf64) { - switch (addr_size) - { - case 4: return g_form_sizes_addr4; - case 8: return g_form_sizes_addr8; + if (!is_dwarf64) { + switch (addr_size) + { + case 4: return g_form_sizes_addr4; + case 8: return g_form_sizes_addr8; + } + } else { + if (addr_size == 8) + return g_form_sizes_addr8_dwarf64; + // is_dwarf64 && addr_size == 4 : no provider does this. } return NULL; } -DWARFFormValue::DWARFFormValue(dw_form_t form) : +DWARFFormValue::DWARFFormValue() : + m_cu (NULL), + m_form(0), + m_value() +{ +} + +DWARFFormValue::DWARFFormValue(const DWARFCompileUnit* cu, dw_form_t form) : + m_cu (cu), m_form(form), m_value() { } bool -DWARFFormValue::ExtractValue(const DWARFDataExtractor& data, lldb::offset_t* offset_ptr, const DWARFCompileUnit* cu) +DWARFFormValue::ExtractValue(const DWARFDataExtractor& data, lldb::offset_t* offset_ptr) { bool indirect = false; bool is_block = false; m_value.data = NULL; + uint8_t ref_addr_size; // Read the value for the form into value and follow and DW_FORM_indirect instances we run into do { indirect = false; switch (m_form) { - case DW_FORM_addr: m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::GetAddressByteSize(cu)); break; + case DW_FORM_addr: assert(m_cu); + m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::GetAddressByteSize(m_cu)); break; case DW_FORM_block2: m_value.value.uval = data.GetU16(offset_ptr); is_block = true; break; case DW_FORM_block4: m_value.value.uval = data.GetU32(offset_ptr); is_block = true; break; case DW_FORM_data2: m_value.value.uval = data.GetU16(offset_ptr); break; @@ -142,15 +198,17 @@ DWARFFormValue::ExtractValue(const DWARFDataExtractor& data, lldb::offset_t* off case DW_FORM_data1: m_value.value.uval = data.GetU8(offset_ptr); break; case DW_FORM_flag: m_value.value.uval = data.GetU8(offset_ptr); break; case DW_FORM_sdata: m_value.value.sval = data.GetSLEB128(offset_ptr); break; - case DW_FORM_strp: m_value.value.uval = data.GetU32(offset_ptr); break; + case DW_FORM_strp: assert(m_cu); + m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::IsDWARF64(m_cu) ? 8 : 4); break; // case DW_FORM_APPLE_db_str: case DW_FORM_udata: m_value.value.uval = data.GetULEB128(offset_ptr); break; - case DW_FORM_ref_addr: - if (cu->GetVersion() <= 2) - m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::GetAddressByteSize(cu)); - else - m_value.value.uval = data.GetU32(offset_ptr); // 4 for DWARF32, 8 for DWARF64, but we don't support DWARF64 yet - break; + case DW_FORM_ref_addr: assert(m_cu); + ref_addr_size = 4; + if (m_cu->GetVersion() <= 2) + ref_addr_size = m_cu->GetAddressByteSize(); + else + ref_addr_size = m_cu->IsDWARF64() ? 8 : 4; + m_value.value.uval = data.GetMaxU64(offset_ptr, ref_addr_size); break; case DW_FORM_ref1: m_value.value.uval = data.GetU8(offset_ptr); break; case DW_FORM_ref2: m_value.value.uval = data.GetU16(offset_ptr); break; case DW_FORM_ref4: m_value.value.uval = data.GetU32(offset_ptr); break; @@ -161,7 +219,8 @@ DWARFFormValue::ExtractValue(const DWARFDataExtractor& data, lldb::offset_t* off indirect = true; break; - case DW_FORM_sec_offset: m_value.value.uval = data.GetU32(offset_ptr); break; + case DW_FORM_sec_offset: assert(m_cu); + m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::IsDWARF64(m_cu) ? 8 : 4); break; case DW_FORM_flag_present: m_value.value.uval = 1; break; case DW_FORM_ref_sig8: m_value.value.uval = data.GetU64(offset_ptr); break; default: @@ -183,14 +242,15 @@ DWARFFormValue::ExtractValue(const DWARFDataExtractor& data, lldb::offset_t* off } bool -DWARFFormValue::SkipValue(const DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu) const +DWARFFormValue::SkipValue(const DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr) const { - return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, cu); + return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, m_cu); } bool DWARFFormValue::SkipValue(dw_form_t form, const DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu) { + uint8_t ref_addr_size; switch (form) { // Blocks if inlined data that have a length field and the data bytes @@ -212,10 +272,13 @@ DWARFFormValue::SkipValue(dw_form_t form, const DWARFDataExtractor& debug_info_d return true; case DW_FORM_ref_addr: + ref_addr_size = 4; + assert (cu); // CU must be valid for DW_FORM_ref_addr objects or we will get this wrong if (cu->GetVersion() <= 2) - *offset_ptr += DWARFCompileUnit::GetAddressByteSize(cu); + ref_addr_size = cu->GetAddressByteSize(); else - *offset_ptr += 4;// 4 for DWARF32, 8 for DWARF64, but we don't support DWARF64 yet + ref_addr_size = cu->IsDWARF64() ? 8 : 4; + *offset_ptr += ref_addr_size; return true; // 0 bytes values (implied from DW_FORM) @@ -237,11 +300,12 @@ DWARFFormValue::SkipValue(dw_form_t form, const DWARFDataExtractor& debug_info_d // 32 bit for DWARF 32, 64 for DWARF 64 case DW_FORM_sec_offset: - *offset_ptr += 4; + case DW_FORM_strp: + assert(cu); + *offset_ptr += (cu->IsDWARF64() ? 8 : 4); return true; // 4 byte values - case DW_FORM_strp: case DW_FORM_data4: case DW_FORM_ref4: *offset_ptr += 4; @@ -278,7 +342,7 @@ DWARFFormValue::SkipValue(dw_form_t form, const DWARFDataExtractor& debug_info_d void -DWARFFormValue::Dump(Stream &s, const DWARFDataExtractor* debug_str_data, const DWARFCompileUnit* cu) const +DWARFFormValue::Dump(Stream &s, const DWARFDataExtractor* debug_str_data) const { uint64_t uvalue = Unsigned(); bool cu_relative_offset = false; @@ -348,7 +412,8 @@ DWARFFormValue::Dump(Stream &s, const DWARFDataExtractor* debug_str_data, const case DW_FORM_ref_addr: { - if (cu->GetVersion() <= 2) + assert (m_cu); // CU must be valid for DW_FORM_ref_addr objects or we will get this wrong + if (m_cu->GetVersion() <= 2) s.Address(uvalue, sizeof (uint64_t) * 2); else s.Address(uvalue, 4 * 2);// 4 for DWARF32, 8 for DWARF64, but we don't support DWARF64 yet @@ -370,10 +435,11 @@ DWARFFormValue::Dump(Stream &s, const DWARFDataExtractor* debug_str_data, const if (cu_relative_offset) { + assert (m_cu); // CU must be valid for DW_FORM_ref forms that are compile unit relative or we will get this wrong if (verbose) s.PutCString(" => "); - s.Printf("{0x%8.8" PRIx64 "}", (uvalue + (cu ? cu->GetOffset() : 0))); + s.Printf("{0x%8.8" PRIx64 "}", uvalue + m_cu->GetOffset()); } } @@ -388,7 +454,7 @@ DWARFFormValue::AsCString(const DWARFDataExtractor* debug_str_data_ptr) const } uint64_t -DWARFFormValue::Reference(const DWARFCompileUnit* cu) const +DWARFFormValue::Reference() const { uint64_t die_offset = m_value.value.uval; switch (m_form) @@ -398,7 +464,8 @@ DWARFFormValue::Reference(const DWARFCompileUnit* cu) const case DW_FORM_ref4: case DW_FORM_ref8: case DW_FORM_ref_udata: - die_offset += (cu ? cu->GetOffset() : 0); + assert (m_cu); // CU must be valid for DW_FORM_ref forms that are compile unit relative or we will get this wrong + die_offset += m_cu->GetOffset(); break; default: @@ -429,32 +496,6 @@ DWARFFormValue::Reference (dw_offset_t base_offset) const return die_offset; } -//---------------------------------------------------------------------- -// Resolve any compile unit specific references so that we don't need -// the compile unit at a later time in order to work with the form -// value. -//---------------------------------------------------------------------- -bool -DWARFFormValue::ResolveCompileUnitReferences(const DWARFCompileUnit* cu) -{ - switch (m_form) - { - case DW_FORM_ref1: - case DW_FORM_ref2: - case DW_FORM_ref4: - case DW_FORM_ref8: - case DW_FORM_ref_udata: - m_value.value.uval += cu->GetOffset(); - m_form = DW_FORM_ref_addr; - return true; - break; - - default: - break; - } - - return false; -} const uint8_t* DWARFFormValue::BlockData() const @@ -496,7 +537,7 @@ DWARFFormValue::IsDataForm(const dw_form_t form) } int -DWARFFormValue::Compare (const DWARFFormValue& a_value, const DWARFFormValue& b_value, const DWARFCompileUnit* a_cu, const DWARFCompileUnit* b_cu, const DWARFDataExtractor* debug_str_data_ptr) +DWARFFormValue::Compare (const DWARFFormValue& a_value, const DWARFFormValue& b_value, const DWARFDataExtractor* debug_str_data_ptr) { dw_form_t a_form = a_value.Form(); dw_form_t b_form = b_value.Form(); @@ -577,8 +618,8 @@ DWARFFormValue::Compare (const DWARFFormValue& a_value, const DWARFFormValue& b_ case DW_FORM_ref8: case DW_FORM_ref_udata: { - uint64_t a = a_value.Reference(a_cu); - uint64_t b = b_value.Reference(b_cu); + uint64_t a = a_value.Reference(); + uint64_t b = b_value.Reference(); if (a < b) return -1; if (a > b) diff --git a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h index d6c580c7ab1b..392df26a088e 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h +++ b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h @@ -45,35 +45,34 @@ public: eValueTypeBlock }; - DWARFFormValue(dw_form_t form = 0); + DWARFFormValue(); + DWARFFormValue(const DWARFCompileUnit* cu, dw_form_t form); + const DWARFCompileUnit* GetCompileUnit () const { return m_cu; } + void SetCompileUnit (const DWARFCompileUnit* cu) { m_cu = cu; } dw_form_t Form() const { return m_form; } void SetForm(dw_form_t form) { m_form = form; } const ValueType& Value() const { return m_value; } - void Dump(lldb_private::Stream &s, const lldb_private::DWARFDataExtractor* debug_str_data, const DWARFCompileUnit* cu) const; + void Dump(lldb_private::Stream &s, const lldb_private::DWARFDataExtractor* debug_str_data) const; bool ExtractValue(const lldb_private::DWARFDataExtractor& data, - lldb::offset_t* offset_ptr, - const DWARFCompileUnit* cu); + lldb::offset_t* offset_ptr); bool IsInlinedCStr() const { return (m_value.data != NULL) && m_value.data == (const uint8_t*)m_value.value.cstr; } const uint8_t* BlockData() const; - uint64_t Reference(const DWARFCompileUnit* cu) const; + uint64_t Reference() const; uint64_t Reference (dw_offset_t offset) const; - bool ResolveCompileUnitReferences(const DWARFCompileUnit* cu); bool Boolean() const { return m_value.value.uval != 0; } uint64_t Unsigned() const { return m_value.value.uval; } void SetUnsigned(uint64_t uval) { m_value.value.uval = uval; } int64_t Signed() const { return m_value.value.sval; } void SetSigned(int64_t sval) { m_value.value.sval = sval; } const char* AsCString(const lldb_private::DWARFDataExtractor* debug_str_data_ptr) const; - bool SkipValue(const lldb_private::DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu) const; + bool SkipValue(const lldb_private::DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr) const; static bool SkipValue(const dw_form_t form, const lldb_private::DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu); -// static bool TransferValue(dw_form_t form, const lldb_private::DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu, BinaryStreamBuf& out_buff); -// static bool TransferValue(const DWARFFormValue& formValue, const DWARFCompileUnit* cu, BinaryStreamBuf& out_buff); -// static bool PutUnsigned(dw_form_t form, dw_offset_t offset, uint64_t value, BinaryStreamBuf& out_buff, const DWARFCompileUnit* cu, bool fixup_cu_relative_refs); static bool IsBlockForm(const dw_form_t form); static bool IsDataForm(const dw_form_t form); - static const uint8_t * GetFixedFormSizesForAddressSize (uint8_t addr_size); - static int Compare (const DWARFFormValue& a, const DWARFFormValue& b, const DWARFCompileUnit* a_cu, const DWARFCompileUnit* b_cu, const lldb_private::DWARFDataExtractor* debug_str_data_ptr); + static const uint8_t * GetFixedFormSizesForAddressSize (uint8_t addr_size, bool is_dwarf64); + static int Compare (const DWARFFormValue& a, const DWARFFormValue& b, const lldb_private::DWARFDataExtractor* debug_str_data_ptr); protected: + const DWARFCompileUnit* m_cu; // Compile unit for this form dw_form_t m_form; // Form for this value ValueType m_value; // Contains all data for the form }; diff --git a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h index ab0c37beeac9..f8a8cc60467d 100644 --- a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h +++ b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h @@ -442,9 +442,9 @@ struct DWARFMappedHash for (size_t i=0; i<num_atoms; ++i) { - DWARFFormValue form_value (header_data.atoms[i].form); + DWARFFormValue form_value (NULL, header_data.atoms[i].form); - if (!form_value.ExtractValue(data, offset_ptr, NULL)) + if (!form_value.ExtractValue(data, offset_ptr)) return false; switch (header_data.atoms[i].type) @@ -481,7 +481,7 @@ struct DWARFMappedHash if (i > 0) strm.PutCString (", "); - DWARFFormValue form_value (header_data.atoms[i].form); + DWARFFormValue form_value (NULL, header_data.atoms[i].form); switch (header_data.atoms[i].type) { case eAtomTypeDIEOffset: // DIE offset, check form for encoding diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 842260dbc3ba..b3a5476227f4 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1457,7 +1457,7 @@ SymbolFileDWARF::ParseTemplateDIE (DWARFCompileUnit* dwarf_cu, case DW_TAG_template_type_parameter: case DW_TAG_template_value_parameter: { - const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize()); + const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64()); DWARFDebugInfoEntry::Attributes attributes; const size_t num_attributes = die->GetAttributes (this, @@ -1486,7 +1486,7 @@ SymbolFileDWARF::ParseTemplateDIE (DWARFCompileUnit* dwarf_cu, case DW_AT_type: if (attributes.ExtractFormValueAtIndex(this, i, form_value)) { - const dw_offset_t type_die_offset = form_value.Reference(dwarf_cu); + const dw_offset_t type_die_offset = form_value.Reference(); lldb_type = ResolveTypeUID(type_die_offset); if (lldb_type) clang_type = lldb_type->GetClangForwardType(); @@ -1752,7 +1752,7 @@ SymbolFileDWARF::ParseChildMembers size_t count = 0; const DWARFDebugInfoEntry *die; - const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize()); + const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64()); uint32_t member_idx = 0; BitfieldInfo last_field_info; ModuleSP module = GetObjectFile()->GetModule(); @@ -1803,7 +1803,7 @@ SymbolFileDWARF::ParseChildMembers case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break; - case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; + case DW_AT_type: encoding_uid = form_value.Reference(); break; case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break; case DW_AT_bit_size: bit_size = form_value.Unsigned(); break; case DW_AT_byte_size: byte_size = form_value.Unsigned(); break; @@ -2201,7 +2201,7 @@ SymbolFileDWARF::ParseChildMembers case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; - case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; + case DW_AT_type: encoding_uid = form_value.Reference(); break; case DW_AT_data_member_location: if (form_value.BlockData()) { @@ -2990,7 +2990,7 @@ SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, if (block_die != NULL) sc.block = block.FindBlockByID (MakeUserID(block_die->GetOffset())); - else + else if (function_die != NULL) sc.block = block.FindBlockByID (MakeUserID(function_die->GetOffset())); } } @@ -3033,7 +3033,7 @@ SymbolFileDWARF::Index () m_indexed = true; Timer scoped_timer (__PRETTY_FUNCTION__, "SymbolFileDWARF::Index (%s)", - GetObjectFile()->GetFileSpec().GetFilename().AsCString()); + GetObjectFile()->GetFileSpec().GetFilename().AsCString("<Unknown>")); DWARFDebugInfo* debug_info = DebugInfo(); if (debug_info) @@ -3197,13 +3197,13 @@ SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const lldb_privat if (m_apple_names_ap.get()) { const char *name_cstr = name.GetCString(); - const char *base_name_start; - const char *base_name_end = NULL; + llvm::StringRef basename; + llvm::StringRef context; - if (!CPPLanguageRuntime::StripNamespacesFromVariableName(name_cstr, base_name_start, base_name_end)) - base_name_start = name_cstr; + if (!CPPLanguageRuntime::ExtractContextAndIdentifier(name_cstr, context, basename)) + basename = name_cstr; - m_apple_names_ap->FindByName (base_name_start, die_offsets); + m_apple_names_ap->FindByName (basename.data(), die_offsets); } } else @@ -3402,7 +3402,7 @@ SymbolFileDWARF::ResolveFunction (DWARFCompileUnit *cu, break; } } - assert (die->Tag() == DW_TAG_subprogram); + assert (die && die->Tag() == DW_TAG_subprogram); if (GetFunction (cu, die, sc)) { Address addr; @@ -4231,7 +4231,7 @@ SymbolFileDWARF::ParseChildParameters (const SymbolContext& sc, if (parent_die == NULL) return 0; - const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize()); + const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64()); size_t arg_idx = 0; const DWARFDebugInfoEntry *die; @@ -4266,7 +4266,7 @@ SymbolFileDWARF::ParseChildParameters (const SymbolContext& sc, case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break; - case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break; + case DW_AT_type: param_type_die_offset = form_value.Reference(); break; case DW_AT_artificial: is_artificial = form_value.Boolean(); break; case DW_AT_location: // if (form_value.BlockData()) @@ -4409,7 +4409,7 @@ SymbolFileDWARF::ParseChildEnumerators size_t enumerators_added = 0; const DWARFDebugInfoEntry *die; - const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize()); + const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64()); for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) { @@ -4488,7 +4488,7 @@ SymbolFileDWARF::ParseChildArrayInfo return; const DWARFDebugInfoEntry *die; - const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize()); + const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64()); for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) { const dw_tag_t tag = die->Tag(); @@ -4929,7 +4929,7 @@ SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry { DEBUG_PRINTF ("resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ")\n", MakeUserID(die->GetOffset()), - m_obj_file->GetFileSpec().GetFilename().AsCString(), + m_obj_file->GetFileSpec().GetFilename().AsCString("<Unknown>"), MakeUserID(type_die->GetOffset()), MakeUserID(type_cu->GetOffset())); @@ -5060,189 +5060,6 @@ SymbolFileDWARF::DIEDeclContextsMatch (DWARFCompileUnit* cu1, const DWARFDebugIn return true; } -// This function can be used when a DIE is found that is a forward declaration -// DIE and we want to try and find a type that has the complete definition. -// "cu" and "die" must be from this SymbolFileDWARF -TypeSP -SymbolFileDWARF::FindDefinitionTypeForDIE (DWARFCompileUnit* cu, - const DWARFDebugInfoEntry *die, - const ConstString &type_name) -{ - TypeSP type_sp; - -#if defined (LLDB_CONFIGURATION_DEBUG) - // You can't and shouldn't call this function with a compile unit from - // another SymbolFileDWARF instance. - assert (DebugInfo()->ContainsCompileUnit (cu)); -#endif - - if (cu == NULL || die == NULL || !type_name) - return type_sp; - - std::string qualified_name; - - Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION|DWARF_LOG_LOOKUPS)); - if (log) - { - die->GetQualifiedName(this, cu, qualified_name); - GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::FindDefinitionTypeForDIE(die=0x%8.8x (%s), name='%s')", - die->GetOffset(), - qualified_name.c_str(), - type_name.GetCString()); - } - - DIEArray die_offsets; - - if (m_using_apple_tables) - { - if (m_apple_types_ap.get()) - { - const bool has_tag = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeTag); - const bool has_qualified_name_hash = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeQualNameHash); - if (has_tag && has_qualified_name_hash) - { - if (qualified_name.empty()) - die->GetQualifiedName(this, cu, qualified_name); - - const uint32_t qualified_name_hash = MappedHash::HashStringUsingDJB (qualified_name.c_str()); - if (log) - GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTagAndQualifiedNameHash()"); - m_apple_types_ap->FindByNameAndTagAndQualifiedNameHash (type_name.GetCString(), die->Tag(), qualified_name_hash, die_offsets); - } - else if (has_tag) - { - if (log) - GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTag()"); - m_apple_types_ap->FindByNameAndTag (type_name.GetCString(), die->Tag(), die_offsets); - } - else - { - m_apple_types_ap->FindByName (type_name.GetCString(), die_offsets); - } - } - } - else - { - if (!m_indexed) - Index (); - - m_type_index.Find (type_name, die_offsets); - } - - const size_t num_matches = die_offsets.size(); - - const dw_tag_t die_tag = die->Tag(); - - DWARFCompileUnit* type_cu = NULL; - const DWARFDebugInfoEntry* type_die = NULL; - if (num_matches) - { - DWARFDebugInfo* debug_info = DebugInfo(); - for (size_t i=0; i<num_matches; ++i) - { - const dw_offset_t die_offset = die_offsets[i]; - type_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &type_cu); - - if (type_die) - { - bool try_resolving_type = false; - - // Don't try and resolve the DIE we are looking for with the DIE itself! - if (type_die != die) - { - const dw_tag_t type_die_tag = type_die->Tag(); - // Make sure the tags match - if (type_die_tag == die_tag) - { - // The tags match, lets try resolving this type - try_resolving_type = true; - } - else - { - // The tags don't match, but we need to watch our for a - // forward declaration for a struct and ("struct foo") - // ends up being a class ("class foo { ... };") or - // vice versa. - switch (type_die_tag) - { - case DW_TAG_class_type: - // We had a "class foo", see if we ended up with a "struct foo { ... };" - try_resolving_type = (die_tag == DW_TAG_structure_type); - break; - case DW_TAG_structure_type: - // We had a "struct foo", see if we ended up with a "class foo { ... };" - try_resolving_type = (die_tag == DW_TAG_class_type); - break; - default: - // Tags don't match, don't event try to resolve - // using this type whose name matches.... - break; - } - } - } - - if (try_resolving_type) - { - if (log) - { - std::string qualified_name; - type_die->GetQualifiedName(this, cu, qualified_name); - GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::FindDefinitionTypeForDIE(die=0x%8.8x, name='%s') trying die=0x%8.8x (%s)", - die->GetOffset(), - type_name.GetCString(), - type_die->GetOffset(), - qualified_name.c_str()); - } - - // Make sure the decl contexts match all the way up - if (DIEDeclContextsMatch(cu, die, type_cu, type_die)) - { - Type *resolved_type = ResolveType (type_cu, type_die, false); - if (resolved_type && resolved_type != DIE_IS_BEING_PARSED) - { - DEBUG_PRINTF ("resolved 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ") from %s to 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ")\n", - MakeUserID(die->GetOffset()), - MakeUserID(cu->GetOffset()), - m_obj_file->GetFileSpec().GetFilename().AsCString(), - MakeUserID(type_die->GetOffset()), - MakeUserID(type_cu->GetOffset())); - - m_die_to_type[die] = resolved_type; - type_sp = resolved_type->shared_from_this(); - break; - } - } - } - else - { - if (log) - { - std::string qualified_name; - type_die->GetQualifiedName(this, cu, qualified_name); - GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::FindDefinitionTypeForDIE(die=0x%8.8x, name='%s') ignoring die=0x%8.8x (%s)", - die->GetOffset(), - type_name.GetCString(), - type_die->GetOffset(), - qualified_name.c_str()); - } - } - } - else - { - if (m_using_apple_tables) - { - GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n", - die_offset, type_name.GetCString()); - } - } - - } - } - return type_sp; -} TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &dwarf_decl_ctx) @@ -5828,7 +5645,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, break; case DW_AT_byte_size: byte_size = form_value.Unsigned(); break; case DW_AT_encoding: encoding = form_value.Unsigned(); break; - case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; + case DW_AT_type: encoding_uid = form_value.Reference(); break; default: case DW_AT_sibling: break; @@ -6403,7 +6220,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, type_name_cstr = form_value.AsCString(&get_debug_str_data()); type_name_const_str.SetCString(type_name_cstr); break; - case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; + case DW_AT_type: encoding_uid = form_value.Reference(); break; case DW_AT_byte_size: byte_size = form_value.Unsigned(); break; case DW_AT_accessibility: break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; case DW_AT_declaration: break; //is_forward_declaration = form_value.Boolean(); break; @@ -6521,7 +6338,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, case DW_AT_linkage_name: case DW_AT_MIPS_linkage_name: break; // mangled = form_value.AsCString(&get_debug_str_data()); break; - case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break; + case DW_AT_type: type_die_offset = form_value.Reference(); break; case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; case DW_AT_declaration: break; // is_forward_declaration = form_value.Boolean(); break; case DW_AT_inline: is_inline = form_value.Boolean(); break; @@ -6541,15 +6358,15 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, break; case DW_AT_specification: - specification_die_offset = form_value.Reference(dwarf_cu); + specification_die_offset = form_value.Reference(); break; case DW_AT_abstract_origin: - abstract_origin_die_offset = form_value.Reference(dwarf_cu); + abstract_origin_die_offset = form_value.Reference(); break; case DW_AT_object_pointer: - object_pointer_die_offset = form_value.Reference(dwarf_cu); + object_pointer_die_offset = form_value.Reference(); break; case DW_AT_allocated: @@ -6985,7 +6802,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, type_name_const_str.SetCString(type_name_cstr); break; - case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break; + case DW_AT_type: type_die_offset = form_value.Reference(); break; case DW_AT_byte_size: break; // byte_size = form_value.Unsigned(); break; case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break; case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break; @@ -7019,17 +6836,26 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, byte_stride = element_type->GetByteSize(); ClangASTType array_element_type = element_type->GetClangForwardType(); uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride; - uint64_t num_elements = 0; - std::vector<uint64_t>::const_reverse_iterator pos; - std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend(); - for (pos = element_orders.rbegin(); pos != end; ++pos) + if (element_orders.size() > 0) + { + uint64_t num_elements = 0; + std::vector<uint64_t>::const_reverse_iterator pos; + std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend(); + for (pos = element_orders.rbegin(); pos != end; ++pos) + { + num_elements = *pos; + clang_type = ast.CreateArrayType (array_element_type, + num_elements, + is_vector); + array_element_type = clang_type; + array_element_bit_stride = num_elements ? + array_element_bit_stride * num_elements : + array_element_bit_stride; + } + } + else { - num_elements = *pos; - clang_type = ast.CreateArrayType (array_element_type, - num_elements, - is_vector); - array_element_type = clang_type; - array_element_bit_stride = num_elements ? array_element_bit_stride * num_elements : array_element_bit_stride; + clang_type = ast.CreateArrayType (array_element_type, 0, is_vector); } ConstString empty_name; type_sp.reset( new Type (MakeUserID(die->GetOffset()), @@ -7065,9 +6891,9 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, switch (attr) { case DW_AT_type: - type_die_offset = form_value.Reference(dwarf_cu); break; + type_die_offset = form_value.Reference(); break; case DW_AT_containing_type: - containing_type_die_offset = form_value.Reference(dwarf_cu); break; + containing_type_die_offset = form_value.Reference(); break; } } } @@ -7114,7 +6940,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, { symbol_context_scope = sc.comp_unit; } - else if (sc.function != NULL) + else if (sc.function != NULL && sc_parent_die) { symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset())); if (symbol_context_scope == NULL) @@ -7347,7 +7173,6 @@ SymbolFileDWARF::ParseVariableDIE const lldb::addr_t func_low_pc ) { - VariableSP var_sp (m_die_to_variable_sp[die]); if (var_sp) return var_sp; // Already been parsed! @@ -7380,6 +7205,7 @@ SymbolFileDWARF::ParseVariableDIE { dw_attr_t attr = attributes.AttributeAtIndex(i); DWARFFormValue form_value; + if (attributes.ExtractFormValueAtIndex(this, i, form_value)) { switch (attr) @@ -7390,7 +7216,7 @@ SymbolFileDWARF::ParseVariableDIE case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break; case DW_AT_linkage_name: case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break; - case DW_AT_type: type_uid = form_value.Reference(dwarf_cu); break; + case DW_AT_type: type_uid = form_value.Reference(); break; case DW_AT_external: is_external = form_value.Boolean(); break; case DW_AT_const_value: // If we have already found a DW_AT_location attribute, ignore this attribute. @@ -7409,7 +7235,7 @@ SymbolFileDWARF::ParseVariableDIE else if (DWARFFormValue::IsDataForm(form_value.Form())) { // Retrieve the value as a data expression. - const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize()); + const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (attributes.CompileUnitAtIndex(i)->GetAddressByteSize(), attributes.CompileUnitAtIndex(i)->IsDWARF64()); uint32_t data_offset = attributes.DIEOffsetAtIndex(i); uint32_t data_length = fixed_form_sizes[form_value.Form()]; if (data_length == 0) @@ -7417,7 +7243,7 @@ SymbolFileDWARF::ParseVariableDIE const uint8_t *data_pointer = form_value.BlockData(); if (data_pointer) { - data_length = form_value.Unsigned(); + form_value.Unsigned(); } else if (DWARFFormValue::IsDataForm(form_value.Form())) { @@ -7433,7 +7259,7 @@ SymbolFileDWARF::ParseVariableDIE // Retrieve the value as a string expression. if (form_value.Form() == DW_FORM_strp) { - const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize()); + const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (attributes.CompileUnitAtIndex(i)->GetAddressByteSize(), attributes.CompileUnitAtIndex(i)->IsDWARF64()); uint32_t data_offset = attributes.DIEOffsetAtIndex(i); uint32_t data_length = fixed_form_sizes[form_value.Form()]; location.CopyOpcodeData(module, debug_info_data, data_offset, data_length); @@ -7470,7 +7296,7 @@ SymbolFileDWARF::ParseVariableDIE { location.CopyOpcodeData(module, debug_loc_data, debug_loc_offset, loc_list_length); assert (func_low_pc != LLDB_INVALID_ADDRESS); - location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress()); + location.SetLocationListSlide (func_low_pc - attributes.CompileUnitAtIndex(i)->GetBaseAddress()); } } } diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index 178e5142d94b..230e1a5d3984 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -421,11 +421,6 @@ protected: const DWARFMappedHash::MemoryTable &memory_table, lldb_private::SymbolContextList& sc_list); - lldb::TypeSP FindDefinitionTypeForDIE ( - DWARFCompileUnit* dwarf_cu, - const DWARFDebugInfoEntry *die, - const lldb_private::ConstString &type_name); - lldb::TypeSP FindDefinitionTypeForDWARFDeclContext ( const DWARFDeclContext &die_decl_ctx); |