1254721Semaste//===-- AddressRange.cpp ----------------------------------------*- C++ -*-===// 2254721Semaste// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6254721Semaste// 7254721Semaste//===----------------------------------------------------------------------===// 8254721Semaste 9254721Semaste#include "lldb/Core/AddressRange.h" 10254721Semaste#include "lldb/Core/Module.h" 11254721Semaste#include "lldb/Target/Target.h" 12344779Sdim#include "lldb/Utility/ConstString.h" 13344779Sdim#include "lldb/Utility/FileSpec.h" 14321369Sdim#include "lldb/Utility/Stream.h" 15344779Sdim#include "lldb/lldb-defines.h" 16254721Semaste 17344779Sdim#include "llvm/Support/Compiler.h" 18321369Sdim 19344779Sdim#include <memory> 20321369Sdim 21344779Sdim#include <inttypes.h> 22321369Sdim 23321369Sdimnamespace lldb_private { 24321369Sdimclass SectionList; 25321369Sdim} 26321369Sdim 27254721Semasteusing namespace lldb; 28254721Semasteusing namespace lldb_private; 29254721Semaste 30314564SdimAddressRange::AddressRange() : m_base_addr(), m_byte_size(0) {} 31254721Semaste 32314564SdimAddressRange::AddressRange(addr_t file_addr, addr_t byte_size, 33314564Sdim const SectionList *section_list) 34314564Sdim : m_base_addr(file_addr, section_list), m_byte_size(byte_size) {} 35254721Semaste 36314564SdimAddressRange::AddressRange(const lldb::SectionSP §ion, addr_t offset, 37314564Sdim addr_t byte_size) 38314564Sdim : m_base_addr(section, offset), m_byte_size(byte_size) {} 39254721Semaste 40314564SdimAddressRange::AddressRange(const Address &so_addr, addr_t byte_size) 41314564Sdim : m_base_addr(so_addr), m_byte_size(byte_size) {} 42254721Semaste 43314564SdimAddressRange::~AddressRange() {} 44254721Semaste 45314564Sdim// bool 46314564Sdim// AddressRange::Contains (const Address &addr) const 47254721Semaste//{ 48254721Semaste// const addr_t byte_size = GetByteSize(); 49254721Semaste// if (byte_size) 50314564Sdim// return addr.GetSection() == m_base_addr.GetSection() && 51314564Sdim// (addr.GetOffset() - m_base_addr.GetOffset()) < byte_size; 52254721Semaste//} 53254721Semaste// 54314564Sdim// bool 55314564Sdim// AddressRange::Contains (const Address *addr) const 56254721Semaste//{ 57254721Semaste// if (addr) 58254721Semaste// return Contains (*addr); 59254721Semaste// return false; 60254721Semaste//} 61254721Semaste 62314564Sdimbool AddressRange::ContainsFileAddress(const Address &addr) const { 63314564Sdim if (addr.GetSection() == m_base_addr.GetSection()) 64314564Sdim return (addr.GetOffset() - m_base_addr.GetOffset()) < GetByteSize(); 65314564Sdim addr_t file_base_addr = GetBaseAddress().GetFileAddress(); 66314564Sdim if (file_base_addr == LLDB_INVALID_ADDRESS) 67314564Sdim return false; 68254721Semaste 69314564Sdim addr_t file_addr = addr.GetFileAddress(); 70314564Sdim if (file_addr == LLDB_INVALID_ADDRESS) 71314564Sdim return false; 72254721Semaste 73314564Sdim if (file_base_addr <= file_addr) 74314564Sdim return (file_addr - file_base_addr) < GetByteSize(); 75254721Semaste 76314564Sdim return false; 77254721Semaste} 78254721Semaste 79314564Sdimbool AddressRange::ContainsFileAddress(addr_t file_addr) const { 80314564Sdim if (file_addr == LLDB_INVALID_ADDRESS) 81314564Sdim return false; 82254721Semaste 83314564Sdim addr_t file_base_addr = GetBaseAddress().GetFileAddress(); 84314564Sdim if (file_base_addr == LLDB_INVALID_ADDRESS) 85314564Sdim return false; 86254721Semaste 87314564Sdim if (file_base_addr <= file_addr) 88314564Sdim return (file_addr - file_base_addr) < GetByteSize(); 89254721Semaste 90314564Sdim return false; 91254721Semaste} 92254721Semaste 93314564Sdimbool AddressRange::ContainsLoadAddress(const Address &addr, 94314564Sdim Target *target) const { 95314564Sdim if (addr.GetSection() == m_base_addr.GetSection()) 96314564Sdim return (addr.GetOffset() - m_base_addr.GetOffset()) < GetByteSize(); 97314564Sdim addr_t load_base_addr = GetBaseAddress().GetLoadAddress(target); 98314564Sdim if (load_base_addr == LLDB_INVALID_ADDRESS) 99314564Sdim return false; 100254721Semaste 101314564Sdim addr_t load_addr = addr.GetLoadAddress(target); 102314564Sdim if (load_addr == LLDB_INVALID_ADDRESS) 103314564Sdim return false; 104254721Semaste 105314564Sdim if (load_base_addr <= load_addr) 106314564Sdim return (load_addr - load_base_addr) < GetByteSize(); 107254721Semaste 108314564Sdim return false; 109314564Sdim} 110254721Semaste 111314564Sdimbool AddressRange::ContainsLoadAddress(addr_t load_addr, Target *target) const { 112314564Sdim if (load_addr == LLDB_INVALID_ADDRESS) 113254721Semaste return false; 114254721Semaste 115314564Sdim addr_t load_base_addr = GetBaseAddress().GetLoadAddress(target); 116314564Sdim if (load_base_addr == LLDB_INVALID_ADDRESS) 117314564Sdim return false; 118254721Semaste 119314564Sdim if (load_base_addr <= load_addr) 120314564Sdim return (load_addr - load_base_addr) < GetByteSize(); 121254721Semaste 122314564Sdim return false; 123254721Semaste} 124254721Semaste 125353358Sdimbool AddressRange::Extend(const AddressRange &rhs_range) { 126353358Sdim addr_t lhs_end_addr = GetBaseAddress().GetFileAddress() + GetByteSize(); 127353358Sdim addr_t rhs_base_addr = rhs_range.GetBaseAddress().GetFileAddress(); 128353358Sdim 129353358Sdim if (!ContainsFileAddress(rhs_range.GetBaseAddress()) && 130353358Sdim lhs_end_addr != rhs_base_addr) 131353358Sdim // The ranges don't intersect at all on the right side of this range. 132353358Sdim return false; 133353358Sdim 134353358Sdim addr_t rhs_end_addr = rhs_base_addr + rhs_range.GetByteSize(); 135353358Sdim if (lhs_end_addr >= rhs_end_addr) 136353358Sdim // The rhs range totally overlaps this one, nothing to add. 137353358Sdim return false; 138353358Sdim 139353358Sdim m_byte_size += rhs_end_addr - lhs_end_addr; 140353358Sdim return true; 141353358Sdim} 142353358Sdim 143314564Sdimvoid AddressRange::Clear() { 144314564Sdim m_base_addr.Clear(); 145314564Sdim m_byte_size = 0; 146254721Semaste} 147254721Semaste 148314564Sdimbool AddressRange::Dump(Stream *s, Target *target, Address::DumpStyle style, 149314564Sdim Address::DumpStyle fallback_style) const { 150314564Sdim addr_t vmaddr = LLDB_INVALID_ADDRESS; 151314564Sdim int addr_size = sizeof(addr_t); 152314564Sdim if (target) 153314564Sdim addr_size = target->GetArchitecture().GetAddressByteSize(); 154254721Semaste 155314564Sdim bool show_module = false; 156314564Sdim switch (style) { 157314564Sdim default: 158314564Sdim break; 159314564Sdim case Address::DumpStyleSectionNameOffset: 160314564Sdim case Address::DumpStyleSectionPointerOffset: 161314564Sdim s->PutChar('['); 162314564Sdim m_base_addr.Dump(s, target, style, fallback_style); 163314564Sdim s->PutChar('-'); 164360784Sdim DumpAddress(s->AsRawOstream(), m_base_addr.GetOffset() + GetByteSize(), 165360784Sdim addr_size); 166314564Sdim s->PutChar(')'); 167314564Sdim return true; 168314564Sdim break; 169254721Semaste 170314564Sdim case Address::DumpStyleModuleWithFileAddress: 171314564Sdim show_module = true; 172314564Sdim LLVM_FALLTHROUGH; 173314564Sdim case Address::DumpStyleFileAddress: 174314564Sdim vmaddr = m_base_addr.GetFileAddress(); 175314564Sdim break; 176254721Semaste 177314564Sdim case Address::DumpStyleLoadAddress: 178314564Sdim vmaddr = m_base_addr.GetLoadAddress(target); 179314564Sdim break; 180314564Sdim } 181254721Semaste 182314564Sdim if (vmaddr != LLDB_INVALID_ADDRESS) { 183314564Sdim if (show_module) { 184314564Sdim ModuleSP module_sp(GetBaseAddress().GetModule()); 185314564Sdim if (module_sp) 186314564Sdim s->Printf("%s", module_sp->GetFileSpec().GetFilename().AsCString( 187314564Sdim "<Unknown>")); 188254721Semaste } 189360784Sdim DumpAddressRange(s->AsRawOstream(), vmaddr, vmaddr + GetByteSize(), 190360784Sdim addr_size); 191314564Sdim return true; 192314564Sdim } else if (fallback_style != Address::DumpStyleInvalid) { 193314564Sdim return Dump(s, target, fallback_style, Address::DumpStyleInvalid); 194314564Sdim } 195254721Semaste 196314564Sdim return false; 197254721Semaste} 198254721Semaste 199314564Sdimvoid AddressRange::DumpDebug(Stream *s) const { 200314564Sdim s->Printf("%p: AddressRange section = %p, offset = 0x%16.16" PRIx64 201314564Sdim ", byte_size = 0x%16.16" PRIx64 "\n", 202314564Sdim static_cast<const void *>(this), 203314564Sdim static_cast<void *>(m_base_addr.GetSection().get()), 204314564Sdim m_base_addr.GetOffset(), GetByteSize()); 205254721Semaste} 206254721Semaste// 207314564Sdim// bool 208314564Sdim// lldb::operator== (const AddressRange& lhs, const AddressRange& rhs) 209254721Semaste//{ 210254721Semaste// if (lhs.GetBaseAddress() == rhs.GetBaseAddress()) 211254721Semaste// return lhs.GetByteSize() == rhs.GetByteSize(); 212254721Semaste// return false; 213254721Semaste//} 214