| Greg Clayton | 044776b | 2019-06-26 14:09:09 +0000 | [diff] [blame] | 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" | 
| Greg Clayton | bf9ee07 | 2019-08-21 21:48:11 +0000 | [diff] [blame] | 11 | #include "llvm/DebugInfo/GSYM/FileWriter.h" | 
|  | 12 | #include "llvm/Support/DataExtractor.h" | 
| Greg Clayton | 044776b | 2019-06-26 14:09:09 +0000 | [diff] [blame] | 13 | #include <algorithm> | 
|  | 14 | #include <inttypes.h> | 
|  | 15 |  | 
|  | 16 | using namespace llvm; | 
|  | 17 | using namespace gsym; | 
|  | 18 |  | 
|  | 19 |  | 
| Fangrui Song | 493a120 | 2019-06-28 10:06:11 +0000 | [diff] [blame] | 20 | void AddressRanges::insert(AddressRange Range) { | 
| Greg Clayton | 044776b | 2019-06-26 14:09:09 +0000 | [diff] [blame] | 21 | if (Range.size() == 0) | 
|  | 22 | return; | 
| Greg Clayton | 044776b | 2019-06-26 14:09:09 +0000 | [diff] [blame] | 23 |  | 
| Fangrui Song | 493a120 | 2019-06-28 10:06:11 +0000 | [diff] [blame] | 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); | 
| Greg Clayton | 044776b | 2019-06-26 14:09:09 +0000 | [diff] [blame] | 31 | } | 
| Fangrui Song | 493a120 | 2019-06-28 10:06:11 +0000 | [diff] [blame] | 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); | 
| Greg Clayton | 044776b | 2019-06-26 14:09:09 +0000 | [diff] [blame] | 36 | } | 
|  | 37 |  | 
|  | 38 | bool AddressRanges::contains(uint64_t Addr) const { | 
| Fangrui Song | e662b69 | 2019-06-28 08:58:05 +0000 | [diff] [blame] | 39 | auto It = std::partition_point( | 
|  | 40 | Ranges.begin(), Ranges.end(), | 
| Fangrui Song | 493a120 | 2019-06-28 10:06:11 +0000 | [diff] [blame] | 41 | [=](const AddressRange &R) { return R.Start <= Addr; }); | 
|  | 42 | return It != Ranges.begin() && Addr < It[-1].End; | 
| Greg Clayton | 044776b | 2019-06-26 14:09:09 +0000 | [diff] [blame] | 43 | } | 
|  | 44 |  | 
|  | 45 | raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const AddressRange &R) { | 
| Fangrui Song | 493a120 | 2019-06-28 10:06:11 +0000 | [diff] [blame] | 46 | return OS << '[' << HEX64(R.Start) << " - " << HEX64(R.End) << ")"; | 
| Greg Clayton | 044776b | 2019-06-26 14:09:09 +0000 | [diff] [blame] | 47 | } | 
|  | 48 |  | 
|  | 49 | raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const AddressRanges &AR) { | 
|  | 50 | size_t Size = AR.size(); | 
| Fangrui Song | 493a120 | 2019-06-28 10:06:11 +0000 | [diff] [blame] | 51 | for (size_t I = 0; I < Size; ++I) { | 
| Greg Clayton | 044776b | 2019-06-26 14:09:09 +0000 | [diff] [blame] | 52 | if (I) | 
|  | 53 | OS << ' '; | 
|  | 54 | OS << AR[I]; | 
|  | 55 | } | 
|  | 56 | return OS; | 
|  | 57 | } | 
| Greg Clayton | bf9ee07 | 2019-08-21 21:48:11 +0000 | [diff] [blame] | 58 |  | 
|  | 59 | void AddressRange::encode(FileWriter &O, uint64_t BaseAddr) const { | 
|  | 60 | assert(Start >= BaseAddr); | 
|  | 61 | O.writeULEB(Start - BaseAddr); | 
|  | 62 | O.writeULEB(size()); | 
|  | 63 | } | 
|  | 64 |  | 
|  | 65 | void AddressRange::decode(DataExtractor &Data, uint64_t BaseAddr, | 
|  | 66 | uint64_t &Offset) { | 
|  | 67 | const uint64_t AddrOffset = Data.getULEB128(&Offset); | 
|  | 68 | const uint64_t Size = Data.getULEB128(&Offset); | 
|  | 69 | const uint64_t StartAddr = BaseAddr + AddrOffset; | 
|  | 70 | Start = StartAddr; | 
|  | 71 | End = StartAddr + Size; | 
|  | 72 | } | 
|  | 73 |  | 
|  | 74 | void AddressRanges::encode(FileWriter &O, uint64_t BaseAddr) const { | 
|  | 75 | O.writeULEB(Ranges.size()); | 
|  | 76 | if (Ranges.empty()) | 
|  | 77 | return; | 
|  | 78 | for (auto Range : Ranges) | 
|  | 79 | Range.encode(O, BaseAddr); | 
|  | 80 | } | 
|  | 81 |  | 
|  | 82 | void AddressRanges::decode(DataExtractor &Data, uint64_t BaseAddr, | 
|  | 83 | uint64_t &Offset) { | 
|  | 84 | clear(); | 
|  | 85 | uint64_t NumRanges = Data.getULEB128(&Offset); | 
|  | 86 | if (NumRanges == 0) | 
|  | 87 | return; | 
|  | 88 | Ranges.resize(NumRanges); | 
|  | 89 | for (auto &Range : Ranges) | 
|  | 90 | Range.decode(Data, BaseAddr, Offset); | 
|  | 91 | } |