| 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 | |
| Greg Clayton | 7d0a545 | 2019-09-04 17:32:51 +0000 | [diff] [blame] | 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 | |
| Greg Clayton | 044776b | 2019-06-26 14:09:09 +0000 | [diff] [blame] | 56 | raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const AddressRange &R) { |
| Fangrui Song | 493a120 | 2019-06-28 10:06:11 +0000 | [diff] [blame] | 57 | return OS << '[' << HEX64(R.Start) << " - " << HEX64(R.End) << ")"; |
| Greg Clayton | 044776b | 2019-06-26 14:09:09 +0000 | [diff] [blame] | 58 | } |
| 59 | |
| 60 | raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const AddressRanges &AR) { |
| 61 | size_t Size = AR.size(); |
| Fangrui Song | 493a120 | 2019-06-28 10:06:11 +0000 | [diff] [blame] | 62 | for (size_t I = 0; I < Size; ++I) { |
| Greg Clayton | 044776b | 2019-06-26 14:09:09 +0000 | [diff] [blame] | 63 | if (I) |
| 64 | OS << ' '; |
| 65 | OS << AR[I]; |
| 66 | } |
| 67 | return OS; |
| 68 | } |
| Greg Clayton | bf9ee07 | 2019-08-21 21:48:11 +0000 | [diff] [blame] | 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 | } |