summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp41
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h3
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp3
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp3
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp34
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h8
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,
OpenPOWER on IntegriCloud