DWARFDebugAranges.cpp revision 263363
150472Speter//===-- DWARFDebugAranges.cpp -----------------------------------*- C++ -*-===// 238738Sbrian// 375031Smurray// The LLVM Compiler Infrastructure 475031Smurray// 575031Smurray// This file is distributed under the University of Illinois Open Source 675031Smurray// License. See LICENSE.TXT for details. 740361Snate// 8143462Sglebius//===----------------------------------------------------------------------===// 9143462Sglebius 1092099Srwatson#include "DWARFDebugAranges.h" 1192100Srwatson 1237Srgrimes#include <assert.h> 1337Srgrimes#include <stdio.h> 14103738Smarkm 1551033Sn_hibma#include <algorithm> 16113902Sdes 1737Srgrimes#include "lldb/Core/Log.h" 1872580Sphk#include "lldb/Core/Stream.h" 1972580Sphk#include "lldb/Core/Timer.h" 2057065Srwatson 2185626Sasmodai#include "LogChannelDWARF.h" 2257065Srwatson#include "SymbolFileDWARF.h" 2357065Srwatson#include "DWARFDebugInfo.h" 2457065Srwatson#include "DWARFCompileUnit.h" 2519473Spst 2619473Spstusing namespace lldb; 2719473Spstusing namespace lldb_private; 2819473Spst 2913296Sache//---------------------------------------------------------------------- 3013296Sache// Constructor 3126549Sache//---------------------------------------------------------------------- 3226549SacheDWARFDebugAranges::DWARFDebugAranges() : 33 m_aranges() 34{ 35} 36 37//---------------------------------------------------------------------- 38// CountArangeDescriptors 39//---------------------------------------------------------------------- 40class CountArangeDescriptors 41{ 42public: 43 CountArangeDescriptors (uint32_t& count_ref) : count(count_ref) 44 { 45// printf("constructor CountArangeDescriptors()\n"); 46 } 47 void operator() (const DWARFDebugArangeSet& set) 48 { 49 count += set.NumDescriptors(); 50 } 51 uint32_t& count; 52}; 53 54 55//---------------------------------------------------------------------- 56// Extract 57//---------------------------------------------------------------------- 58bool 59DWARFDebugAranges::Extract(const DWARFDataExtractor &debug_aranges_data) 60{ 61 if (debug_aranges_data.ValidOffset(0)) 62 { 63 lldb::offset_t offset = 0; 64 65 DWARFDebugArangeSet set; 66 Range range; 67 while (set.Extract(debug_aranges_data, &offset)) 68 { 69 const uint32_t num_descriptors = set.NumDescriptors(); 70 if (num_descriptors > 0) 71 { 72 const dw_offset_t cu_offset = set.GetCompileUnitDIEOffset(); 73 74 for (uint32_t i=0; i<num_descriptors; ++i) 75 { 76 const DWARFDebugArangeSet::Descriptor &descriptor = set.GetDescriptorRef(i); 77 m_aranges.Append(RangeToDIE::Entry (descriptor.address, descriptor.length, cu_offset)); 78 } 79 } 80 set.Clear(); 81 } 82 } 83 return false; 84} 85 86//---------------------------------------------------------------------- 87// Generate 88//---------------------------------------------------------------------- 89bool 90DWARFDebugAranges::Generate(SymbolFileDWARF* dwarf2Data) 91{ 92 Clear(); 93 DWARFDebugInfo* debug_info = dwarf2Data->DebugInfo(); 94 if (debug_info) 95 { 96 const bool clear_dies_if_already_not_parsed = true; 97 uint32_t cu_idx = 0; 98 const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits(); 99 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) 100 { 101 DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx); 102 if (cu) 103 cu->BuildAddressRangeTable(dwarf2Data, this, clear_dies_if_already_not_parsed); 104 } 105 } 106 return !IsEmpty(); 107} 108 109 110void 111DWARFDebugAranges::Dump (Log *log) const 112{ 113 if (log == NULL) 114 return; 115 116 const size_t num_entries = m_aranges.GetSize(); 117 for (size_t i=0; i<num_entries; ++i) 118 { 119 const RangeToDIE::Entry *entry = m_aranges.GetEntryAtIndex(i); 120 if (entry) 121 log->Printf ("0x%8.8x: [0x%" PRIx64 " - 0x%" PRIx64 ")", 122 entry->data, 123 entry->GetRangeBase(), 124 entry->GetRangeEnd()); 125 } 126} 127 128void 129DWARFDebugAranges::AppendRange (dw_offset_t offset, dw_addr_t low_pc, dw_addr_t high_pc) 130{ 131 if (high_pc > low_pc) 132 m_aranges.Append(RangeToDIE::Entry (low_pc, high_pc - low_pc, offset)); 133} 134 135void 136DWARFDebugAranges::Sort (bool minimize) 137{ 138 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", 139 __PRETTY_FUNCTION__, this); 140 141 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES)); 142 size_t orig_arange_size = 0; 143 if (log) 144 { 145 orig_arange_size = m_aranges.GetSize(); 146 log->Printf ("DWARFDebugAranges::Sort(minimize = %u) with %" PRIu64 " entries", minimize, (uint64_t)orig_arange_size); 147 } 148 149 m_aranges.Sort(); 150 m_aranges.CombineConsecutiveEntriesWithEqualData(); 151 152 if (log) 153 { 154 if (minimize) 155 { 156 const size_t new_arange_size = m_aranges.GetSize(); 157 const size_t delta = orig_arange_size - new_arange_size; 158 log->Printf ("DWARFDebugAranges::Sort() %" PRIu64 " entries after minimizing (%" PRIu64 " entries combined for %" PRIu64 " bytes saved)", 159 (uint64_t)new_arange_size, 160 (uint64_t)delta, 161 (uint64_t)delta * sizeof(Range)); 162 } 163 Dump (log); 164 } 165} 166 167//---------------------------------------------------------------------- 168// FindAddress 169//---------------------------------------------------------------------- 170dw_offset_t 171DWARFDebugAranges::FindAddress(dw_addr_t address) const 172{ 173 const RangeToDIE::Entry *entry = m_aranges.FindEntryThatContains(address); 174 if (entry) 175 return entry->data; 176 return DW_INVALID_OFFSET; 177} 178