1 //===-- AddressRange.cpp --------------------------------------------------===//
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 "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 #include "lldb/lldb-types.h"
19 #include "llvm/Support/Compiler.h"
25 namespace lldb_private
{
30 using namespace lldb_private
;
32 AddressRange::AddressRange() : m_base_addr() {}
34 AddressRange::AddressRange(addr_t file_addr
, addr_t byte_size
,
35 const SectionList
*section_list
)
36 : m_base_addr(file_addr
, section_list
), m_byte_size(byte_size
) {}
38 AddressRange::AddressRange(const lldb::SectionSP
§ion
, addr_t offset
,
40 : m_base_addr(section
, offset
), m_byte_size(byte_size
) {}
42 AddressRange::AddressRange(const Address
&so_addr
, addr_t byte_size
)
43 : m_base_addr(so_addr
), m_byte_size(byte_size
) {}
45 AddressRange::~AddressRange() = default;
47 bool AddressRange::Contains(const Address
&addr
) const {
48 SectionSP range_sect_sp
= GetBaseAddress().GetSection();
49 SectionSP addr_sect_sp
= addr
.GetSection();
52 range_sect_sp
->GetModule() != addr_sect_sp
->GetModule())
53 return false; // Modules do not match.
54 } else if (addr_sect_sp
) {
55 return false; // Range has no module but "addr" does because addr has a
58 // Either the modules match, or both have no module, so it is ok to compare
59 // the file addresses in this case only.
60 return ContainsFileAddress(addr
);
63 bool AddressRange::ContainsFileAddress(const Address
&addr
) const {
64 if (addr
.GetSection() == m_base_addr
.GetSection())
65 return (addr
.GetOffset() - m_base_addr
.GetOffset()) < GetByteSize();
66 addr_t file_base_addr
= GetBaseAddress().GetFileAddress();
67 if (file_base_addr
== LLDB_INVALID_ADDRESS
)
70 addr_t file_addr
= addr
.GetFileAddress();
71 if (file_addr
== LLDB_INVALID_ADDRESS
)
74 if (file_base_addr
<= file_addr
)
75 return (file_addr
- file_base_addr
) < GetByteSize();
80 bool AddressRange::ContainsFileAddress(addr_t file_addr
) const {
81 if (file_addr
== LLDB_INVALID_ADDRESS
)
84 addr_t file_base_addr
= GetBaseAddress().GetFileAddress();
85 if (file_base_addr
== LLDB_INVALID_ADDRESS
)
88 if (file_base_addr
<= file_addr
)
89 return (file_addr
- file_base_addr
) < GetByteSize();
94 bool AddressRange::ContainsLoadAddress(const Address
&addr
,
95 Target
*target
) const {
96 if (addr
.GetSection() == m_base_addr
.GetSection())
97 return (addr
.GetOffset() - m_base_addr
.GetOffset()) < GetByteSize();
98 addr_t load_base_addr
= GetBaseAddress().GetLoadAddress(target
);
99 if (load_base_addr
== LLDB_INVALID_ADDRESS
)
102 addr_t load_addr
= addr
.GetLoadAddress(target
);
103 if (load_addr
== LLDB_INVALID_ADDRESS
)
106 if (load_base_addr
<= load_addr
)
107 return (load_addr
- load_base_addr
) < GetByteSize();
112 bool AddressRange::ContainsLoadAddress(addr_t load_addr
, Target
*target
) const {
113 if (load_addr
== LLDB_INVALID_ADDRESS
)
116 addr_t load_base_addr
= GetBaseAddress().GetLoadAddress(target
);
117 if (load_base_addr
== LLDB_INVALID_ADDRESS
)
120 if (load_base_addr
<= load_addr
)
121 return (load_addr
- load_base_addr
) < GetByteSize();
126 bool AddressRange::Extend(const AddressRange
&rhs_range
) {
127 addr_t lhs_end_addr
= GetBaseAddress().GetFileAddress() + GetByteSize();
128 addr_t rhs_base_addr
= rhs_range
.GetBaseAddress().GetFileAddress();
130 if (!ContainsFileAddress(rhs_range
.GetBaseAddress()) &&
131 lhs_end_addr
!= rhs_base_addr
)
132 // The ranges don't intersect at all on the right side of this range.
135 addr_t rhs_end_addr
= rhs_base_addr
+ rhs_range
.GetByteSize();
136 if (lhs_end_addr
>= rhs_end_addr
)
137 // The rhs range totally overlaps this one, nothing to add.
140 m_byte_size
+= rhs_end_addr
- lhs_end_addr
;
144 void AddressRange::Clear() {
149 bool AddressRange::IsValid() const {
150 return m_base_addr
.IsValid() && (m_byte_size
> 0);
153 bool AddressRange::Dump(Stream
*s
, Target
*target
, Address::DumpStyle style
,
154 Address::DumpStyle fallback_style
) const {
155 addr_t vmaddr
= LLDB_INVALID_ADDRESS
;
156 int addr_size
= sizeof(addr_t
);
158 addr_size
= target
->GetArchitecture().GetAddressByteSize();
160 bool show_module
= false;
164 case Address::DumpStyleSectionNameOffset
:
165 case Address::DumpStyleSectionPointerOffset
:
167 m_base_addr
.Dump(s
, target
, style
, fallback_style
);
169 DumpAddress(s
->AsRawOstream(), m_base_addr
.GetOffset() + GetByteSize(),
175 case Address::DumpStyleModuleWithFileAddress
:
178 case Address::DumpStyleFileAddress
:
179 vmaddr
= m_base_addr
.GetFileAddress();
182 case Address::DumpStyleLoadAddress
:
183 vmaddr
= m_base_addr
.GetLoadAddress(target
);
187 if (vmaddr
!= LLDB_INVALID_ADDRESS
) {
189 ModuleSP
module_sp(GetBaseAddress().GetModule());
191 s
->Printf("%s", module_sp
->GetFileSpec().GetFilename().AsCString(
194 DumpAddressRange(s
->AsRawOstream(), vmaddr
, vmaddr
+ GetByteSize(),
197 } else if (fallback_style
!= Address::DumpStyleInvalid
) {
198 return Dump(s
, target
, fallback_style
, Address::DumpStyleInvalid
);
204 void AddressRange::DumpDebug(Stream
*s
) const {
205 s
->Printf("%p: AddressRange section = %p, offset = 0x%16.16" PRIx64
206 ", byte_size = 0x%16.16" PRIx64
"\n",
207 static_cast<const void *>(this),
208 static_cast<void *>(m_base_addr
.GetSection().get()),
209 m_base_addr
.GetOffset(), GetByteSize());
212 bool AddressRange::GetDescription(Stream
*s
, Target
*target
) const {
213 addr_t start_addr
= m_base_addr
.GetLoadAddress(target
);
214 if (start_addr
!= LLDB_INVALID_ADDRESS
) {
215 // We have a valid target and the address was resolved, or we have a base
216 // address with no section. Just print out a raw address range: [<addr>,
218 s
->Printf("[0x%" PRIx64
"-0x%" PRIx64
")", start_addr
,
219 start_addr
+ GetByteSize());
223 // Either no target or the address wasn't resolved, print as
224 // <module>[<file-addr>-<file-addr>)
225 const char *file_name
= "";
226 const auto section_sp
= m_base_addr
.GetSection();
228 if (const auto object_file
= section_sp
->GetObjectFile())
229 file_name
= object_file
->GetFileSpec().GetFilename().AsCString();
231 start_addr
= m_base_addr
.GetFileAddress();
232 const addr_t end_addr
= (start_addr
== LLDB_INVALID_ADDRESS
)
233 ? LLDB_INVALID_ADDRESS
234 : start_addr
+ GetByteSize();
235 s
->Printf("%s[0x%" PRIx64
"-0x%" PRIx64
")", file_name
, start_addr
, end_addr
);
239 bool AddressRange::operator==(const AddressRange
&rhs
) {
240 if (!IsValid() || !rhs
.IsValid())
242 return m_base_addr
== rhs
.GetBaseAddress() &&
243 m_byte_size
== rhs
.GetByteSize();
246 bool AddressRange::operator!=(const AddressRange
&rhs
) {
247 return !(*this == rhs
);