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