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