DWARFDebugRanges.cpp revision 263367
1//===-- DWARFDebugRanges.cpp ------------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "DWARFDebugRanges.h" 11#include "SymbolFileDWARF.h" 12#include "lldb/Core/Stream.h" 13#include <assert.h> 14 15using namespace lldb_private; 16using namespace std; 17 18DWARFDebugRanges::DWARFDebugRanges() : 19 m_range_map() 20{ 21} 22 23DWARFDebugRanges::~DWARFDebugRanges() 24{ 25} 26 27void 28DWARFDebugRanges::Extract(SymbolFileDWARF* dwarf2Data) 29{ 30 RangeList range_list; 31 lldb::offset_t offset = 0; 32 dw_offset_t debug_ranges_offset = offset; 33 while (Extract(dwarf2Data, &offset, range_list)) 34 { 35 range_list.Sort(); 36 m_range_map[debug_ranges_offset] = range_list; 37 debug_ranges_offset = offset; 38 } 39} 40 41//void 42//DWARFDebugRanges::RangeList::AddOffset(dw_addr_t offset) 43//{ 44// if (!ranges.empty()) 45// { 46// Range::iterator pos = ranges.begin(); 47// Range::iterator end_pos = ranges.end(); 48// for (pos = ranges.begin(); pos != end_pos; ++pos) 49// { 50// // assert for unsigned overflows 51// assert (~pos->begin_offset >= offset); 52// assert (~pos->end_offset >= offset); 53// pos->begin_offset += offset; 54// pos->end_offset += offset; 55// } 56// } 57//} 58// 59//void 60//DWARFDebugRanges::RangeList::SubtractOffset(dw_addr_t offset) 61//{ 62// if (!ranges.empty()) 63// { 64// Range::iterator pos = ranges.begin(); 65// Range::iterator end_pos = ranges.end(); 66// for (pos = ranges.begin(); pos != end_pos; ++pos) 67// { 68// assert (pos->begin_offset >= offset); 69// assert (pos->end_offset >= offset); 70// pos->begin_offset -= offset; 71// pos->end_offset -= offset; 72// } 73// } 74//} 75// 76// 77//const DWARFDebugRanges::Range* 78//DWARFDebugRanges::RangeList::RangeAtIndex(size_t i) const 79//{ 80// if (i < ranges.size()) 81// return &ranges[i]; 82// return NULL; 83//} 84 85bool 86DWARFDebugRanges::Extract(SymbolFileDWARF* dwarf2Data, lldb::offset_t *offset_ptr, RangeList &range_list) 87{ 88 range_list.Clear(); 89 90 lldb::offset_t range_offset = *offset_ptr; 91 const DWARFDataExtractor& debug_ranges_data = dwarf2Data->get_debug_ranges_data(); 92 uint32_t addr_size = debug_ranges_data.GetAddressByteSize(); 93 94 while (debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) 95 { 96 dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); 97 dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); 98 if (!begin && !end) 99 { 100 // End of range list 101 break; 102 } 103 // Extend 4 byte addresses that consists of 32 bits of 1's to be 64 bits 104 // of ones 105 switch (addr_size) 106 { 107 case 2: 108 if (begin == 0xFFFFull) 109 begin = LLDB_INVALID_ADDRESS; 110 break; 111 112 case 4: 113 if (begin == 0xFFFFFFFFull) 114 begin = LLDB_INVALID_ADDRESS; 115 break; 116 117 case 8: 118 break; 119 120 default: 121 assert(!"DWARFDebugRanges::RangeList::Extract() unsupported address size."); 122 break; 123 } 124 125 // Filter out empty ranges 126 if (begin < end) 127 range_list.Append(Range(begin, end - begin)); 128 } 129 130 // Make sure we consumed at least something 131 return range_offset != *offset_ptr; 132} 133 134 135void 136DWARFDebugRanges::Dump(Stream &s, const DWARFDataExtractor& debug_ranges_data, lldb::offset_t *offset_ptr, dw_addr_t cu_base_addr) 137{ 138 uint32_t addr_size = s.GetAddressByteSize(); 139 bool verbose = s.GetVerbose(); 140 141 dw_addr_t base_addr = cu_base_addr; 142 while (debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) 143 { 144 dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); 145 dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); 146 // Extend 4 byte addresses that consits of 32 bits of 1's to be 64 bits 147 // of ones 148 if (begin == 0xFFFFFFFFull && addr_size == 4) 149 begin = LLDB_INVALID_ADDRESS; 150 151 s.Indent(); 152 if (verbose) 153 { 154 s.AddressRange(begin, end, sizeof (dw_addr_t), " offsets = "); 155 } 156 157 158 if (begin == 0 && end == 0) 159 { 160 s.PutCString(" End"); 161 break; 162 } 163 else if (begin == LLDB_INVALID_ADDRESS) 164 { 165 // A base address selection entry 166 base_addr = end; 167 s.Address(base_addr, sizeof (dw_addr_t), " Base address = "); 168 } 169 else 170 { 171 // Convert from offset to an address 172 dw_addr_t begin_addr = begin + base_addr; 173 dw_addr_t end_addr = end + base_addr; 174 175 s.AddressRange(begin_addr, end_addr, sizeof (dw_addr_t), verbose ? " ==> addrs = " : NULL); 176 } 177 } 178} 179 180bool 181DWARFDebugRanges::FindRanges(dw_offset_t debug_ranges_offset, RangeList& range_list) const 182{ 183 range_map_const_iterator pos = m_range_map.find(debug_ranges_offset); 184 if (pos != m_range_map.end()) 185 { 186 range_list = pos->second; 187 return true; 188 } 189 return false; 190} 191 192 193 194