Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h @@ -12,10 +12,15 @@ #include "DWARFUnit.h" #include "llvm/Support/Error.h" +namespace lldb_private { +class DWARFContext; +} + class DWARFCompileUnit : public DWARFUnit { public: static llvm::Expected extract(SymbolFileDWARF *dwarf2Data, + lldb_private::DWARFContext *dwarf_context, const lldb_private::DWARFDataExtractor &debug_info, lldb::offset_t *offset_ptr); void Dump(lldb_private::Stream *s) const override; @@ -39,7 +44,8 @@ uint32_t GetHeaderByteSize() const override; private: - DWARFCompileUnit(SymbolFileDWARF *dwarf2Data); + DWARFCompileUnit(SymbolFileDWARF *dwarf2Data, + lldb_private::DWARFContext *dwarf_context); DISALLOW_COPY_AND_ASSIGN(DWARFCompileUnit); }; Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -15,17 +15,18 @@ using namespace lldb; using namespace lldb_private; -DWARFCompileUnit::DWARFCompileUnit(SymbolFileDWARF *dwarf2Data) - : DWARFUnit(dwarf2Data) {} +DWARFCompileUnit::DWARFCompileUnit(SymbolFileDWARF *dwarf2Data, + DWARFContext *dwarf_context) + : DWARFUnit(dwarf2Data, dwarf_context) {} -llvm::Expected -DWARFCompileUnit::extract(SymbolFileDWARF *dwarf2Data, - const DWARFDataExtractor &debug_info, - lldb::offset_t *offset_ptr) { +llvm::Expected DWARFCompileUnit::extract( + SymbolFileDWARF *dwarf2Data, DWARFContext *dwarf_context, + const DWARFDataExtractor &debug_info, lldb::offset_t *offset_ptr) { assert(debug_info.ValidOffset(*offset_ptr)); // std::make_shared would require the ctor to be public. - std::shared_ptr cu_sp(new DWARFCompileUnit(dwarf2Data)); + std::shared_ptr cu_sp( + new DWARFCompileUnit(dwarf2Data, dwarf_context)); cu_sp->m_offset = *offset_ptr; Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h @@ -19,11 +19,33 @@ private: Module &m_module; llvm::Optional m_data_debug_aranges; + llvm::Optional m_data_debug_frame; + llvm::Optional m_data_debug_line; + llvm::Optional m_data_debug_line_str; + llvm::Optional m_data_debug_macro; + llvm::Optional m_data_debug_loc; + llvm::Optional m_data_debug_loclists; + llvm::Optional m_data_debug_ranges; + llvm::Optional m_data_debug_rnglists; + llvm::Optional m_data_debug_types; + llvm::Optional m_data_gnu_debug_altlink; public: explicit DWARFContext(Module &module); const DWARFDataExtractor *getOrLoadArangesData(); + const DWARFDataExtractor *getOrLoadDebugLineData(); + const DWARFDataExtractor *getOrLoadDebugLineStrData(); + const DWARFDataExtractor *getOrLoadDebugMacroData(); + const DWARFDataExtractor *getOrLoadDebugLocData(); + const DWARFDataExtractor *getOrLoadDebugLoclistData(); + const DWARFDataExtractor *getOrLoadDebugRangesData(); + const DWARFDataExtractor *getOrLoadDebugRnglistsData(); + const DWARFDataExtractor *getOrLoadDebugFrameData(); + const DWARFDataExtractor *getOrLoadDebugTypesData(); + const DWARFDataExtractor *getOrLoadGnuDebugAltlinkData(); + + const DWARFDataExtractor *getOrLoadBestDebugLocData(); }; } // namespace lldb_private Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp @@ -14,6 +14,13 @@ using namespace lldb_private; static const DWARFDataExtractor * +GetPointerOrNull(const llvm::Optional &extractor) { + if (!extractor.hasValue()) + return nullptr; + return extractor.getPointer(); +} + +static const DWARFDataExtractor * LoadOrGetSection(Module &module, SectionType section_type, llvm::Optional &extractor) { if (extractor.hasValue()) @@ -41,3 +48,61 @@ return LoadOrGetSection(m_module, eSectionTypeDWARFDebugAranges, m_data_debug_aranges); } + +const DWARFDataExtractor *DWARFContext::getOrLoadDebugLineData() { + return LoadOrGetSection(m_module, eSectionTypeDWARFDebugLine, + m_data_debug_line); +} + +const DWARFDataExtractor *DWARFContext::getOrLoadDebugLineStrData() { + return LoadOrGetSection(m_module, eSectionTypeDWARFDebugLineStr, + m_data_debug_line_str); +} + +const DWARFDataExtractor *DWARFContext::getOrLoadDebugMacroData() { + return LoadOrGetSection(m_module, eSectionTypeDWARFDebugMacro, + m_data_debug_macro); +} + +const DWARFDataExtractor *DWARFContext::getOrLoadDebugLocData() { + return LoadOrGetSection(m_module, eSectionTypeDWARFDebugLoc, + m_data_debug_loc); +} + +const DWARFDataExtractor *DWARFContext::getOrLoadDebugLoclistData() { + return LoadOrGetSection(m_module, eSectionTypeDWARFDebugLocLists, + m_data_debug_loclists); +} + +const DWARFDataExtractor *DWARFContext::getOrLoadDebugRangesData() { + return LoadOrGetSection(m_module, eSectionTypeDWARFDebugRanges, + m_data_debug_ranges); +} + +const DWARFDataExtractor *DWARFContext::getOrLoadDebugRnglistsData() { + return LoadOrGetSection(m_module, eSectionTypeDWARFDebugRngLists, + m_data_debug_rnglists); +} + +const DWARFDataExtractor *DWARFContext::getOrLoadDebugFrameData() { + return LoadOrGetSection(m_module, eSectionTypeDWARFDebugFrame, + m_data_debug_frame); +} + +const DWARFDataExtractor *DWARFContext::getOrLoadDebugTypesData() { + return LoadOrGetSection(m_module, eSectionTypeDWARFDebugTypes, + m_data_debug_types); +} + +const DWARFDataExtractor *DWARFContext::getOrLoadGnuDebugAltlinkData() { + return LoadOrGetSection(m_module, eSectionTypeDWARFGNUDebugAltLink, + m_data_gnu_debug_altlink); +} + +const DWARFDataExtractor *DWARFContext::getOrLoadBestDebugLocData() { + const DWARFDataExtractor *loc = getOrLoadDebugLocData(); + if (loc) + return loc; + + return getOrLoadDebugLoclistData(); +} Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp @@ -332,8 +332,9 @@ lldb_private::DWARFExpression *frame_base) const { if (IsValid()) { return m_die->GetDIENamesAndRanges( - GetDWARF(), GetCU(), name, mangled, ranges, decl_file, decl_line, - decl_column, call_file, call_line, call_column, frame_base); + GetDWARF(), GetDWARF()->GetDWARFContext(), GetCU(), name, mangled, + ranges, decl_file, decl_line, decl_column, call_file, call_line, + call_column, frame_base); } else return false; } Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp @@ -91,8 +91,8 @@ const auto &debug_info_data = m_dwarf2Data->get_debug_info_data(); while (debug_info_data.ValidOffset(offset)) { - llvm::Expected cu_sp = - DWARFCompileUnit::extract(m_dwarf2Data, debug_info_data, &offset); + llvm::Expected cu_sp = DWARFCompileUnit::extract( + m_dwarf2Data, &m_context, debug_info_data, &offset); if (!cu_sp) { // FIXME: Propagate this error up. Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h @@ -158,22 +158,23 @@ static bool OffsetLessThan(const DWARFDebugInfoEntry &a, const DWARFDebugInfoEntry &b); - void Dump(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, + void Dump(SymbolFileDWARF *dwarf2Data, + lldb_private::DWARFContext *dwarf_context, const DWARFUnit *cu, lldb_private::Stream &s, uint32_t recurse_depth) const; static void - DumpAttribute(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, + DumpAttribute(SymbolFileDWARF *dwarf2Data, + lldb_private::DWARFContext *dwarf_context, const DWARFUnit *cu, const lldb_private::DWARFDataExtractor &debug_info_data, lldb::offset_t *offset_ptr, lldb_private::Stream &s, dw_attr_t attr, DWARFFormValue &form_value); - bool - GetDIENamesAndRanges(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, - const char *&name, const char *&mangled, - DWARFRangeList &rangeList, int &decl_file, - int &decl_line, int &decl_column, int &call_file, - int &call_line, int &call_column, - lldb_private::DWARFExpression *frame_base = NULL) const; + bool GetDIENamesAndRanges( + SymbolFileDWARF *dwarf2Data, lldb_private::DWARFContext *dwarf_context, + const DWARFUnit *cu, const char *&name, const char *&mangled, + DWARFRangeList &rangeList, int &decl_file, int &decl_line, + int &decl_column, int &call_file, int &call_line, int &call_column, + lldb_private::DWARFExpression *frame_base = NULL) const; const DWARFAbbreviationDeclaration * GetAbbreviationDeclarationPtr(SymbolFileDWARF *dwarf2Data, Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -377,19 +377,20 @@ // DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges attributes. //---------------------------------------------------------------------- bool DWARFDebugInfoEntry::GetDIENamesAndRanges( - SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, const char *&name, - const char *&mangled, DWARFRangeList &ranges, int &decl_file, - int &decl_line, int &decl_column, int &call_file, int &call_line, - int &call_column, DWARFExpression *frame_base) const { + SymbolFileDWARF *dwarf2Data, DWARFContext *dwarf_context, + const DWARFUnit *cu, const char *&name, const char *&mangled, + DWARFRangeList &ranges, int &decl_file, int &decl_line, int &decl_column, + int &call_file, int &call_line, int &call_column, + DWARFExpression *frame_base) const { if (dwarf2Data == nullptr) return false; SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile(); if (dwo_symbol_file) return GetDIENamesAndRanges( - dwo_symbol_file, dwo_symbol_file->GetCompileUnit(), name, mangled, - ranges, decl_file, decl_line, decl_column, call_file, call_line, - call_column, frame_base); + dwo_symbol_file, dwarf_context, dwo_symbol_file->GetCompileUnit(), name, + mangled, ranges, decl_file, decl_line, decl_column, call_file, + call_line, call_column, frame_base); dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; @@ -515,15 +516,18 @@ frame_base->SetOpcodeData(module, debug_info_data, block_offset, block_length); } else { - const DWARFDataExtractor &debug_loc_data = - dwarf2Data->DebugLocData(); + const DWARFDataExtractor *debug_loc = + dwarf_context->getOrLoadBestDebugLocData(); + if (!debug_loc) + break; + const dw_offset_t debug_loc_offset = form_value.Unsigned(); size_t loc_list_length = DWARFExpression::LocationListSize( - cu, debug_loc_data, debug_loc_offset); + cu, *debug_loc, debug_loc_offset); if (loc_list_length > 0) { - frame_base->SetOpcodeData(module, debug_loc_data, - debug_loc_offset, loc_list_length); + frame_base->SetOpcodeData(module, *debug_loc, debug_loc_offset, + loc_list_length); if (lo_pc != LLDB_INVALID_ADDRESS) { assert(lo_pc >= cu->GetBaseAddress()); frame_base->SetLocationListSlide(lo_pc - @@ -564,8 +568,9 @@ DWARFDIE die = dwarf2Data->GetDIE(die_ref); if (die) die.GetDIE()->GetDIENamesAndRanges( - die.GetDWARF(), die.GetCU(), name, mangled, ranges, decl_file, - decl_line, decl_column, call_file, call_line, call_column); + die.GetDWARF(), die.GetDWARF()->GetDWARFContext(), die.GetCU(), + name, mangled, ranges, decl_file, decl_line, decl_column, + call_file, call_line, call_column); } } } @@ -579,6 +584,7 @@ // stream. //---------------------------------------------------------------------- void DWARFDebugInfoEntry::Dump(SymbolFileDWARF *dwarf2Data, + lldb_private::DWARFContext *dwarf_context, const DWARFUnit *cu, Stream &s, uint32_t recurse_depth) const { const DWARFDataExtractor &debug_info_data = cu->GetData(); @@ -606,8 +612,8 @@ dw_attr_t attr; abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value); - DumpAttribute(dwarf2Data, cu, debug_info_data, &offset, s, attr, - form_value); + DumpAttribute(dwarf2Data, dwarf_context, cu, debug_info_data, &offset, + s, attr, form_value); } const DWARFDebugInfoEntry *child = GetFirstChild(); @@ -615,7 +621,7 @@ s.IndentMore(); while (child) { - child->Dump(dwarf2Data, cu, s, recurse_depth - 1); + child->Dump(dwarf2Data, dwarf_context, cu, s, recurse_depth - 1); child = child->GetSibling(); } s.IndentLess(); @@ -638,9 +644,10 @@ // values for attributes, etc). //---------------------------------------------------------------------- void DWARFDebugInfoEntry::DumpAttribute( - SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, - const DWARFDataExtractor &debug_info_data, lldb::offset_t *offset_ptr, - Stream &s, dw_attr_t attr, DWARFFormValue &form_value) { + SymbolFileDWARF *dwarf2Data, lldb_private::DWARFContext *dwarf_context, + const DWARFUnit *cu, const DWARFDataExtractor &debug_info_data, + lldb::offset_t *offset_ptr, Stream &s, dw_attr_t attr, + DWARFFormValue &form_value) { bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm); s.Printf(" "); @@ -693,8 +700,13 @@ // the .debug_loc section that describes the value over it's lifetime uint64_t debug_loc_offset = form_value.Unsigned(); if (dwarf2Data) { - DWARFExpression::PrintDWARFLocationList( - s, cu, dwarf2Data->DebugLocData(), debug_loc_offset); + const DWARFDataExtractor *debug_loc_data = + dwarf_context->getOrLoadBestDebugLocData(); + if (!debug_loc_data) + break; + + DWARFExpression::PrintDWARFLocationList(s, cu, *debug_loc_data, + debug_loc_offset); } } } break; @@ -720,8 +732,12 @@ lldb::offset_t ranges_offset = GetRangesOffset(dwarf2Data->DebugRanges(), form_value); dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0; - DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(), - &ranges_offset, base_addr); + const DWARFDataExtractor *debug_ranges = + dwarf_context->getOrLoadDebugRangesData(); + if (!debug_ranges) + break; + + DWARFDebugRanges::Dump(s, *debug_ranges, &ranges_offset, base_addr); } break; default: Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h @@ -14,11 +14,16 @@ #include +namespace lldb_private { +class DWARFContext; +} + class DWARFDebugRangesBase { public: virtual ~DWARFDebugRangesBase(){}; - virtual void Extract(SymbolFileDWARF *dwarf2Data) = 0; + virtual void Extract(SymbolFileDWARF *dwarf2Data, + lldb_private::DWARFContext *dwarf_context) = 0; virtual bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset, DWARFRangeList &range_list) const = 0; virtual uint64_t GetOffset(size_t Index) const = 0; @@ -28,7 +33,8 @@ public: DWARFDebugRanges(); - void Extract(SymbolFileDWARF *dwarf2Data) override; + void Extract(SymbolFileDWARF *dwarf2Data, + lldb_private::DWARFContext *dwarf_context) override; bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset, DWARFRangeList &range_list) const override; uint64_t GetOffset(size_t Index) const override; @@ -38,8 +44,9 @@ lldb::offset_t *offset_ptr, dw_addr_t cu_base_addr); protected: - bool Extract(SymbolFileDWARF *dwarf2Data, lldb::offset_t *offset_ptr, - DWARFRangeList &range_list); + bool Extract(SymbolFileDWARF *dwarf2Data, + lldb_private::DWARFContext *dwarf_context, + lldb::offset_t *offset_ptr, DWARFRangeList &range_list); typedef std::map range_map; typedef range_map::iterator range_map_iterator; @@ -56,7 +63,8 @@ }; public: - void Extract(SymbolFileDWARF *dwarf2Data) override; + void Extract(SymbolFileDWARF *dwarf2Data, + lldb_private::DWARFContext *dwarf_context) override; bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset, DWARFRangeList &range_list) const override; uint64_t GetOffset(size_t Index) const override; Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp @@ -29,11 +29,12 @@ DWARFDebugRanges::DWARFDebugRanges() : m_range_map() {} -void DWARFDebugRanges::Extract(SymbolFileDWARF *dwarf2Data) { +void DWARFDebugRanges::Extract(SymbolFileDWARF *dwarf2Data, + lldb_private::DWARFContext *dwarf_context) { DWARFRangeList range_list; lldb::offset_t offset = 0; dw_offset_t debug_ranges_offset = offset; - while (Extract(dwarf2Data, &offset, range_list)) { + while (Extract(dwarf2Data, dwarf_context, &offset, range_list)) { range_list.Sort(); m_range_map[debug_ranges_offset] = range_list; debug_ranges_offset = offset; @@ -41,21 +42,24 @@ } bool DWARFDebugRanges::Extract(SymbolFileDWARF *dwarf2Data, + DWARFContext *dwarf_context, lldb::offset_t *offset_ptr, DWARFRangeList &range_list) { range_list.Clear(); lldb::offset_t range_offset = *offset_ptr; - const DWARFDataExtractor &debug_ranges_data = - dwarf2Data->get_debug_ranges_data(); - uint32_t addr_size = debug_ranges_data.GetAddressByteSize(); + const DWARFDataExtractor *debug_ranges = + dwarf_context->getOrLoadDebugRangesData(); + if (!debug_ranges) + return false; + + uint32_t addr_size = debug_ranges->GetAddressByteSize(); dw_addr_t base_addr = 0; dw_addr_t base_addr_marker = GetBaseAddressMarker(addr_size); - while ( - debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) { - dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); - dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); + while (debug_ranges->ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) { + dw_addr_t begin = debug_ranges->GetMaxU64(offset_ptr, addr_size); + dw_addr_t end = debug_ranges->GetMaxU64(offset_ptr, addr_size); if (!begin && !end) { // End of range list @@ -255,33 +259,38 @@ return false; } -void DWARFDebugRngLists::Extract(SymbolFileDWARF *dwarf2Data) { - const DWARFDataExtractor &data = dwarf2Data->get_debug_rnglists_data(); +void DWARFDebugRngLists::Extract(SymbolFileDWARF *dwarf2Data, + lldb_private::DWARFContext *dwarf_context) { + const DWARFDataExtractor *data = dwarf_context->getOrLoadDebugRnglistsData(); + if (!data) + return; + lldb::offset_t offset = 0; - uint64_t length = data.GetU32(&offset); + uint64_t length = data->GetU32(&offset); // FIXME: Handle DWARF64. lldb::offset_t end = offset + length; // Check version. - if (data.GetU16(&offset) < 5) + if (data->GetU16(&offset) < 5) return; - uint8_t addrSize = data.GetU8(&offset); + uint8_t addrSize = data->GetU8(&offset); // We do not support non-zero segment selector size. - if (data.GetU8(&offset) != 0) { + if (data->GetU8(&offset) != 0) { lldbassert(0 && "not implemented"); return; } - uint32_t offsetsAmount = data.GetU32(&offset); + uint32_t offsetsAmount = data->GetU32(&offset); for (uint32_t i = 0; i < offsetsAmount; ++i) - Offsets.push_back(data.GetMaxU64(&offset, 4)); + Offsets.push_back(data->GetMaxU64(&offset, 4)); lldb::offset_t listOffset = offset; std::vector rangeList; - while (offset < end && ExtractRangeList(data, addrSize, &offset, rangeList)) { + while (offset < end && + ExtractRangeList(*data, addrSize, &offset, rangeList)) { m_range_map[listOffset] = rangeList; listOffset = offset; } Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp @@ -489,16 +489,20 @@ } const char *DWARFFormValue::AsCString() const { + if (m_form == DW_FORM_string) + return m_value.value.cstr; + + DWARFContext *context = m_cu->GetDWARFContext(); SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF(); - if (m_form == DW_FORM_string) { - return m_value.value.cstr; - } else if (m_form == DW_FORM_strp) { - if (!symbol_file) + if (m_form == DW_FORM_strp) { + if (!context) return nullptr; return symbol_file->get_debug_str_data().PeekCStr(m_value.value.uval); - } else if (m_form == DW_FORM_GNU_str_index) { + } + + if (m_form == DW_FORM_GNU_str_index) { if (!symbol_file) return nullptr; @@ -526,8 +530,13 @@ return symbol_file->get_debug_str_data().PeekCStr(strOffset); } - if (m_form == DW_FORM_line_strp) - return symbol_file->get_debug_line_str_data().PeekCStr(m_value.value.uval); + if (m_form == DW_FORM_line_strp) { + const DWARFDataExtractor *extractor = context->getOrLoadDebugLineStrData(); + if (!extractor) + return nullptr; + + return extractor->PeekCStr(m_value.value.uval); + } return nullptr; } Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -21,6 +21,10 @@ class SymbolFileDWARF; class SymbolFileDWARFDwo; +namespace lldb_private { +class DWARFContext; +} + typedef std::shared_ptr DWARFUnitSP; enum DWARFProducer { @@ -147,6 +151,7 @@ bool Supports_unnamed_objc_bitfields(); SymbolFileDWARF *GetSymbolFileDWARF() const; + lldb_private::DWARFContext *GetDWARFContext() const; DWARFProducer GetProducer(); @@ -175,9 +180,10 @@ } protected: - DWARFUnit(SymbolFileDWARF *dwarf); + DWARFUnit(SymbolFileDWARF *dwarf, lldb_private::DWARFContext *dwarf_context); SymbolFileDWARF *m_dwarf = nullptr; + lldb_private::DWARFContext *m_dwarf_context = nullptr; std::unique_ptr m_dwo_symbol_file; const DWARFAbbreviationDeclarationSet *m_abbrevs = nullptr; void *m_user_data = nullptr; Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -29,8 +29,8 @@ extern int g_verbose; -DWARFUnit::DWARFUnit(SymbolFileDWARF *dwarf) - : m_dwarf(dwarf), m_cancel_scopes(false) {} +DWARFUnit::DWARFUnit(SymbolFileDWARF *dwarf, DWARFContext *dwarf_context) + : m_dwarf(dwarf), m_dwarf_context(dwarf_context), m_cancel_scopes(false) {} DWARFUnit::~DWARFUnit() {} @@ -609,6 +609,7 @@ } SymbolFileDWARF *DWARFUnit::GetSymbolFileDWARF() const { return m_dwarf; } +DWARFContext *DWARFUnit::GetDWARFContext() const { return m_dwarf_context; } void DWARFUnit::ParseProducerInfo() { m_producer_version_major = UINT32_MAX; Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -228,23 +228,9 @@ virtual const lldb_private::DWARFDataExtractor &get_debug_abbrev_data(); virtual const lldb_private::DWARFDataExtractor &get_debug_addr_data(); - const lldb_private::DWARFDataExtractor &get_debug_frame_data(); virtual const lldb_private::DWARFDataExtractor &get_debug_info_data(); - const lldb_private::DWARFDataExtractor &get_debug_line_data(); - const lldb_private::DWARFDataExtractor &get_debug_line_str_data(); - const lldb_private::DWARFDataExtractor &get_debug_macro_data(); - const lldb_private::DWARFDataExtractor &get_debug_loc_data(); - const lldb_private::DWARFDataExtractor &get_debug_loclists_data(); - const lldb_private::DWARFDataExtractor &get_debug_ranges_data(); - const lldb_private::DWARFDataExtractor &get_debug_rnglists_data(); virtual const lldb_private::DWARFDataExtractor &get_debug_str_data(); virtual const lldb_private::DWARFDataExtractor &get_debug_str_offsets_data(); - const lldb_private::DWARFDataExtractor &get_debug_types_data(); - const lldb_private::DWARFDataExtractor &get_apple_names_data(); - const lldb_private::DWARFDataExtractor &get_apple_types_data(); - const lldb_private::DWARFDataExtractor &get_apple_namespaces_data(); - const lldb_private::DWARFDataExtractor &get_apple_objc_data(); - const lldb_private::DWARFDataExtractor &get_gnu_debugaltlink(); DWARFDebugAbbrev *DebugAbbrev(); @@ -258,8 +244,6 @@ const DWARFDebugRangesBase *DebugRanges() const; - const lldb_private::DWARFDataExtractor &DebugLocData(); - static bool SupportedVersion(uint16_t version); DWARFDIE @@ -285,7 +269,7 @@ uint32_t cu_idx); virtual lldb_private::DWARFExpression::LocationListFormat - GetLocationListFormat() const; + GetLocationListFormat(); lldb::ModuleSP GetDWOModule(lldb_private::ConstString name); @@ -302,6 +286,7 @@ virtual std::unique_ptr GetDwoSymbolFileForCompileUnit(DWARFUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die); + lldb_private::DWARFContext *GetDWARFContext(); // For regular SymbolFileDWARF instances the method returns nullptr, // for the instances of the subclass SymbolFileDWARFDwo @@ -462,23 +447,9 @@ DWARFDataSegment m_data_debug_abbrev; DWARFDataSegment m_data_debug_addr; - DWARFDataSegment m_data_debug_frame; DWARFDataSegment m_data_debug_info; - DWARFDataSegment m_data_debug_line; - DWARFDataSegment m_data_debug_line_str; - DWARFDataSegment m_data_debug_macro; - DWARFDataSegment m_data_debug_loc; - DWARFDataSegment m_data_debug_loclists; - DWARFDataSegment m_data_debug_ranges; - DWARFDataSegment m_data_debug_rnglists; DWARFDataSegment m_data_debug_str; DWARFDataSegment m_data_debug_str_offsets; - DWARFDataSegment m_data_debug_types; - DWARFDataSegment m_data_apple_names; - DWARFDataSegment m_data_apple_types; - DWARFDataSegment m_data_apple_namespaces; - DWARFDataSegment m_data_apple_objc; - DWARFDataSegment m_data_gnu_debugaltlink; // The unique pointer items below are generated on demand if and when someone // accesses Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -54,6 +54,7 @@ #include "AppleDWARFIndex.h" #include "DWARFASTParser.h" #include "DWARFASTParserClang.h" +#include "DWARFContext.h" #include "DWARFDebugAbbrev.h" #include "DWARFDebugAranges.h" #include "DWARFDebugInfo.h" @@ -357,11 +358,8 @@ // contain the .o file index/ID m_debug_map_module_wp(), m_debug_map_symfile(NULL), m_context(*objfile->GetModule()), m_data_debug_abbrev(), - m_data_debug_frame(), m_data_debug_info(), m_data_debug_line(), - m_data_debug_macro(), m_data_debug_loc(), m_data_debug_ranges(), - m_data_debug_rnglists(), m_data_debug_str(), m_data_apple_names(), - m_data_apple_types(), m_data_apple_namespaces(), m_abbr(), m_info(), - m_line(), m_fetched_external_modules(false), + m_data_debug_info(), m_data_debug_str(), m_abbr(), m_info(), m_line(), + m_fetched_external_modules(false), m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate), m_ranges(), m_unique_ast_type_map() {} @@ -561,52 +559,10 @@ return GetCachedSectionData(eSectionTypeDWARFDebugAddr, m_data_debug_addr); } -const DWARFDataExtractor &SymbolFileDWARF::get_debug_frame_data() { - return GetCachedSectionData(eSectionTypeDWARFDebugFrame, m_data_debug_frame); -} - const DWARFDataExtractor &SymbolFileDWARF::get_debug_info_data() { return GetCachedSectionData(eSectionTypeDWARFDebugInfo, m_data_debug_info); } -const DWARFDataExtractor &SymbolFileDWARF::get_debug_line_data() { - return GetCachedSectionData(eSectionTypeDWARFDebugLine, m_data_debug_line); -} - -const DWARFDataExtractor &SymbolFileDWARF::get_debug_line_str_data() { - return GetCachedSectionData(eSectionTypeDWARFDebugLineStr, m_data_debug_line_str); -} - -const DWARFDataExtractor &SymbolFileDWARF::get_debug_macro_data() { - return GetCachedSectionData(eSectionTypeDWARFDebugMacro, m_data_debug_macro); -} - -const DWARFDataExtractor &SymbolFileDWARF::DebugLocData() { - const DWARFDataExtractor &debugLocData = get_debug_loc_data(); - if (debugLocData.GetByteSize() > 0) - return debugLocData; - return get_debug_loclists_data(); -} - -const DWARFDataExtractor &SymbolFileDWARF::get_debug_loc_data() { - return GetCachedSectionData(eSectionTypeDWARFDebugLoc, m_data_debug_loc); -} - -const DWARFDataExtractor &SymbolFileDWARF::get_debug_loclists_data() { - return GetCachedSectionData(eSectionTypeDWARFDebugLocLists, - m_data_debug_loclists); -} - -const DWARFDataExtractor &SymbolFileDWARF::get_debug_ranges_data() { - return GetCachedSectionData(eSectionTypeDWARFDebugRanges, - m_data_debug_ranges); -} - -const DWARFDataExtractor &SymbolFileDWARF::get_debug_rnglists_data() { - return GetCachedSectionData(eSectionTypeDWARFDebugRngLists, - m_data_debug_rnglists); -} - const DWARFDataExtractor &SymbolFileDWARF::get_debug_str_data() { return GetCachedSectionData(eSectionTypeDWARFDebugStr, m_data_debug_str); } @@ -616,32 +572,6 @@ m_data_debug_str_offsets); } -const DWARFDataExtractor &SymbolFileDWARF::get_debug_types_data() { - return GetCachedSectionData(eSectionTypeDWARFDebugTypes, m_data_debug_types); -} - -const DWARFDataExtractor &SymbolFileDWARF::get_apple_names_data() { - return GetCachedSectionData(eSectionTypeDWARFAppleNames, m_data_apple_names); -} - -const DWARFDataExtractor &SymbolFileDWARF::get_apple_types_data() { - return GetCachedSectionData(eSectionTypeDWARFAppleTypes, m_data_apple_types); -} - -const DWARFDataExtractor &SymbolFileDWARF::get_apple_namespaces_data() { - return GetCachedSectionData(eSectionTypeDWARFAppleNamespaces, - m_data_apple_namespaces); -} - -const DWARFDataExtractor &SymbolFileDWARF::get_apple_objc_data() { - return GetCachedSectionData(eSectionTypeDWARFAppleObjC, m_data_apple_objc); -} - -const DWARFDataExtractor &SymbolFileDWARF::get_gnu_debugaltlink() { - return GetCachedSectionData(eSectionTypeDWARFGNUDebugAltLink, - m_data_gnu_debugaltlink); -} - DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() { if (m_abbr) return m_abbr.get(); @@ -709,13 +639,13 @@ Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION, static_cast(this)); - if (get_debug_ranges_data().GetByteSize() > 0) - m_ranges.reset(new DWARFDebugRanges()); - else if (get_debug_rnglists_data().GetByteSize() > 0) - m_ranges.reset(new DWARFDebugRngLists()); + if (m_context.getOrLoadDebugRangesData()) + m_ranges = llvm::make_unique(); + else if (m_context.getOrLoadDebugRnglistsData()) + m_ranges = llvm::make_unique(); if (m_ranges) - m_ranges->Extract(this); + m_ranges->Extract(this, &m_context); } return m_ranges.get(); } @@ -871,23 +801,26 @@ FileSpecList &support_files) { ASSERT_MODULE_LOCK(this); DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); - if (dwarf_cu) { - const DWARFBaseDIE cu_die = dwarf_cu->GetUnitDIEOnly(); - - if (cu_die) { - const dw_offset_t stmt_list = cu_die.GetAttributeValueAsUnsigned( - DW_AT_stmt_list, DW_INVALID_OFFSET); - if (stmt_list != DW_INVALID_OFFSET) { - // All file indexes in DWARF are one based and a file of index zero is - // supposed to be the compile unit itself. - support_files.Append(comp_unit); - return DWARFDebugLine::ParseSupportFiles( - comp_unit.GetModule(), get_debug_line_data(), stmt_list, - support_files, dwarf_cu); - } - } - } - return false; + if (!dwarf_cu) + return false; + const DWARFBaseDIE cu_die = dwarf_cu->GetUnitDIEOnly(); + + if (!cu_die) + return false; + + const dw_offset_t stmt_list = + cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list, DW_INVALID_OFFSET); + if (stmt_list == DW_INVALID_OFFSET) + return false; + // All file indexes in DWARF are one based and a file of index zero is + // supposed to be the compile unit itself. + support_files.Append(comp_unit); + const DWARFDataExtractor *debug_line = m_context.getOrLoadDebugLineData(); + if (!debug_line) + return false; + + return DWARFDebugLine::ParseSupportFiles(comp_unit.GetModule(), *debug_line, + stmt_list, support_files, dwarf_cu); } bool SymbolFileDWARF::ParseIsOptimized(CompileUnit &comp_unit) { @@ -998,58 +931,64 @@ return true; DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); - if (dwarf_cu) { - const DWARFBaseDIE dwarf_cu_die = dwarf_cu->GetUnitDIEOnly(); - if (dwarf_cu_die) { - const dw_offset_t cu_line_offset = - dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list, - DW_INVALID_OFFSET); - if (cu_line_offset != DW_INVALID_OFFSET) { - std::unique_ptr line_table_up(new LineTable(&comp_unit)); - if (line_table_up) { - ParseDWARFLineTableCallbackInfo info; - info.line_table = line_table_up.get(); - - /* - * MIPS: - * The SymbolContext may not have a valid target, thus we may not be - * able - * to call Address::GetOpcodeLoadAddress() which would clear the bit - * #0 - * for MIPS. Use ArchSpec to clear the bit #0. - */ - switch (GetObjectFile()->GetArchitecture().GetMachine()) { - case llvm::Triple::mips: - case llvm::Triple::mipsel: - case llvm::Triple::mips64: - case llvm::Triple::mips64el: - info.addr_mask = ~((lldb::addr_t)1); - break; - default: - info.addr_mask = ~((lldb::addr_t)0); - break; - } + if (!dwarf_cu) + return false; - lldb::offset_t offset = cu_line_offset; - DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, - ParseDWARFLineTableCallback, - &info, dwarf_cu); - SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); - if (debug_map_symfile) { - // We have an object file that has a line table with addresses that - // are not linked. We need to link the line table and convert the - // addresses that are relative to the .o file into addresses for - // the main executable. - comp_unit.SetLineTable( - debug_map_symfile->LinkOSOLineTable(this, line_table_up.get())); - } else { - comp_unit.SetLineTable(line_table_up.release()); - return true; - } - } - } + const DWARFBaseDIE dwarf_cu_die = dwarf_cu->GetUnitDIEOnly(); + if (dwarf_cu_die) { + const dw_offset_t cu_line_offset = dwarf_cu_die.GetAttributeValueAsUnsigned( + DW_AT_stmt_list, DW_INVALID_OFFSET); + if (cu_line_offset == DW_INVALID_OFFSET) + return false; + + std::unique_ptr line_table_up(new LineTable(&comp_unit)); + if (!line_table_up) + return false; + + ParseDWARFLineTableCallbackInfo info; + info.line_table = line_table_up.get(); + + /* + * MIPS: + * The SymbolContext may not have a valid target, thus we may not be + * able + * to call Address::GetOpcodeLoadAddress() which would clear the bit + * #0 + * for MIPS. Use ArchSpec to clear the bit #0. + */ + switch (GetObjectFile()->GetArchitecture().GetMachine()) { + case llvm::Triple::mips: + case llvm::Triple::mipsel: + case llvm::Triple::mips64: + case llvm::Triple::mips64el: + info.addr_mask = ~((lldb::addr_t)1); + break; + default: + info.addr_mask = ~((lldb::addr_t)0); + break; } - } + + lldb::offset_t offset = cu_line_offset; + const DWARFDataExtractor *debug_line = m_context.getOrLoadDebugLineData(); + if (!debug_line) + return false; + + DWARFDebugLine::ParseStatementTable( + *debug_line, &offset, ParseDWARFLineTableCallback, &info, dwarf_cu); + SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); + if (debug_map_symfile) { + // We have an object file that has a line table with addresses that + // are not linked. We need to link the line table and convert the + // addresses that are relative to the .o file into addresses for + // the main executable. + comp_unit.SetLineTable( + debug_map_symfile->LinkOSOLineTable(this, line_table_up.get())); + } else { + comp_unit.SetLineTable(line_table_up.release()); + return true; + } + } + return false; } @@ -1059,18 +998,19 @@ if (iter != m_debug_macros_map.end()) return iter->second; - const DWARFDataExtractor &debug_macro_data = get_debug_macro_data(); - if (debug_macro_data.GetByteSize() == 0) - return DebugMacrosSP(); + const DWARFDataExtractor *debug_macro_data = + m_context.getOrLoadDebugMacroData(); + if (!debug_macro_data) + return nullptr; lldb_private::DebugMacrosSP debug_macros_sp(new lldb_private::DebugMacros()); m_debug_macros_map[*offset] = debug_macros_sp; const DWARFDebugMacroHeader &header = - DWARFDebugMacroHeader::ParseHeader(debug_macro_data, offset); - DWARFDebugMacroEntry::ReadMacroEntries(debug_macro_data, get_debug_str_data(), - header.OffsetIs64Bit(), offset, this, - debug_macros_sp); + DWARFDebugMacroHeader::ParseHeader(*debug_macro_data, offset); + DWARFDebugMacroEntry::ReadMacroEntries( + *debug_macro_data, get_debug_str_data(), header.OffsetIs64Bit(), offset, + this, debug_macros_sp); return debug_macros_sp; } @@ -1597,6 +1537,8 @@ return llvm::make_unique(dwo_obj_file, &dwarf_cu); } +DWARFContext *SymbolFileDWARF::GetDWARFContext() { return &m_context; } + void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() { if (m_fetched_external_modules) return; @@ -3302,13 +3244,17 @@ uint32_t block_length = form_value.Unsigned(); location.CopyOpcodeData(module, data, block_offset, block_length); } else { - const DWARFDataExtractor &debug_loc_data = DebugLocData(); + const DWARFDataExtractor *debug_loc_data = + m_context.getOrLoadBestDebugLocData(); + if (!debug_loc_data) + break; + const dw_offset_t debug_loc_offset = form_value.Unsigned(); size_t loc_list_length = DWARFExpression::LocationListSize( - die.GetCU(), debug_loc_data, debug_loc_offset); + die.GetCU(), *debug_loc_data, debug_loc_offset); if (loc_list_length > 0) { - location.CopyOpcodeData(module, debug_loc_data, + location.CopyOpcodeData(module, *debug_loc_data, debug_loc_offset, loc_list_length); assert(func_low_pc != LLDB_INVALID_ADDRESS); location.SetLocationListSlide( @@ -3818,9 +3764,8 @@ return m_debug_map_symfile; } -DWARFExpression::LocationListFormat -SymbolFileDWARF::GetLocationListFormat() const { - if (m_data_debug_loclists.m_data.GetByteSize() > 0) +DWARFExpression::LocationListFormat SymbolFileDWARF::GetLocationListFormat() { + if (m_context.getOrLoadDebugLoclistData()) return DWARFExpression::LocLists; return DWARFExpression::RegularLocationList; } Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h @@ -26,7 +26,7 @@ GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) override; lldb_private::DWARFExpression::LocationListFormat - GetLocationListFormat() const override; + GetLocationListFormat() override; size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name, DIEArray &method_die_offsets) override; Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp @@ -147,7 +147,7 @@ } DWARFExpression::LocationListFormat -SymbolFileDWARFDwo::GetLocationListFormat() const { +SymbolFileDWARFDwo::GetLocationListFormat() { return DWARFExpression::SplitDwarfLocationList; }