• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- Range.h --------------------------------------------------*- C++ -*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_DEBUGINFO_GSYM_RANGE_H
10 #define LLVM_DEBUGINFO_GSYM_RANGE_H
11 
12 #include "llvm/Support/Format.h"
13 #include "llvm/Support/raw_ostream.h"
14 #include <stdint.h>
15 #include <vector>
16 
17 #define HEX8(v) llvm::format_hex(v, 4)
18 #define HEX16(v) llvm::format_hex(v, 6)
19 #define HEX32(v) llvm::format_hex(v, 10)
20 #define HEX64(v) llvm::format_hex(v, 18)
21 
22 namespace llvm {
23 class DataExtractor;
24 class raw_ostream;
25 
26 namespace gsym {
27 
28 class FileWriter;
29 
30 /// A class that represents an address range. The range is specified using
31 /// a start and an end address.
32 struct AddressRange {
33   uint64_t Start;
34   uint64_t End;
AddressRangeAddressRange35   AddressRange() : Start(0), End(0) {}
AddressRangeAddressRange36   AddressRange(uint64_t S, uint64_t E) : Start(S), End(E) {}
sizeAddressRange37   uint64_t size() const { return End - Start; }
containsAddressRange38   bool contains(uint64_t Addr) const { return Start <= Addr && Addr < End; }
intersectsAddressRange39   bool intersects(const AddressRange &R) const {
40     return Start < R.End && R.Start < End;
41   }
42 
43   bool operator==(const AddressRange &R) const {
44     return Start == R.Start && End == R.End;
45   }
46   bool operator!=(const AddressRange &R) const {
47     return !(*this == R);
48   }
49   bool operator<(const AddressRange &R) const {
50     return std::make_pair(Start, End) < std::make_pair(R.Start, R.End);
51   }
52   /// AddressRange objects are encoded and decoded to be relative to a base
53   /// address. This will be the FunctionInfo's start address if the AddressRange
54   /// is directly contained in a FunctionInfo, or a base address of the
55   /// containing parent AddressRange or AddressRanges. This allows address
56   /// ranges to be efficiently encoded using ULEB128 encodings as we encode the
57   /// offset and size of each range instead of full addresses. This also makes
58   /// encoded addresses easy to relocate as we just need to relocate one base
59   /// address.
60   /// @{
61   void decode(DataExtractor &Data, uint64_t BaseAddr, uint64_t &Offset);
62   void encode(FileWriter &O, uint64_t BaseAddr) const;
63   /// @}
64 
65   /// Skip an address range object in the specified data a the specified
66   /// offset.
67   ///
68   /// \param Data The binary stream to read the data from.
69   ///
70   /// \param Offset The byte offset within \a Data.
71   static void skip(DataExtractor &Data, uint64_t &Offset);
72 };
73 
74 raw_ostream &operator<<(raw_ostream &OS, const AddressRange &R);
75 
76 /// The AddressRanges class helps normalize address range collections.
77 /// This class keeps a sorted vector of AddressRange objects and can perform
78 /// insertions and searches efficiently. The address ranges are always sorted
79 /// and never contain any invalid or empty address ranges. This allows us to
80 /// emit address ranges into the GSYM file efficiently. Intersecting address
81 /// ranges are combined during insertion so that we can emit the most compact
82 /// representation for address ranges when writing to disk.
83 class AddressRanges {
84 protected:
85   using Collection = std::vector<AddressRange>;
86   Collection Ranges;
87 public:
clear()88   void clear() { Ranges.clear(); }
empty()89   bool empty() const { return Ranges.empty(); }
90   bool contains(uint64_t Addr) const;
91   bool contains(AddressRange Range) const;
92   void insert(AddressRange Range);
size()93   size_t size() const { return Ranges.size(); }
94   bool operator==(const AddressRanges &RHS) const {
95     return Ranges == RHS.Ranges;
96   }
97   const AddressRange &operator[](size_t i) const {
98     assert(i < Ranges.size());
99     return Ranges[i];
100   }
begin()101   Collection::const_iterator begin() const { return Ranges.begin(); }
end()102   Collection::const_iterator end() const { return Ranges.end(); }
103 
104   /// Address ranges are decoded and encoded to be relative to a base address.
105   /// See the AddressRange comment for the encode and decode methods for full
106   /// details.
107   /// @{
108   void decode(DataExtractor &Data, uint64_t BaseAddr, uint64_t &Offset);
109   void encode(FileWriter &O, uint64_t BaseAddr) const;
110   /// @}
111 
112   /// Skip an address range object in the specified data a the specified
113   /// offset.
114   ///
115   /// \param Data The binary stream to read the data from.
116   ///
117   /// \param Offset The byte offset within \a Data.
118   ///
119   /// \returns The number of address ranges that were skipped.
120   static uint64_t skip(DataExtractor &Data, uint64_t &Offset);
121 };
122 
123 raw_ostream &operator<<(raw_ostream &OS, const AddressRanges &AR);
124 
125 } // namespace gsym
126 } // namespace llvm
127 
128 #endif // #ifndef LLVM_DEBUGINFO_GSYM_RANGE_H
129