brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.9 KiB · 315fcf1 Raw
252 lines · cpp
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-exception6//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#include "lldb/lldb-types.h"18 19#include "llvm/Support/Compiler.h"20 21#include <memory>22 23#include <cinttypes>24 25namespace lldb_private {26class SectionList;27}28 29using namespace lldb;30using namespace lldb_private;31 32AddressRange::AddressRange() : m_base_addr() {}33 34AddressRange::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) {}37 38AddressRange::AddressRange(const lldb::SectionSP &section, addr_t offset,39                           addr_t byte_size)40    : m_base_addr(section, offset), m_byte_size(byte_size) {}41 42AddressRange::AddressRange(const Address &so_addr, addr_t byte_size)43    : m_base_addr(so_addr), m_byte_size(byte_size) {}44 45AddressRange::~AddressRange() = default;46 47bool AddressRange::Contains(const Address &addr) const {48  SectionSP range_sect_sp = GetBaseAddress().GetSection();49  SectionSP addr_sect_sp = addr.GetSection();50  if (range_sect_sp) {51    if (!addr_sect_sp ||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 a56                  // section57  }58  // Either the modules match, or both have no module, so it is ok to compare59  // the file addresses in this case only.60  return ContainsFileAddress(addr);61}62 63bool 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)68    return false;69 70  addr_t file_addr = addr.GetFileAddress();71  if (file_addr == LLDB_INVALID_ADDRESS)72    return false;73 74  if (file_base_addr <= file_addr)75    return (file_addr - file_base_addr) < GetByteSize();76 77  return false;78}79 80bool AddressRange::ContainsFileAddress(addr_t file_addr) const {81  if (file_addr == LLDB_INVALID_ADDRESS)82    return false;83 84  addr_t file_base_addr = GetBaseAddress().GetFileAddress();85  if (file_base_addr == LLDB_INVALID_ADDRESS)86    return false;87 88  if (file_base_addr <= file_addr)89    return (file_addr - file_base_addr) < GetByteSize();90 91  return false;92}93 94bool 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)100    return false;101 102  addr_t load_addr = addr.GetLoadAddress(target);103  if (load_addr == LLDB_INVALID_ADDRESS)104    return false;105 106  if (load_base_addr <= load_addr)107    return (load_addr - load_base_addr) < GetByteSize();108 109  return false;110}111 112bool AddressRange::ContainsLoadAddress(addr_t load_addr, Target *target) const {113  if (load_addr == LLDB_INVALID_ADDRESS)114    return false;115 116  addr_t load_base_addr = GetBaseAddress().GetLoadAddress(target);117  if (load_base_addr == LLDB_INVALID_ADDRESS)118    return false;119 120  if (load_base_addr <= load_addr)121    return (load_addr - load_base_addr) < GetByteSize();122 123  return false;124}125 126bool 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();129 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.133    return false;134 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.138    return false;139 140  m_byte_size += rhs_end_addr - lhs_end_addr;141  return true;142}143 144void AddressRange::Clear() {145  m_base_addr.Clear();146  m_byte_size = 0;147}148 149bool AddressRange::IsValid() const {150  return m_base_addr.IsValid() && (m_byte_size > 0);151}152 153bool 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);157  if (target)158    addr_size = target->GetArchitecture().GetAddressByteSize();159 160  bool show_module = false;161  switch (style) {162  default:163    break;164  case Address::DumpStyleSectionNameOffset:165  case Address::DumpStyleSectionPointerOffset: {166    s->PutChar('[');167    m_base_addr.Dump(s, target, style, fallback_style);168    s->PutChar('-');169    addr_t end = m_base_addr.GetOffset() + GetByteSize();170    if (m_base_addr.GetSection())171      s->Format("{0}", end);172    else173      DumpAddress(s->AsRawOstream(), end, addr_size);174    s->PutChar(')');175    return true;176  }177 178  case Address::DumpStyleModuleWithFileAddress:179    show_module = true;180    [[fallthrough]];181  case Address::DumpStyleFileAddress:182    vmaddr = m_base_addr.GetFileAddress();183    break;184 185  case Address::DumpStyleLoadAddress:186    vmaddr = m_base_addr.GetLoadAddress(target);187    break;188  }189 190  if (vmaddr != LLDB_INVALID_ADDRESS) {191    if (show_module) {192      ModuleSP module_sp(GetBaseAddress().GetModule());193      if (module_sp)194        s->Printf("%s", module_sp->GetFileSpec().GetFilename().AsCString(195                            "<Unknown>"));196    }197    DumpAddressRange(s->AsRawOstream(), vmaddr, vmaddr + GetByteSize(),198                     addr_size);199    return true;200  } else if (fallback_style != Address::DumpStyleInvalid) {201    return Dump(s, target, fallback_style, Address::DumpStyleInvalid);202  }203 204  return false;205}206 207void AddressRange::DumpDebug(Stream *s) const {208  s->Printf("%p: AddressRange section = %p, offset = 0x%16.16" PRIx64209            ", byte_size = 0x%16.16" PRIx64 "\n",210            static_cast<const void *>(this),211            static_cast<void *>(m_base_addr.GetSection().get()),212            m_base_addr.GetOffset(), GetByteSize());213}214 215bool AddressRange::GetDescription(Stream *s, Target *target) const {216  addr_t start_addr = m_base_addr.GetLoadAddress(target);217  if (start_addr != LLDB_INVALID_ADDRESS) {218    // We have a valid target and the address was resolved, or we have a base219    // address with no section. Just print out a raw address range: [<addr>,220    // <addr>)221    s->Printf("[0x%" PRIx64 "-0x%" PRIx64 ")", start_addr,222              start_addr + GetByteSize());223    return true;224  }225 226  // Either no target or the address wasn't resolved, print as227  // <module>[<file-addr>-<file-addr>)228  const char *file_name = "";229  const auto section_sp = m_base_addr.GetSection();230  if (section_sp) {231    if (const auto object_file = section_sp->GetObjectFile())232      file_name = object_file->GetFileSpec().GetFilename().AsCString();233  }234  start_addr = m_base_addr.GetFileAddress();235  const addr_t end_addr = (start_addr == LLDB_INVALID_ADDRESS)236                              ? LLDB_INVALID_ADDRESS237                              : start_addr + GetByteSize();238  s->Printf("%s[0x%" PRIx64 "-0x%" PRIx64 ")", file_name, start_addr, end_addr);239  return true;240}241 242bool AddressRange::operator==(const AddressRange &rhs) {243  if (!IsValid() || !rhs.IsValid())244    return false;245  return m_base_addr == rhs.GetBaseAddress() &&246         m_byte_size == rhs.GetByteSize();247}248 249bool AddressRange::operator!=(const AddressRange &rhs) {250  return !(*this == rhs);251}252