//===-- AddressRange.cpp --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Core/AddressRange.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Stream.h"
#include "lldb/lldb-defines.h"

#include "llvm/Support/Compiler.h"

#include <memory>

#include <cinttypes>

namespace lldb_private {
class SectionList;
}

using namespace lldb;
using namespace lldb_private;

AddressRange::AddressRange() : m_base_addr() {}

AddressRange::AddressRange(addr_t file_addr, addr_t byte_size,
                           const SectionList *section_list)
    : m_base_addr(file_addr, section_list), m_byte_size(byte_size) {}

AddressRange::AddressRange(const lldb::SectionSP &section, addr_t offset,
                           addr_t byte_size)
    : m_base_addr(section, offset), m_byte_size(byte_size) {}

AddressRange::AddressRange(const Address &so_addr, addr_t byte_size)
    : m_base_addr(so_addr), m_byte_size(byte_size) {}

AddressRange::~AddressRange() = default;

bool AddressRange::Contains(const Address &addr) const {
  SectionSP range_sect_sp = GetBaseAddress().GetSection();
  SectionSP addr_sect_sp = addr.GetSection();
  if (range_sect_sp) {
    if (!addr_sect_sp ||
        range_sect_sp->GetModule() != addr_sect_sp->GetModule())
      return false; // Modules do not match.
  } else if (addr_sect_sp) {
    return false; // Range has no module but "addr" does because addr has a
                  // section
  }
  // Either the modules match, or both have no module, so it is ok to compare
  // the file addresses in this case only.
  return ContainsFileAddress(addr);
}

//
// bool
// AddressRange::Contains (const Address *addr) const
//{
//    if (addr)
//        return Contains (*addr);
//    return false;
//}

bool AddressRange::ContainsFileAddress(const Address &addr) const {
  if (addr.GetSection() == m_base_addr.GetSection())
    return (addr.GetOffset() - m_base_addr.GetOffset()) < GetByteSize();
  addr_t file_base_addr = GetBaseAddress().GetFileAddress();
  if (file_base_addr == LLDB_INVALID_ADDRESS)
    return false;

  addr_t file_addr = addr.GetFileAddress();
  if (file_addr == LLDB_INVALID_ADDRESS)
    return false;

  if (file_base_addr <= file_addr)
    return (file_addr - file_base_addr) < GetByteSize();

  return false;
}

bool AddressRange::ContainsFileAddress(addr_t file_addr) const {
  if (file_addr == LLDB_INVALID_ADDRESS)
    return false;

  addr_t file_base_addr = GetBaseAddress().GetFileAddress();
  if (file_base_addr == LLDB_INVALID_ADDRESS)
    return false;

  if (file_base_addr <= file_addr)
    return (file_addr - file_base_addr) < GetByteSize();

  return false;
}

bool AddressRange::ContainsLoadAddress(const Address &addr,
                                       Target *target) const {
  if (addr.GetSection() == m_base_addr.GetSection())
    return (addr.GetOffset() - m_base_addr.GetOffset()) < GetByteSize();
  addr_t load_base_addr = GetBaseAddress().GetLoadAddress(target);
  if (load_base_addr == LLDB_INVALID_ADDRESS)
    return false;

  addr_t load_addr = addr.GetLoadAddress(target);
  if (load_addr == LLDB_INVALID_ADDRESS)
    return false;

  if (load_base_addr <= load_addr)
    return (load_addr - load_base_addr) < GetByteSize();

  return false;
}

bool AddressRange::ContainsLoadAddress(addr_t load_addr, Target *target) const {
  if (load_addr == LLDB_INVALID_ADDRESS)
    return false;

  addr_t load_base_addr = GetBaseAddress().GetLoadAddress(target);
  if (load_base_addr == LLDB_INVALID_ADDRESS)
    return false;

  if (load_base_addr <= load_addr)
    return (load_addr - load_base_addr) < GetByteSize();

  return false;
}

bool AddressRange::Extend(const AddressRange &rhs_range) {
  addr_t lhs_end_addr = GetBaseAddress().GetFileAddress() + GetByteSize();
  addr_t rhs_base_addr = rhs_range.GetBaseAddress().GetFileAddress();

  if (!ContainsFileAddress(rhs_range.GetBaseAddress()) &&
      lhs_end_addr != rhs_base_addr)
    // The ranges don't intersect at all on the right side of this range.
    return false;

  addr_t rhs_end_addr = rhs_base_addr + rhs_range.GetByteSize();
  if (lhs_end_addr >= rhs_end_addr)
    // The rhs range totally overlaps this one, nothing to add.
    return false;

  m_byte_size += rhs_end_addr - lhs_end_addr;
  return true;
}

void AddressRange::Clear() {
  m_base_addr.Clear();
  m_byte_size = 0;
}

bool AddressRange::Dump(Stream *s, Target *target, Address::DumpStyle style,
                        Address::DumpStyle fallback_style) const {
  addr_t vmaddr = LLDB_INVALID_ADDRESS;
  int addr_size = sizeof(addr_t);
  if (target)
    addr_size = target->GetArchitecture().GetAddressByteSize();

  bool show_module = false;
  switch (style) {
  default:
    break;
  case Address::DumpStyleSectionNameOffset:
  case Address::DumpStyleSectionPointerOffset:
    s->PutChar('[');
    m_base_addr.Dump(s, target, style, fallback_style);
    s->PutChar('-');
    DumpAddress(s->AsRawOstream(), m_base_addr.GetOffset() + GetByteSize(),
                addr_size);
    s->PutChar(')');
    return true;
    break;

  case Address::DumpStyleModuleWithFileAddress:
    show_module = true;
    LLVM_FALLTHROUGH;
  case Address::DumpStyleFileAddress:
    vmaddr = m_base_addr.GetFileAddress();
    break;

  case Address::DumpStyleLoadAddress:
    vmaddr = m_base_addr.GetLoadAddress(target);
    break;
  }

  if (vmaddr != LLDB_INVALID_ADDRESS) {
    if (show_module) {
      ModuleSP module_sp(GetBaseAddress().GetModule());
      if (module_sp)
        s->Printf("%s", module_sp->GetFileSpec().GetFilename().AsCString(
                            "<Unknown>"));
    }
    DumpAddressRange(s->AsRawOstream(), vmaddr, vmaddr + GetByteSize(),
                     addr_size);
    return true;
  } else if (fallback_style != Address::DumpStyleInvalid) {
    return Dump(s, target, fallback_style, Address::DumpStyleInvalid);
  }

  return false;
}

void AddressRange::DumpDebug(Stream *s) const {
  s->Printf("%p: AddressRange section = %p, offset = 0x%16.16" PRIx64
            ", byte_size = 0x%16.16" PRIx64 "\n",
            static_cast<const void *>(this),
            static_cast<void *>(m_base_addr.GetSection().get()),
            m_base_addr.GetOffset(), GetByteSize());
}
//
// bool
// lldb::operator==    (const AddressRange& lhs, const AddressRange& rhs)
//{
//    if (lhs.GetBaseAddress() == rhs.GetBaseAddress())
//        return lhs.GetByteSize() == rhs.GetByteSize();
//    return false;
//}
