1 //===- DWARFAddressRange.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_DWARF_DWARFADDRESSRANGE_H
10 #define LLVM_DEBUGINFO_DWARF_DWARFADDRESSRANGE_H
11 
12 #include "llvm/DebugInfo/DIContext.h"
13 #include "llvm/Object/ObjectFile.h"
14 #include <algorithm>
15 #include <cassert>
16 #include <cstdint>
17 #include <tuple>
18 #include <vector>
19 
20 namespace llvm {
21 
22 class raw_ostream;
23 class DWARFObject;
24 
25 struct DWARFAddressRange {
26   uint64_t LowPC;
27   uint64_t HighPC;
28   uint64_t SectionIndex;
29 
30   DWARFAddressRange() = default;
31 
32   /// Used for unit testing.
33   DWARFAddressRange(
34       uint64_t LowPC, uint64_t HighPC,
35       uint64_t SectionIndex = object::SectionedAddress::UndefSection)
LowPCDWARFAddressRange36       : LowPC(LowPC), HighPC(HighPC), SectionIndex(SectionIndex) {}
37 
38   /// Returns true if LowPC is smaller or equal to HighPC. This accounts for
39   /// dead-stripped ranges.
validDWARFAddressRange40   bool valid() const { return LowPC <= HighPC; }
41 
42   /// Returns true if [LowPC, HighPC) intersects with [RHS.LowPC, RHS.HighPC).
intersectsDWARFAddressRange43   bool intersects(const DWARFAddressRange &RHS) const {
44     assert(valid() && RHS.valid());
45     if (SectionIndex != RHS.SectionIndex)
46       return false;
47     // Empty ranges can't intersect.
48     if (LowPC == HighPC || RHS.LowPC == RHS.HighPC)
49       return false;
50     return LowPC < RHS.HighPC && RHS.LowPC < HighPC;
51   }
52 
53   /// Union two address ranges if they intersect.
54   ///
55   /// This function will union two address ranges if they intersect by
56   /// modifying this range to be the union of both ranges. If the two ranges
57   /// don't intersect this range will be left alone.
58   ///
59   /// \param RHS Another address range to combine with.
60   ///
61   /// \returns false if the ranges don't intersect, true if they do and the
62   /// ranges were combined.
mergeDWARFAddressRange63   bool merge(const DWARFAddressRange &RHS) {
64     if (!intersects(RHS))
65       return false;
66     LowPC = std::min<uint64_t>(LowPC, RHS.LowPC);
67     HighPC = std::max<uint64_t>(HighPC, RHS.HighPC);
68     return true;
69   }
70 
71   void dump(raw_ostream &OS, uint32_t AddressSize, DIDumpOptions DumpOpts = {},
72             const DWARFObject *Obj = nullptr) const;
73 };
74 
75 inline bool operator<(const DWARFAddressRange &LHS,
76                       const DWARFAddressRange &RHS) {
77   return std::tie(LHS.SectionIndex, LHS.LowPC, LHS.HighPC) < std::tie(RHS.SectionIndex, RHS.LowPC, RHS.HighPC);
78 }
79 
80 inline bool operator==(const DWARFAddressRange &LHS,
81                        const DWARFAddressRange &RHS) {
82   return std::tie(LHS.SectionIndex, LHS.LowPC, LHS.HighPC) == std::tie(RHS.SectionIndex, RHS.LowPC, RHS.HighPC);
83 }
84 
85 raw_ostream &operator<<(raw_ostream &OS, const DWARFAddressRange &R);
86 
87 /// DWARFAddressRangesVector - represents a set of absolute address ranges.
88 using DWARFAddressRangesVector = std::vector<DWARFAddressRange>;
89 
90 } // end namespace llvm
91 
92 #endif // LLVM_DEBUGINFO_DWARF_DWARFADDRESSRANGE_H
93