/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Core/AddressRange.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- AddressRange.cpp --------------------------------------------------===// |
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 | | #include "lldb/Core/AddressRange.h" |
10 | | #include "lldb/Core/Module.h" |
11 | | #include "lldb/Core/Section.h" |
12 | | #include "lldb/Target/Target.h" |
13 | | #include "lldb/Utility/ConstString.h" |
14 | | #include "lldb/Utility/FileSpec.h" |
15 | | #include "lldb/Utility/Stream.h" |
16 | | #include "lldb/lldb-defines.h" |
17 | | |
18 | | #include "llvm/Support/Compiler.h" |
19 | | |
20 | | #include <memory> |
21 | | |
22 | | #include <cinttypes> |
23 | | |
24 | | namespace lldb_private { |
25 | | class SectionList; |
26 | | } |
27 | | |
28 | | using namespace lldb; |
29 | | using namespace lldb_private; |
30 | | |
31 | 163M | AddressRange::AddressRange() : m_base_addr() {} |
32 | | |
33 | | AddressRange::AddressRange(addr_t file_addr, addr_t byte_size, |
34 | | const SectionList *section_list) |
35 | 4.82k | : m_base_addr(file_addr, section_list), m_byte_size(byte_size) {} |
36 | | |
37 | | AddressRange::AddressRange(const lldb::SectionSP §ion, addr_t offset, |
38 | | addr_t byte_size) |
39 | 7.34k | : m_base_addr(section, offset), m_byte_size(byte_size) {} |
40 | | |
41 | | AddressRange::AddressRange(const Address &so_addr, addr_t byte_size) |
42 | 352 | : m_base_addr(so_addr), m_byte_size(byte_size) {} |
43 | | |
44 | 291M | AddressRange::~AddressRange() = default; |
45 | | |
46 | 0 | bool AddressRange::Contains(const Address &addr) const { |
47 | 0 | SectionSP range_sect_sp = GetBaseAddress().GetSection(); |
48 | 0 | SectionSP addr_sect_sp = addr.GetSection(); |
49 | 0 | if (range_sect_sp) { |
50 | 0 | if (!addr_sect_sp || |
51 | 0 | range_sect_sp->GetModule() != addr_sect_sp->GetModule()) |
52 | 0 | return false; // Modules do not match. |
53 | 0 | } else if (addr_sect_sp) { |
54 | 0 | return false; // Range has no module but "addr" does because addr has a |
55 | | // section |
56 | 0 | } |
57 | | // Either the modules match, or both have no module, so it is ok to compare |
58 | | // the file addresses in this case only. |
59 | 0 | return ContainsFileAddress(addr); |
60 | 0 | } |
61 | | |
62 | 301k | bool AddressRange::ContainsFileAddress(const Address &addr) const { |
63 | 301k | if (addr.GetSection() == m_base_addr.GetSection()) |
64 | 300k | return (addr.GetOffset() - m_base_addr.GetOffset()) < GetByteSize(); |
65 | 410 | addr_t file_base_addr = GetBaseAddress().GetFileAddress(); |
66 | 410 | if (file_base_addr == LLDB_INVALID_ADDRESS) |
67 | 0 | return false; |
68 | | |
69 | 410 | addr_t file_addr = addr.GetFileAddress(); |
70 | 410 | if (file_addr == LLDB_INVALID_ADDRESS) |
71 | 0 | return false; |
72 | | |
73 | 410 | if (file_base_addr <= file_addr) |
74 | 108 | return (file_addr - file_base_addr) < GetByteSize(); |
75 | | |
76 | 302 | return false; |
77 | 410 | } |
78 | | |
79 | 2.99M | bool AddressRange::ContainsFileAddress(addr_t file_addr) const { |
80 | 2.99M | if (file_addr == LLDB_INVALID_ADDRESS) |
81 | 0 | return false; |
82 | | |
83 | 2.99M | addr_t file_base_addr = GetBaseAddress().GetFileAddress(); |
84 | 2.99M | if (file_base_addr == LLDB_INVALID_ADDRESS) |
85 | 0 | return false; |
86 | | |
87 | 2.99M | if (file_base_addr <= file_addr) |
88 | 2.99M | return (file_addr - file_base_addr) < GetByteSize(); |
89 | | |
90 | 0 | return false; |
91 | 2.99M | } |
92 | | |
93 | | bool AddressRange::ContainsLoadAddress(const Address &addr, |
94 | 262k | Target *target) const { |
95 | 262k | if (addr.GetSection() == m_base_addr.GetSection()) |
96 | 76.0k | return (addr.GetOffset() - m_base_addr.GetOffset()) < GetByteSize(); |
97 | 186k | addr_t load_base_addr = GetBaseAddress().GetLoadAddress(target); |
98 | 186k | if (load_base_addr == LLDB_INVALID_ADDRESS) |
99 | 7 | return false; |
100 | | |
101 | 186k | addr_t load_addr = addr.GetLoadAddress(target); |
102 | 186k | if (load_addr == LLDB_INVALID_ADDRESS) |
103 | 0 | return false; |
104 | | |
105 | 186k | if (load_base_addr <= load_addr) |
106 | 185k | return (load_addr - load_base_addr) < GetByteSize(); |
107 | | |
108 | 498 | return false; |
109 | 186k | } |
110 | | |
111 | 2.54k | bool AddressRange::ContainsLoadAddress(addr_t load_addr, Target *target) const { |
112 | 2.54k | if (load_addr == LLDB_INVALID_ADDRESS) |
113 | 0 | return false; |
114 | | |
115 | 2.54k | addr_t load_base_addr = GetBaseAddress().GetLoadAddress(target); |
116 | 2.54k | if (load_base_addr == LLDB_INVALID_ADDRESS) |
117 | 0 | return false; |
118 | | |
119 | 2.54k | if (load_base_addr <= load_addr) |
120 | 2.49k | return (load_addr - load_base_addr) < GetByteSize(); |
121 | | |
122 | 53 | return false; |
123 | 2.54k | } |
124 | | |
125 | 380 | bool AddressRange::Extend(const AddressRange &rhs_range) { |
126 | 380 | addr_t lhs_end_addr = GetBaseAddress().GetFileAddress() + GetByteSize(); |
127 | 380 | addr_t rhs_base_addr = rhs_range.GetBaseAddress().GetFileAddress(); |
128 | | |
129 | 380 | if (!ContainsFileAddress(rhs_range.GetBaseAddress()) && |
130 | 380 | lhs_end_addr != rhs_base_addr) |
131 | | // The ranges don't intersect at all on the right side of this range. |
132 | 0 | return false; |
133 | | |
134 | 380 | addr_t rhs_end_addr = rhs_base_addr + rhs_range.GetByteSize(); |
135 | 380 | if (lhs_end_addr >= rhs_end_addr) |
136 | | // The rhs range totally overlaps this one, nothing to add. |
137 | 0 | return false; |
138 | | |
139 | 380 | m_byte_size += rhs_end_addr - lhs_end_addr; |
140 | 380 | return true; |
141 | 380 | } |
142 | | |
143 | 5.72M | void AddressRange::Clear() { |
144 | 5.72M | m_base_addr.Clear(); |
145 | 5.72M | m_byte_size = 0; |
146 | 5.72M | } |
147 | | |
148 | | bool AddressRange::Dump(Stream *s, Target *target, Address::DumpStyle style, |
149 | 567 | Address::DumpStyle fallback_style) const { |
150 | 567 | addr_t vmaddr = LLDB_INVALID_ADDRESS; |
151 | 567 | int addr_size = sizeof(addr_t); |
152 | 567 | if (target) |
153 | 275 | addr_size = target->GetArchitecture().GetAddressByteSize(); |
154 | | |
155 | 567 | bool show_module = false; |
156 | 567 | switch (style) { |
157 | 0 | default: |
158 | 0 | break; |
159 | 15 | case Address::DumpStyleSectionNameOffset: |
160 | 15 | case Address::DumpStyleSectionPointerOffset: |
161 | 15 | s->PutChar('['); |
162 | 15 | m_base_addr.Dump(s, target, style, fallback_style); |
163 | 15 | s->PutChar('-'); |
164 | 15 | DumpAddress(s->AsRawOstream(), m_base_addr.GetOffset() + GetByteSize(), |
165 | 15 | addr_size); |
166 | 15 | s->PutChar(')'); |
167 | 15 | return true; |
168 | 0 | break; |
169 | | |
170 | 2 | case Address::DumpStyleModuleWithFileAddress: |
171 | 2 | show_module = true; |
172 | 2 | [[fallthrough]]; |
173 | 248 | case Address::DumpStyleFileAddress: |
174 | 248 | vmaddr = m_base_addr.GetFileAddress(); |
175 | 248 | break; |
176 | | |
177 | 304 | case Address::DumpStyleLoadAddress: |
178 | 304 | vmaddr = m_base_addr.GetLoadAddress(target); |
179 | 304 | break; |
180 | 567 | } |
181 | | |
182 | 552 | if (vmaddr != LLDB_INVALID_ADDRESS) { |
183 | 304 | if (show_module) { |
184 | 2 | ModuleSP module_sp(GetBaseAddress().GetModule()); |
185 | 2 | if (module_sp) |
186 | 2 | s->Printf("%s", module_sp->GetFileSpec().GetFilename().AsCString( |
187 | 2 | "<Unknown>")); |
188 | 2 | } |
189 | 304 | DumpAddressRange(s->AsRawOstream(), vmaddr, vmaddr + GetByteSize(), |
190 | 304 | addr_size); |
191 | 304 | return true; |
192 | 304 | } else if (248 fallback_style != Address::DumpStyleInvalid248 ) { |
193 | 248 | return Dump(s, target, fallback_style, Address::DumpStyleInvalid); |
194 | 248 | } |
195 | | |
196 | 0 | return false; |
197 | 552 | } |
198 | | |
199 | 0 | void AddressRange::DumpDebug(Stream *s) const { |
200 | 0 | s->Printf("%p: AddressRange section = %p, offset = 0x%16.16" PRIx64 |
201 | 0 | ", byte_size = 0x%16.16" PRIx64 "\n", |
202 | 0 | static_cast<const void *>(this), |
203 | 0 | static_cast<void *>(m_base_addr.GetSection().get()), |
204 | 0 | m_base_addr.GetOffset(), GetByteSize()); |
205 | 0 | } |