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/DebugInfo/DWARF/DWARFContext.h" 12 #include "llvm/Support/Format.h" 13 #include "llvm/Support/raw_ostream.h" 14 #include <cinttypes> 15 #include <cstdint> 16 #include <utility> 17 18 using namespace llvm; 19 20 void DWARFDebugRangeList::clear() { 21 Offset = -1U; 22 AddressSize = 0; 23 Entries.clear(); 24 } 25 26 bool DWARFDebugRangeList::extract(const DWARFDataExtractor &data, 27 uint32_t *offset_ptr) { 28 clear(); 29 if (!data.isValidOffset(*offset_ptr)) 30 return false; 31 AddressSize = data.getAddressSize(); 32 if (AddressSize != 4 && AddressSize != 8) 33 return false; 34 Offset = *offset_ptr; 35 while (true) { 36 RangeListEntry Entry; 37 Entry.SectionIndex = -1ULL; 38 39 uint32_t prev_offset = *offset_ptr; 40 Entry.StartAddress = data.getRelocatedAddress(offset_ptr); 41 Entry.EndAddress = 42 data.getRelocatedAddress(offset_ptr, &Entry.SectionIndex); 43 44 // Check that both values were extracted correctly. 45 if (*offset_ptr != prev_offset + 2 * AddressSize) { 46 clear(); 47 return false; 48 } 49 if (Entry.isEndOfListEntry()) 50 break; 51 Entries.push_back(Entry); 52 } 53 return true; 54 } 55 56 void DWARFDebugRangeList::dump(raw_ostream &OS) const { 57 for (const RangeListEntry &RLE : Entries) { 58 const char *format_str = (AddressSize == 4 59 ? "%08x %08" PRIx64 " %08" PRIx64 "\n" 60 : "%08x %016" PRIx64 " %016" PRIx64 "\n"); 61 OS << format(format_str, Offset, RLE.StartAddress, RLE.EndAddress); 62 } 63 OS << format("%08x <End of list>\n", Offset); 64 } 65 66 DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges( 67 llvm::Optional<BaseAddress> BaseAddr) const { 68 DWARFAddressRangesVector Res; 69 for (const RangeListEntry &RLE : Entries) { 70 if (RLE.isBaseAddressSelectionEntry(AddressSize)) { 71 BaseAddr = {RLE.EndAddress, RLE.SectionIndex}; 72 continue; 73 } 74 75 DWARFAddressRange E; 76 E.LowPC = RLE.StartAddress; 77 E.HighPC = RLE.EndAddress; 78 E.SectionIndex = RLE.SectionIndex; 79 // Base address of a range list entry is determined by the closest preceding 80 // base address selection entry in the same range list. It defaults to the 81 // base address of the compilation unit if there is no such entry. 82 if (BaseAddr) { 83 E.LowPC += BaseAddr->Address; 84 E.HighPC += BaseAddr->Address; 85 if (E.SectionIndex == -1ULL) 86 E.SectionIndex = BaseAddr->SectionIndex; 87 } 88 Res.push_back(E); 89 } 90 return Res; 91 } 92