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 AddressRange::AddressRange() : m_base_addr() {} 32 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) {} 36 37 AddressRange::AddressRange(const lldb::SectionSP §ion, addr_t offset, 38 addr_t byte_size) 39 : m_base_addr(section, offset), m_byte_size(byte_size) {} 40 41 AddressRange::AddressRange(const Address &so_addr, addr_t byte_size) 42 : m_base_addr(so_addr), m_byte_size(byte_size) {} 43 44 AddressRange::~AddressRange() = default; 45 46 bool AddressRange::Contains(const Address &addr) const { 47 SectionSP range_sect_sp = GetBaseAddress().GetSection(); 48 SectionSP addr_sect_sp = addr.GetSection(); 49 if (range_sect_sp) { 50 if (!addr_sect_sp || 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 55 // section 56 } 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); 60 } 61 62 // 63 // bool 64 // AddressRange::Contains (const Address *addr) const 65 //{ 66 // if (addr) 67 // return Contains (*addr); 68 // return false; 69 //} 70 71 bool AddressRange::ContainsFileAddress(const Address &addr) const { 72 if (addr.GetSection() == m_base_addr.GetSection()) 73 return (addr.GetOffset() - m_base_addr.GetOffset()) < GetByteSize(); 74 addr_t file_base_addr = GetBaseAddress().GetFileAddress(); 75 if (file_base_addr == LLDB_INVALID_ADDRESS) 76 return false; 77 78 addr_t file_addr = addr.GetFileAddress(); 79 if (file_addr == LLDB_INVALID_ADDRESS) 80 return false; 81 82 if (file_base_addr <= file_addr) 83 return (file_addr - file_base_addr) < GetByteSize(); 84 85 return false; 86 } 87 88 bool AddressRange::ContainsFileAddress(addr_t file_addr) const { 89 if (file_addr == LLDB_INVALID_ADDRESS) 90 return false; 91 92 addr_t file_base_addr = GetBaseAddress().GetFileAddress(); 93 if (file_base_addr == LLDB_INVALID_ADDRESS) 94 return false; 95 96 if (file_base_addr <= file_addr) 97 return (file_addr - file_base_addr) < GetByteSize(); 98 99 return false; 100 } 101 102 bool AddressRange::ContainsLoadAddress(const Address &addr, 103 Target *target) const { 104 if (addr.GetSection() == m_base_addr.GetSection()) 105 return (addr.GetOffset() - m_base_addr.GetOffset()) < GetByteSize(); 106 addr_t load_base_addr = GetBaseAddress().GetLoadAddress(target); 107 if (load_base_addr == LLDB_INVALID_ADDRESS) 108 return false; 109 110 addr_t load_addr = addr.GetLoadAddress(target); 111 if (load_addr == LLDB_INVALID_ADDRESS) 112 return false; 113 114 if (load_base_addr <= load_addr) 115 return (load_addr - load_base_addr) < GetByteSize(); 116 117 return false; 118 } 119 120 bool AddressRange::ContainsLoadAddress(addr_t load_addr, Target *target) const { 121 if (load_addr == LLDB_INVALID_ADDRESS) 122 return false; 123 124 addr_t load_base_addr = GetBaseAddress().GetLoadAddress(target); 125 if (load_base_addr == LLDB_INVALID_ADDRESS) 126 return false; 127 128 if (load_base_addr <= load_addr) 129 return (load_addr - load_base_addr) < GetByteSize(); 130 131 return false; 132 } 133 134 bool AddressRange::Extend(const AddressRange &rhs_range) { 135 addr_t lhs_end_addr = GetBaseAddress().GetFileAddress() + GetByteSize(); 136 addr_t rhs_base_addr = rhs_range.GetBaseAddress().GetFileAddress(); 137 138 if (!ContainsFileAddress(rhs_range.GetBaseAddress()) && 139 lhs_end_addr != rhs_base_addr) 140 // The ranges don't intersect at all on the right side of this range. 141 return false; 142 143 addr_t rhs_end_addr = rhs_base_addr + rhs_range.GetByteSize(); 144 if (lhs_end_addr >= rhs_end_addr) 145 // The rhs range totally overlaps this one, nothing to add. 146 return false; 147 148 m_byte_size += rhs_end_addr - lhs_end_addr; 149 return true; 150 } 151 152 void AddressRange::Clear() { 153 m_base_addr.Clear(); 154 m_byte_size = 0; 155 } 156 157 bool AddressRange::Dump(Stream *s, Target *target, Address::DumpStyle style, 158 Address::DumpStyle fallback_style) const { 159 addr_t vmaddr = LLDB_INVALID_ADDRESS; 160 int addr_size = sizeof(addr_t); 161 if (target) 162 addr_size = target->GetArchitecture().GetAddressByteSize(); 163 164 bool show_module = false; 165 switch (style) { 166 default: 167 break; 168 case Address::DumpStyleSectionNameOffset: 169 case Address::DumpStyleSectionPointerOffset: 170 s->PutChar('['); 171 m_base_addr.Dump(s, target, style, fallback_style); 172 s->PutChar('-'); 173 DumpAddress(s->AsRawOstream(), m_base_addr.GetOffset() + GetByteSize(), 174 addr_size); 175 s->PutChar(')'); 176 return true; 177 break; 178 179 case Address::DumpStyleModuleWithFileAddress: 180 show_module = true; 181 LLVM_FALLTHROUGH; 182 case Address::DumpStyleFileAddress: 183 vmaddr = m_base_addr.GetFileAddress(); 184 break; 185 186 case Address::DumpStyleLoadAddress: 187 vmaddr = m_base_addr.GetLoadAddress(target); 188 break; 189 } 190 191 if (vmaddr != LLDB_INVALID_ADDRESS) { 192 if (show_module) { 193 ModuleSP module_sp(GetBaseAddress().GetModule()); 194 if (module_sp) 195 s->Printf("%s", module_sp->GetFileSpec().GetFilename().AsCString( 196 "<Unknown>")); 197 } 198 DumpAddressRange(s->AsRawOstream(), vmaddr, vmaddr + GetByteSize(), 199 addr_size); 200 return true; 201 } else if (fallback_style != Address::DumpStyleInvalid) { 202 return Dump(s, target, fallback_style, Address::DumpStyleInvalid); 203 } 204 205 return false; 206 } 207 208 void AddressRange::DumpDebug(Stream *s) const { 209 s->Printf("%p: AddressRange section = %p, offset = 0x%16.16" PRIx64 210 ", byte_size = 0x%16.16" PRIx64 "\n", 211 static_cast<const void *>(this), 212 static_cast<void *>(m_base_addr.GetSection().get()), 213 m_base_addr.GetOffset(), GetByteSize()); 214 } 215 // 216 // bool 217 // lldb::operator== (const AddressRange& lhs, const AddressRange& rhs) 218 //{ 219 // if (lhs.GetBaseAddress() == rhs.GetBaseAddress()) 220 // return lhs.GetByteSize() == rhs.GetByteSize(); 221 // return false; 222 //} 223