Range.cpp 3.5 KB

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