1 //===- Range.cpp ------------------------------------------------*- C++ -*-===// 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/GSYM/Range.h" 11 #include "llvm/DebugInfo/GSYM/FileWriter.h" 12 #include "llvm/Support/DataExtractor.h" 13 #include <algorithm> 14 #include <inttypes.h> 15 16 using namespace llvm; 17 using namespace gsym; 18 19 20 void AddressRanges::insert(AddressRange Range) { 21 if (Range.size() == 0) 22 return; 23 24 auto It = llvm::upper_bound(Ranges, Range); 25 auto It2 = It; 26 while (It2 != Ranges.end() && It2->Start < Range.End) 27 ++It2; 28 if (It != It2) { 29 Range.End = std::max(Range.End, It2[-1].End); 30 It = Ranges.erase(It, It2); 31 } 32 if (It != Ranges.begin() && Range.Start < It[-1].End) 33 It[-1].End = std::max(It[-1].End, Range.End); 34 else 35 Ranges.insert(It, Range); 36 } 37 38 bool AddressRanges::contains(uint64_t Addr) const { 39 auto It = std::partition_point( 40 Ranges.begin(), Ranges.end(), 41 [=](const AddressRange &R) { return R.Start <= Addr; }); 42 return It != Ranges.begin() && Addr < It[-1].End; 43 } 44 45 bool AddressRanges::contains(AddressRange Range) const { 46 if (Range.size() == 0) 47 return false; 48 auto It = std::partition_point( 49 Ranges.begin(), Ranges.end(), 50 [=](const AddressRange &R) { return R.Start <= Range.Start; }); 51 if (It == Ranges.begin()) 52 return false; 53 return Range.End <= It[-1].End; 54 } 55 56 raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const AddressRange &R) { 57 return OS << '[' << HEX64(R.Start) << " - " << HEX64(R.End) << ")"; 58 } 59 60 raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const AddressRanges &AR) { 61 size_t Size = AR.size(); 62 for (size_t I = 0; I < Size; ++I) { 63 if (I) 64 OS << ' '; 65 OS << AR[I]; 66 } 67 return OS; 68 } 69 70 void AddressRange::encode(FileWriter &O, uint64_t BaseAddr) const { 71 assert(Start >= BaseAddr); 72 O.writeULEB(Start - BaseAddr); 73 O.writeULEB(size()); 74 } 75 76 void AddressRange::decode(DataExtractor &Data, uint64_t BaseAddr, 77 uint64_t &Offset) { 78 const uint64_t AddrOffset = Data.getULEB128(&Offset); 79 const uint64_t Size = Data.getULEB128(&Offset); 80 const uint64_t StartAddr = BaseAddr + AddrOffset; 81 Start = StartAddr; 82 End = StartAddr + Size; 83 } 84 85 void AddressRanges::encode(FileWriter &O, uint64_t BaseAddr) const { 86 O.writeULEB(Ranges.size()); 87 if (Ranges.empty()) 88 return; 89 for (auto Range : Ranges) 90 Range.encode(O, BaseAddr); 91 } 92 93 void AddressRanges::decode(DataExtractor &Data, uint64_t BaseAddr, 94 uint64_t &Offset) { 95 clear(); 96 uint64_t NumRanges = Data.getULEB128(&Offset); 97 if (NumRanges == 0) 98 return; 99 Ranges.resize(NumRanges); 100 for (auto &Range : Ranges) 101 Range.decode(Data, BaseAddr, Offset); 102 } 103