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 15 using namespace lldb_private; 16 using namespace std; 17 18 DWARFDebugRanges::DWARFDebugRanges() : 19 m_range_map() 20 { 21 } 22 23 DWARFDebugRanges::~DWARFDebugRanges() 24 { 25 } 26 27 void 28 DWARFDebugRanges::Extract(SymbolFileDWARF* dwarf2Data) 29 { 30 RangeList range_list; 31 dw_offset_t offset = 0; 32 dw_offset_t debug_ranges_offset = offset; 33 while (Extract(dwarf2Data, &offset, range_list)) 34 { 35 m_range_map[debug_ranges_offset] = range_list; 36 debug_ranges_offset = offset; 37 } 38 } 39 40 //void 41 //DWARFDebugRanges::RangeList::AddOffset(dw_addr_t offset) 42 //{ 43 // if (!ranges.empty()) 44 // { 45 // Range::iterator pos = ranges.begin(); 46 // Range::iterator end_pos = ranges.end(); 47 // for (pos = ranges.begin(); pos != end_pos; ++pos) 48 // { 49 // // assert for unsigned overflows 50 // assert (~pos->begin_offset >= offset); 51 // assert (~pos->end_offset >= offset); 52 // pos->begin_offset += offset; 53 // pos->end_offset += offset; 54 // } 55 // } 56 //} 57 // 58 //void 59 //DWARFDebugRanges::RangeList::SubtractOffset(dw_addr_t offset) 60 //{ 61 // if (!ranges.empty()) 62 // { 63 // Range::iterator pos = ranges.begin(); 64 // Range::iterator end_pos = ranges.end(); 65 // for (pos = ranges.begin(); pos != end_pos; ++pos) 66 // { 67 // assert (pos->begin_offset >= offset); 68 // assert (pos->end_offset >= offset); 69 // pos->begin_offset -= offset; 70 // pos->end_offset -= offset; 71 // } 72 // } 73 //} 74 // 75 // 76 //const DWARFDebugRanges::Range* 77 //DWARFDebugRanges::RangeList::RangeAtIndex(size_t i) const 78 //{ 79 // if (i < ranges.size()) 80 // return &ranges[i]; 81 // return NULL; 82 //} 83 84 bool 85 DWARFDebugRanges::Extract(SymbolFileDWARF* dwarf2Data, uint32_t* offset_ptr, RangeList &range_list) 86 { 87 range_list.Clear(); 88 89 uint32_t range_offset = *offset_ptr; 90 const DataExtractor& debug_ranges_data = dwarf2Data->get_debug_ranges_data(); 91 uint32_t addr_size = debug_ranges_data.GetAddressByteSize(); 92 93 while (debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) 94 { 95 dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); 96 dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); 97 if (!begin && !end) 98 { 99 // End of range list 100 break; 101 } 102 // Extend 4 byte addresses that consists of 32 bits of 1's to be 64 bits 103 // of ones 104 switch (addr_size) 105 { 106 case 2: 107 if (begin == 0xFFFFull) 108 begin = DW_INVALID_ADDRESS; 109 break; 110 111 case 4: 112 if (begin == 0xFFFFFFFFull) 113 begin = DW_INVALID_ADDRESS; 114 break; 115 116 case 8: 117 break; 118 119 default: 120 assert(!"DWARFDebugRanges::RangeList::Extract() unsupported address size."); 121 break; 122 } 123 124 // Filter out empty ranges 125 if (begin < end) 126 range_list.Append(Range(begin, end - begin)); 127 } 128 129 // Make sure we consumed at least something 130 return range_offset != *offset_ptr; 131 } 132 133 // 134 //dw_addr_t 135 //DWARFDebugRanges::RangeList::LowestAddress(const dw_addr_t cu_base_addr) const 136 //{ 137 // dw_addr_t addr = DW_INVALID_ADDRESS; 138 // dw_addr_t curr_base_addr = cu_base_addr; 139 // if (!ranges.empty()) 140 // { 141 // Range::const_iterator pos = ranges.begin(); 142 // Range::const_iterator end_pos = ranges.end(); 143 // for (pos = ranges.begin(); pos != end_pos; ++pos) 144 // { 145 // if (pos->begin_offset == DW_INVALID_ADDRESS) 146 // curr_base_addr = pos->end_offset; 147 // else if (curr_base_addr != DW_INVALID_ADDRESS) 148 // { 149 // dw_addr_t curr_addr = curr_base_addr + pos->begin_offset; 150 // if (addr > curr_addr) 151 // addr = curr_addr; 152 // } 153 // } 154 // } 155 // return addr; 156 //} 157 // 158 //dw_addr_t 159 //DWARFDebugRanges::RangeList::HighestAddress(const dw_addr_t cu_base_addr) const 160 //{ 161 // dw_addr_t addr = 0; 162 // dw_addr_t curr_base_addr = cu_base_addr; 163 // if (!ranges.empty()) 164 // { 165 // Range::const_iterator pos = ranges.begin(); 166 // Range::const_iterator end_pos = ranges.end(); 167 // for (pos = ranges.begin(); pos != end_pos; ++pos) 168 // { 169 // if (pos->begin_offset == DW_INVALID_ADDRESS) 170 // curr_base_addr = pos->end_offset; 171 // else if (curr_base_addr != DW_INVALID_ADDRESS) 172 // { 173 // dw_addr_t curr_addr = curr_base_addr + pos->end_offset; 174 // if (addr < curr_addr) 175 // addr = curr_addr; 176 // } 177 // } 178 // } 179 // if (addr != 0) 180 // return addr; 181 // return DW_INVALID_ADDRESS; 182 //} 183 // 184 185 void 186 DWARFDebugRanges::Dump(Stream &s, const DataExtractor& debug_ranges_data, uint32_t* offset_ptr, dw_addr_t cu_base_addr) 187 { 188 uint32_t addr_size = s.GetAddressByteSize(); 189 bool verbose = s.GetVerbose(); 190 191 dw_addr_t base_addr = cu_base_addr; 192 while (debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) 193 { 194 dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); 195 dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); 196 // Extend 4 byte addresses that consits of 32 bits of 1's to be 64 bits 197 // of ones 198 if (begin == 0xFFFFFFFFull && addr_size == 4) 199 begin = DW_INVALID_ADDRESS; 200 201 s.Indent(); 202 if (verbose) 203 { 204 s.AddressRange(begin, end, sizeof (dw_addr_t), " offsets = "); 205 } 206 207 208 if (begin == 0 && end == 0) 209 { 210 s.PutCString(" End"); 211 break; 212 } 213 else if (begin == DW_INVALID_ADDRESS) 214 { 215 // A base address selection entry 216 base_addr = end; 217 s.Address(base_addr, sizeof (dw_addr_t), " Base address = "); 218 } 219 else 220 { 221 // Convert from offset to an address 222 dw_addr_t begin_addr = begin + base_addr; 223 dw_addr_t end_addr = end + base_addr; 224 225 s.AddressRange(begin_addr, end_addr, sizeof (dw_addr_t), verbose ? " ==> addrs = " : NULL); 226 } 227 } 228 } 229 230 bool 231 DWARFDebugRanges::FindRanges(dw_offset_t debug_ranges_offset, RangeList& range_list) const 232 { 233 range_map_const_iterator pos = m_range_map.find(debug_ranges_offset); 234 if (pos != m_range_map.end()) 235 { 236 range_list = pos->second; 237 return true; 238 } 239 return false; 240 } 241 242 243 244