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"
18 #include "llvm/Support/Compiler.h"
24 namespace lldb_private
{
29 using namespace lldb_private
;
31 AddressRange::AddressRange() : m_base_addr() {}
33 AddressRange::AddressRange(addr_t file_addr
, addr_t byte_size
,
34 const SectionList
*section_list
)
35 : m_base_addr(file_addr
, section_list
), m_byte_size(byte_size
) {}
37 AddressRange::AddressRange(const lldb::SectionSP
§ion
, addr_t offset
,
39 : m_base_addr(section
, offset
), m_byte_size(byte_size
) {}
41 AddressRange::AddressRange(const Address
&so_addr
, addr_t byte_size
)
42 : m_base_addr(so_addr
), m_byte_size(byte_size
) {}
44 AddressRange::~AddressRange() = default;
46 bool AddressRange::Contains(const Address
&addr
) const {
47 SectionSP range_sect_sp
= GetBaseAddress().GetSection();
48 SectionSP addr_sect_sp
= addr
.GetSection();
51 range_sect_sp
->GetModule() != addr_sect_sp
->GetModule())
52 return false; // Modules do not match.
53 } else if (addr_sect_sp
) {
54 return false; // Range has no module but "addr" does because addr has a
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 return ContainsFileAddress(addr
);
62 bool AddressRange::ContainsFileAddress(const Address
&addr
) const {
63 if (addr
.GetSection() == m_base_addr
.GetSection())
64 return (addr
.GetOffset() - m_base_addr
.GetOffset()) < GetByteSize();
65 addr_t file_base_addr
= GetBaseAddress().GetFileAddress();
66 if (file_base_addr
== LLDB_INVALID_ADDRESS
)
69 addr_t file_addr
= addr
.GetFileAddress();
70 if (file_addr
== LLDB_INVALID_ADDRESS
)
73 if (file_base_addr
<= file_addr
)
74 return (file_addr
- file_base_addr
) < GetByteSize();
79 bool AddressRange::ContainsFileAddress(addr_t file_addr
) const {
80 if (file_addr
== LLDB_INVALID_ADDRESS
)
83 addr_t file_base_addr
= GetBaseAddress().GetFileAddress();
84 if (file_base_addr
== LLDB_INVALID_ADDRESS
)
87 if (file_base_addr
<= file_addr
)
88 return (file_addr
- file_base_addr
) < GetByteSize();
93 bool AddressRange::ContainsLoadAddress(const Address
&addr
,
94 Target
*target
) const {
95 if (addr
.GetSection() == m_base_addr
.GetSection())
96 return (addr
.GetOffset() - m_base_addr
.GetOffset()) < GetByteSize();
97 addr_t load_base_addr
= GetBaseAddress().GetLoadAddress(target
);
98 if (load_base_addr
== LLDB_INVALID_ADDRESS
)
101 addr_t load_addr
= addr
.GetLoadAddress(target
);
102 if (load_addr
== LLDB_INVALID_ADDRESS
)
105 if (load_base_addr
<= load_addr
)
106 return (load_addr
- load_base_addr
) < GetByteSize();
111 bool AddressRange::ContainsLoadAddress(addr_t load_addr
, Target
*target
) const {
112 if (load_addr
== LLDB_INVALID_ADDRESS
)
115 addr_t load_base_addr
= GetBaseAddress().GetLoadAddress(target
);
116 if (load_base_addr
== LLDB_INVALID_ADDRESS
)
119 if (load_base_addr
<= load_addr
)
120 return (load_addr
- load_base_addr
) < GetByteSize();
125 bool AddressRange::Extend(const AddressRange
&rhs_range
) {
126 addr_t lhs_end_addr
= GetBaseAddress().GetFileAddress() + GetByteSize();
127 addr_t rhs_base_addr
= rhs_range
.GetBaseAddress().GetFileAddress();
129 if (!ContainsFileAddress(rhs_range
.GetBaseAddress()) &&
130 lhs_end_addr
!= rhs_base_addr
)
131 // The ranges don't intersect at all on the right side of this range.
134 addr_t rhs_end_addr
= rhs_base_addr
+ rhs_range
.GetByteSize();
135 if (lhs_end_addr
>= rhs_end_addr
)
136 // The rhs range totally overlaps this one, nothing to add.
139 m_byte_size
+= rhs_end_addr
- lhs_end_addr
;
143 void AddressRange::Clear() {
148 bool AddressRange::Dump(Stream
*s
, Target
*target
, Address::DumpStyle style
,
149 Address::DumpStyle fallback_style
) const {
150 addr_t vmaddr
= LLDB_INVALID_ADDRESS
;
151 int addr_size
= sizeof(addr_t
);
153 addr_size
= target
->GetArchitecture().GetAddressByteSize();
155 bool show_module
= false;
159 case Address::DumpStyleSectionNameOffset
:
160 case Address::DumpStyleSectionPointerOffset
:
162 m_base_addr
.Dump(s
, target
, style
, fallback_style
);
164 DumpAddress(s
->AsRawOstream(), m_base_addr
.GetOffset() + GetByteSize(),
170 case Address::DumpStyleModuleWithFileAddress
:
173 case Address::DumpStyleFileAddress
:
174 vmaddr
= m_base_addr
.GetFileAddress();
177 case Address::DumpStyleLoadAddress
:
178 vmaddr
= m_base_addr
.GetLoadAddress(target
);
182 if (vmaddr
!= LLDB_INVALID_ADDRESS
) {
184 ModuleSP
module_sp(GetBaseAddress().GetModule());
186 s
->Printf("%s", module_sp
->GetFileSpec().GetFilename().AsCString(
189 DumpAddressRange(s
->AsRawOstream(), vmaddr
, vmaddr
+ GetByteSize(),
192 } else if (fallback_style
!= Address::DumpStyleInvalid
) {
193 return Dump(s
, target
, fallback_style
, Address::DumpStyleInvalid
);
199 void AddressRange::DumpDebug(Stream
*s
) const {
200 s
->Printf("%p: AddressRange section = %p, offset = 0x%16.16" PRIx64
201 ", byte_size = 0x%16.16" PRIx64
"\n",
202 static_cast<const void *>(this),
203 static_cast<void *>(m_base_addr
.GetSection().get()),
204 m_base_addr
.GetOffset(), GetByteSize());