1 //===- Range.cpp ------------------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/DebugInfo/GSYM/Range.h"
10 #include "llvm/DebugInfo/GSYM/FileWriter.h"
11 #include "llvm/Support/DataExtractor.h"
19 void AddressRanges::insert(AddressRange Range
) {
20 if (Range
.size() == 0)
23 auto It
= llvm::upper_bound(Ranges
, Range
);
25 while (It2
!= Ranges
.end() && It2
->Start
< Range
.End
)
28 Range
.End
= std::max(Range
.End
, It2
[-1].End
);
29 It
= Ranges
.erase(It
, It2
);
31 if (It
!= Ranges
.begin() && Range
.Start
< It
[-1].End
)
32 It
[-1].End
= std::max(It
[-1].End
, Range
.End
);
34 Ranges
.insert(It
, Range
);
37 bool AddressRanges::contains(uint64_t Addr
) const {
38 auto It
= std::partition_point(
39 Ranges
.begin(), Ranges
.end(),
40 [=](const AddressRange
&R
) { return R
.Start
<= Addr
; });
41 return It
!= Ranges
.begin() && Addr
< It
[-1].End
;
44 bool AddressRanges::contains(AddressRange Range
) const {
45 if (Range
.size() == 0)
47 auto It
= std::partition_point(
48 Ranges
.begin(), Ranges
.end(),
49 [=](const AddressRange
&R
) { return R
.Start
<= Range
.Start
; });
50 if (It
== Ranges
.begin())
52 return Range
.End
<= It
[-1].End
;
55 Optional
<AddressRange
>
56 AddressRanges::getRangeThatContains(uint64_t Addr
) const {
57 auto It
= std::partition_point(
58 Ranges
.begin(), Ranges
.end(),
59 [=](const AddressRange
&R
) { return R
.Start
<= Addr
; });
60 if (It
!= Ranges
.begin() && Addr
< It
[-1].End
)
65 raw_ostream
&llvm::gsym::operator<<(raw_ostream
&OS
, const AddressRange
&R
) {
66 return OS
<< '[' << HEX64(R
.Start
) << " - " << HEX64(R
.End
) << ")";
69 raw_ostream
&llvm::gsym::operator<<(raw_ostream
&OS
, const AddressRanges
&AR
) {
70 size_t Size
= AR
.size();
71 for (size_t I
= 0; I
< Size
; ++I
) {
79 void AddressRange::encode(FileWriter
&O
, uint64_t BaseAddr
) const {
80 assert(Start
>= BaseAddr
);
81 O
.writeULEB(Start
- BaseAddr
);
85 void AddressRange::decode(DataExtractor
&Data
, uint64_t BaseAddr
,
87 const uint64_t AddrOffset
= Data
.getULEB128(&Offset
);
88 const uint64_t Size
= Data
.getULEB128(&Offset
);
89 const uint64_t StartAddr
= BaseAddr
+ AddrOffset
;
91 End
= StartAddr
+ Size
;
94 void AddressRanges::encode(FileWriter
&O
, uint64_t BaseAddr
) const {
95 O
.writeULEB(Ranges
.size());
98 for (auto Range
: Ranges
)
99 Range
.encode(O
, BaseAddr
);
102 void AddressRanges::decode(DataExtractor
&Data
, uint64_t BaseAddr
,
105 uint64_t NumRanges
= Data
.getULEB128(&Offset
);
108 Ranges
.resize(NumRanges
);
109 for (auto &Range
: Ranges
)
110 Range
.decode(Data
, BaseAddr
, Offset
);
113 void AddressRange::skip(DataExtractor
&Data
, uint64_t &Offset
) {
114 Data
.getULEB128(&Offset
);
115 Data
.getULEB128(&Offset
);
118 uint64_t AddressRanges::skip(DataExtractor
&Data
, uint64_t &Offset
) {
119 uint64_t NumRanges
= Data
.getULEB128(&Offset
);
120 for (uint64_t I
=0; I
<NumRanges
; ++I
)
121 AddressRange::skip(Data
, Offset
);