diff options
6 files changed, 77 insertions, 15 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp index c63def1dc20..b2e64ad9f8c 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -361,18 +361,43 @@ DWARFCompileUnit::SetDefaultAddressSize(uint8_t addr_size) void DWARFCompileUnit::BuildAddressRangeTable (SymbolFileDWARF* dwarf2Data, - DWARFDebugAranges* debug_aranges, - bool clear_dies_if_already_not_parsed) + DWARFDebugAranges* debug_aranges) { // This function is usually called if there in no .debug_aranges section // in order to produce a compile unit level set of address ranges that - // is accurate. If the DIEs weren't parsed, then we don't want all dies for - // all compile units to stay loaded when they weren't needed. So we can end - // up parsing the DWARF and then throwing them all away to keep memory usage - // down. + // is accurate. + + // First get the compile unit DIE only and check if it has a DW_AT_ranges + const DWARFDebugInfoEntry* die = GetCompileUnitDIEOnly(); + + const dw_offset_t cu_offset = GetOffset(); + if (die) + { + DWARFDebugRanges::RangeList ranges; + const size_t num_ranges = die->GetAttributeAddressRanges(dwarf2Data, this, ranges, false); + if (num_ranges > 0) + { + // This compile unit has DW_AT_ranges, assume this is correct if it + // is present since clang no longer makes .debug_aranges by default + // and it emits DW_AT_ranges for DW_TAG_compile_units. GCC also does + // this with recent GCC builds. + for (size_t i=0; i<num_ranges; ++i) + { + const DWARFDebugRanges::RangeList::Entry &range = ranges.GetEntryRef(i); + debug_aranges->AppendRange(cu_offset, range.GetRangeBase(), range.GetRangeEnd()); + } + + return; // We got all of our ranges from the DW_AT_ranges attribute + } + } + // We don't have a DW_AT_ranges attribute, so we need to parse the DWARF + + // If the DIEs weren't parsed, then we don't want all dies for all compile units + // to stay loaded when they weren't needed. So we can end up parsing the DWARF + // and then throwing them all away to keep memory usage down. const bool clear_dies = ExtractDIEsIfNeeded (false) > 1; - const DWARFDebugInfoEntry* die = DIE(); + die = DIE(); if (die) die->BuildAddressRangeTable(dwarf2Data, this, debug_aranges); @@ -397,7 +422,7 @@ DWARFCompileUnit::BuildAddressRangeTable (SymbolFileDWARF* dwarf2Data, for (uint32_t idx=0; idx<num_ranges; ++idx) { const LineTable::FileAddressRanges::Entry &range = file_ranges.GetEntryRef(idx); - debug_aranges->AppendRange(GetOffset(), range.GetRangeBase(), range.GetRangeEnd()); + debug_aranges->AppendRange(cu_offset, range.GetRangeBase(), range.GetRangeEnd()); printf ("0x%8.8x: [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", GetOffset(), range.GetRangeBase(), range.GetRangeEnd()); } } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h index 35597f38942..ed1894b8a9f 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h @@ -54,8 +54,7 @@ public: dw_addr_t GetBaseAddress() const { return m_base_addr; } void ClearDIEs(bool keep_compile_unit_die); void BuildAddressRangeTable (SymbolFileDWARF* dwarf2Data, - DWARFDebugAranges* debug_aranges, - bool clear_dies_if_already_not_parsed); + DWARFDebugAranges* debug_aranges); void SetBaseAddress(dw_addr_t base_addr) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp index 4f77bff86bd..be60321fb4e 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp @@ -93,14 +93,13 @@ DWARFDebugAranges::Generate(SymbolFileDWARF* dwarf2Data) DWARFDebugInfo* debug_info = dwarf2Data->DebugInfo(); if (debug_info) { - const bool clear_dies_if_already_not_parsed = true; uint32_t cu_idx = 0; const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits(); for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) { DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx); if (cu) - cu->BuildAddressRangeTable(dwarf2Data, this, clear_dies_if_already_not_parsed); + cu->BuildAddressRangeTable(dwarf2Data, this); } } return !IsEmpty(); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp index d4db12c17a4..b37bad9e5fb 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp @@ -79,7 +79,6 @@ DWARFDebugInfo::GetCompileUnitAranges () // Manually build arange data for everything that wasn't in the .debug_aranges table. bool printed = false; const size_t num_compile_units = GetNumCompileUnits(); - const bool clear_dies_if_already_not_parsed = true; for (size_t idx = 0; idx < num_compile_units; ++idx) { DWARFCompileUnit* cu = GetCompileUnitAtIndex(idx); @@ -94,7 +93,7 @@ DWARFDebugInfo::GetCompileUnitAranges () m_dwarf2Data->GetObjectFile()->GetFileSpec().GetPath().c_str()); printed = true; } - cu->BuildAddressRangeTable (m_dwarf2Data, m_cu_aranges_ap.get(), clear_dies_if_already_not_parsed); + cu->BuildAddressRangeTable (m_dwarf2Data, m_cu_aranges_ap.get()); } } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp index 37741eb1da9..856a7fa7a2f 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -1485,6 +1485,40 @@ DWARFDebugInfoEntry::GetAttributeAddressRange hi_pc = fail_value; return false; } + +size_t +DWARFDebugInfoEntry::GetAttributeAddressRanges(SymbolFileDWARF* dwarf2Data, + const DWARFCompileUnit* cu, + DWARFDebugRanges::RangeList &ranges, + bool check_hi_lo_pc) const +{ + ranges.Clear(); + + dw_offset_t ranges_offset = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET); + if (ranges_offset != DW_INVALID_OFFSET) + { + dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET); + if (debug_ranges_offset != DW_INVALID_OFFSET) + { + DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges(); + + debug_ranges->FindRanges(debug_ranges_offset, ranges); + ranges.Slide (cu->GetBaseAddress()); + } + } + else if (check_hi_lo_pc) + { + dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; + dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; + if (GetAttributeAddressRange (dwarf2Data, cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS)) + { + if (lo_pc < hi_pc) + ranges.Append(DWARFDebugRanges::RangeList::Entry(lo_pc, hi_pc - lo_pc)); + } + } + return ranges.GetSize(); +} + //---------------------------------------------------------------------- // GetAttributeValueAsLocation // diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h index f7405755528..68020d6952c 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h @@ -209,7 +209,13 @@ public: dw_addr_t& lo_pc, dw_addr_t& hi_pc, uint64_t fail_value) const; - + + size_t GetAttributeAddressRanges ( + SymbolFileDWARF* dwarf2Data, + const DWARFCompileUnit* cu, + DWARFDebugRanges::RangeList &ranges, + bool check_hi_lo_pc) const; + dw_offset_t GetAttributeValueAsLocation( SymbolFileDWARF* dwarf2Data, const DWARFCompileUnit* cu, |