1 //===- DWARFDebugRangesList.cpp -------------------------------------------===// 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 "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" 11 #include "llvm/Support/Format.h" 12 #include "llvm/Support/raw_ostream.h" 13 #include <cinttypes> 14 #include <cstdint> 15 #include <utility> 16 17 using namespace llvm; 18 19 void DWARFDebugRangeList::clear() { 20 Offset = -1U; 21 AddressSize = 0; 22 Entries.clear(); 23 } 24 25 bool DWARFDebugRangeList::extract(DataExtractor data, uint32_t *offset_ptr) { 26 clear(); 27 if (!data.isValidOffset(*offset_ptr)) 28 return false; 29 AddressSize = data.getAddressSize(); 30 if (AddressSize != 4 && AddressSize != 8) 31 return false; 32 Offset = *offset_ptr; 33 while (true) { 34 RangeListEntry entry; 35 uint32_t prev_offset = *offset_ptr; 36 entry.StartAddress = data.getAddress(offset_ptr); 37 entry.EndAddress = data.getAddress(offset_ptr); 38 // Check that both values were extracted correctly. 39 if (*offset_ptr != prev_offset + 2 * AddressSize) { 40 clear(); 41 return false; 42 } 43 if (entry.isEndOfListEntry()) 44 break; 45 Entries.push_back(entry); 46 } 47 return true; 48 } 49 50 void DWARFDebugRangeList::dump(raw_ostream &OS) const { 51 for (const RangeListEntry &RLE : Entries) { 52 const char *format_str = (AddressSize == 4 53 ? "%08x %08" PRIx64 " %08" PRIx64 "\n" 54 : "%08x %016" PRIx64 " %016" PRIx64 "\n"); 55 OS << format(format_str, Offset, RLE.StartAddress, RLE.EndAddress); 56 } 57 OS << format("%08x <End of list>\n", Offset); 58 } 59 60 DWARFAddressRangesVector 61 DWARFDebugRangeList::getAbsoluteRanges(uint64_t BaseAddress) const { 62 DWARFAddressRangesVector Res; 63 for (const RangeListEntry &RLE : Entries) { 64 if (RLE.isBaseAddressSelectionEntry(AddressSize)) { 65 BaseAddress = RLE.EndAddress; 66 } else { 67 Res.push_back(std::make_pair(BaseAddress + RLE.StartAddress, 68 BaseAddress + RLE.EndAddress)); 69 } 70 } 71 return Res; 72 } 73