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