//===-- Address.h -----------------------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_CORE_ADDRESS_H
#define LLDB_CORE_ADDRESS_H

#include "lldb/lldb-defines.h"
#include "lldb/lldb-forward.h"
#include "lldb/lldb-private-enumerations.h"
#include "lldb/lldb-types.h"

#include <cstddef>
#include <cstdint>

namespace lldb_private {
class Block;
class CompileUnit;
class ExecutionContextScope;
class Function;
class SectionList;
class Stream;
class Symbol;
class SymbolContext;
class Target;
struct LineEntry;

/// \class Address Address.h "lldb/Core/Address.h"
/// A section + offset based address class.
///
/// The Address class allows addresses to be relative to a section that can
/// move during runtime due to images (executables, shared libraries, bundles,
/// frameworks) being loaded at different addresses than the addresses found
/// in the object file that represents them on disk. There are currently two
/// types of addresses for a section:
///     \li file addresses
///     \li load addresses
///
/// File addresses represent the virtual addresses that are in the "on disk"
/// object files. These virtual addresses are converted to be relative to
/// unique sections scoped to the object file so that when/if the addresses
/// slide when the images are loaded/unloaded in memory, we can easily track
/// these changes without having to update every object (compile unit ranges,
/// line tables, function address ranges, lexical block and inlined subroutine
/// address ranges, global and static variables) each time an image is loaded
/// or unloaded.
///
/// Load addresses represent the virtual addresses where each section ends up
/// getting loaded at runtime. Before executing a program, it is common for
/// all of the load addresses to be unresolved. When a DynamicLoader plug-in
/// receives notification that shared libraries have been loaded/unloaded, the
/// load addresses of the main executable and any images (shared libraries)
/// will be  resolved/unresolved. When this happens, breakpoints that are in
/// one of these sections can be set/cleared.
class Address {
public:
  /// Dump styles allow the Address::Dump(Stream *,DumpStyle) const function
  /// to display Address contents in a variety of ways.
  enum DumpStyle {
    /// Invalid dump style.
    DumpStyleInvalid,
    /// Display as the section name + offset.
    /// \code
    /// // address for printf in libSystem.B.dylib as a section name + offset
    /// libSystem.B.dylib.__TEXT.__text + 0x0005cfdf
    /// \endcode
    DumpStyleSectionNameOffset,
    /// Display as the section pointer + offset (debug output).
    /// \code
    /// // address for printf in libSystem.B.dylib as a section pointer +
    /// offset (lldb::Section *)0x35cc50 + 0x000000000005cfdf
    /// \endcode
    DumpStyleSectionPointerOffset,
    /// Display as the file address (if any).
    /// \code
    /// // address for printf in libSystem.B.dylib as a file address
    /// 0x000000000005dcff
    /// \endcode
    ///
    DumpStyleFileAddress,
    /// Display as the file address with the module name prepended (if any).
    /// \code
    /// // address for printf in libSystem.B.dylib as a file address
    /// libSystem.B.dylib[0x000000000005dcff]
    /// \endcode
    DumpStyleModuleWithFileAddress,
    /// Display as the load address (if resolved).
    /// \code
    /// // address for printf in libSystem.B.dylib as a load address
    /// 0x00007fff8306bcff
    /// \endcode
    DumpStyleLoadAddress,
    /// Display the details about what an address resolves to. This can be
    /// anything from a symbol context summary (module, function/symbol, and
    /// file and line), to information about what the pointer points to if the
    /// address is in a section (section of pointers, c strings, etc).
    DumpStyleResolvedDescription,
    DumpStyleResolvedDescriptionNoModule,
    DumpStyleResolvedDescriptionNoFunctionArguments,
    /// Elide the function name; display an offset into the current function.
    /// Used primarily in disassembly symbolication
    DumpStyleNoFunctionName,
    /// Detailed symbol context information for an address for all symbol
    /// context members.
    DumpStyleDetailedSymbolContext,
    /// Dereference a pointer at the current address and then lookup the
    /// dereferenced address using DumpStyleResolvedDescription
    DumpStyleResolvedPointerDescription
  };

  /// Default constructor.
  ///
  /// Initialize with a invalid section (NULL) and an invalid offset
  /// (LLDB_INVALID_ADDRESS).
  Address() {}

  /// Copy constructor
  ///
  /// Makes a copy of the another Address object \a rhs.
  ///
  /// \param[in] rhs
  ///     A const Address object reference to copy.
  Address(const Address &rhs)
      : m_section_wp(rhs.m_section_wp), m_offset(rhs.m_offset) {}

  /// Construct with a section pointer and offset.
  ///
  /// Initialize the address with the supplied \a section and \a offset.
  ///
  /// \param[in] section_sp
  ///     A section pointer to a valid lldb::Section, or NULL if the
  ///     address doesn't have a section or will get resolved later.
  ///
  /// \param[in] offset
  ///     The offset in bytes into \a section.
  Address(const lldb::SectionSP &section_sp, lldb::addr_t offset)
      : m_section_wp(), // Don't init with section_sp in case section_sp is
                        // invalid (the weak_ptr will throw)
        m_offset(offset) {
    if (section_sp)
      m_section_wp = section_sp;
  }

  /// Construct with a virtual address and section list.
  ///
  /// Initialize and resolve the address with the supplied virtual address \a
  /// file_addr.
  ///
  /// \param[in] file_addr
  ///     A virtual file address.
  ///
  /// \param[in] section_list
  ///     A list of sections, one of which may contain the \a file_addr.
  Address(lldb::addr_t file_addr, const SectionList *section_list);

  Address(lldb::addr_t abs_addr);

/// Assignment operator.
///
/// Copies the address value from another Address object \a rhs into \a this
/// object.
///
/// \param[in] rhs
///     A const Address object reference to copy.
///
/// \return
///     A const Address object reference to \a this.
  const Address &operator=(const Address &rhs);

  /// Clear the object's state.
  ///
  /// Sets the section to an invalid value (NULL) and an invalid offset
  /// (LLDB_INVALID_ADDRESS).
  void Clear() {
    m_section_wp.reset();
    m_offset = LLDB_INVALID_ADDRESS;
  }

  /// Compare two Address objects.
  ///
  /// \param[in] lhs
  ///     The Left Hand Side const Address object reference.
  ///
  /// \param[in] rhs
  ///     The Right Hand Side const Address object reference.
  ///
  /// \return
  ///     -1 if lhs < rhs
  ///     0 if lhs == rhs
  ///     1 if lhs > rhs
  static int CompareFileAddress(const Address &lhs, const Address &rhs);

  static int CompareLoadAddress(const Address &lhs, const Address &rhs,
                                Target *target);

  static int CompareModulePointerAndOffset(const Address &lhs,
                                           const Address &rhs);

  // For use with std::map, std::multi_map
  class ModulePointerAndOffsetLessThanFunctionObject {
  public:
    ModulePointerAndOffsetLessThanFunctionObject() = default;

    bool operator()(const Address &a, const Address &b) const {
      return Address::CompareModulePointerAndOffset(a, b) < 0;
    }
  };

  /// Write a description of this object to a Stream.
  bool GetDescription(Stream &s, Target &target,
                      lldb::DescriptionLevel level) const;

  /// Dump a description of this object to a Stream.
  ///
  /// Dump a description of the contents of this object to the supplied stream
  /// \a s. There are many ways to display a section offset based address, and
  /// \a style lets the user choose.
  ///
  /// \param[in] s
  ///     The stream to which to dump the object description.
  ///
  /// \param[in] style
  ///     The display style for the address.
  ///
  /// \param[in] fallback_style
  ///     The display style for the address.
  ///
  /// \param[in] addr_byte_size
  ///     The address byte size for the address.
  ///
  /// \param[in] all_ranges
  ///     If true, dump all valid ranges and value ranges for the variable that
  ///     contains the address, otherwise dumping the range that contains the
  ///     address.
  ///
  /// \return
  ///     Returns \b true if the address was able to be displayed.
  ///     File and load addresses may be unresolved and it may not be
  ///     possible to display a valid value, \b false will be returned
  ///     in such cases.
  ///
  /// \see Address::DumpStyle
  bool Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
            DumpStyle fallback_style = DumpStyleInvalid,
            uint32_t addr_byte_size = UINT32_MAX,
            bool all_ranges = false) const;

  AddressClass GetAddressClass() const;

  /// Get the file address.
  ///
  /// If an address comes from a file on disk that has section relative
  /// addresses, then it has a virtual address that is relative to unique
  /// section in the object file.
  ///
  /// \return
  ///     The valid file virtual address, or LLDB_INVALID_ADDRESS if
  ///     the address doesn't have a file virtual address (image is
  ///     from memory only with no representation on disk).
  lldb::addr_t GetFileAddress() const;

  /// Get the load address.
  ///
  /// If an address comes from a file on disk that has section relative
  /// addresses, then it has a virtual address that is relative to unique
  /// section in the object file. Sections get resolved at runtime by
  /// DynamicLoader plug-ins as images (executables and shared libraries) get
  /// loaded/unloaded. If a section is loaded, then the load address can be
  /// resolved.
  ///
  /// \return
  ///     The valid load virtual address, or LLDB_INVALID_ADDRESS if
  ///     the address is currently not loaded.
  lldb::addr_t GetLoadAddress(Target *target) const;

  /// Get the load address as a callable code load address.
  ///
  /// This function will first resolve its address to a load address. Then, if
  /// the address turns out to be in code address, return the load address
  /// that would be required to call or return to. The address might have
  /// extra bits set (bit zero will be set to Thumb functions for an ARM
  /// target) that are required when changing the program counter to setting a
  /// return address.
  ///
  /// \return
  ///     The valid load virtual address, or LLDB_INVALID_ADDRESS if
  ///     the address is currently not loaded.
  lldb::addr_t GetCallableLoadAddress(Target *target,
                                      bool is_indirect = false) const;

  /// Get the load address as an opcode load address.
  ///
  /// This function will first resolve its address to a load address. Then, if
  /// the address turns out to be in code address, return the load address for
  /// an opcode. This address object might have extra bits set (bit zero will
  /// be set to Thumb functions for an
  /// ARM target) that are required for changing the program counter
  /// and this function will remove any bits that are intended for these
  /// special purposes. The result of this function can be used to safely
  /// write a software breakpoint trap to memory.
  ///
  /// \return
  ///     The valid load virtual address with extra callable bits
  ///     removed, or LLDB_INVALID_ADDRESS if the address is currently
  ///     not loaded.
  lldb::addr_t GetOpcodeLoadAddress(
      Target *target,
      AddressClass addr_class = AddressClass::eInvalid) const;

  /// Get the section relative offset value.
  ///
  /// \return
  ///     The current offset, or LLDB_INVALID_ADDRESS if this address
  ///     doesn't contain a valid offset.
  lldb::addr_t GetOffset() const { return m_offset; }

  /// Check if an address is section offset.
  ///
  /// When converting a virtual file or load address into a section offset
  /// based address, we often need to know if, given a section list, if the
  /// address was able to be converted to section offset. This function
  /// returns true if the current value contained in this object is section
  /// offset based.
  ///
  /// \return
  ///     Returns \b true if the address has a valid section and
  ///     offset, \b false otherwise.
  bool IsSectionOffset() const {
    return IsValid() && (GetSection().get() != nullptr);
  }

  /// Check if the object state is valid.
  ///
  /// A valid Address object contains either a section pointer and
  /// offset (for section offset based addresses), or just a valid offset
  /// (for absolute addresses that have no section).
  ///
  /// \return
  ///     Returns \b true if the offset is valid, \b false
  ///     otherwise.
  bool IsValid() const { return m_offset != LLDB_INVALID_ADDRESS; }

  /// Get the memory cost of this object.
  ///
  /// \return
  ///     The number of bytes that this object occupies in memory.
  size_t MemorySize() const;

  /// Resolve a file virtual address using a section list.
  ///
  /// Given a list of sections, attempt to resolve \a addr as an offset into
  /// one of the file sections.
  ///
  /// \return
  ///     Returns \b true if \a addr was able to be resolved, \b false
  ///     otherwise.
  bool ResolveAddressUsingFileSections(lldb::addr_t addr,
                                       const SectionList *sections);

  /// Resolve this address to its containing function and optionally get
  /// that function's address range.
  ///
  /// \param[out] sym_ctx
  ///     The symbol context describing the function in which this address lies
  ///
  /// \parm[out] addr_range_ptr
  ///     Pointer to the AddressRange to fill in with the function's address
  ///     range.  Caller may pass null if they don't need the address range.
  ///
  /// \return
  ///     Returns \b false if the function/symbol could not be resolved
  ///     or if the address range was requested and could not be resolved;
  ///     returns \b true otherwise.
  bool ResolveFunctionScope(lldb_private::SymbolContext &sym_ctx,
                            lldb_private::AddressRange *addr_range_ptr = nullptr);

  /// Set the address to represent \a load_addr.
  ///
  /// The address will attempt to find a loaded section within \a target that
  /// contains \a load_addr. If successful, this address object will have a
  /// valid section and offset. Else this address object will have no section
  /// (NULL) and the offset will be \a load_addr.
  ///
  /// \param[in] load_addr
  ///     A load address from a current process.
  ///
  /// \param[in] target
  ///     The target to use when trying resolve the address into
  ///     a section + offset. The Target's SectionLoadList object
  ///     is used to resolve the address.
  ///
  /// \param[in] allow_section_end
  ///     If true, treat an address pointing to the end of the module as
  ///     belonging to that module.
  ///
  /// \return
  ///     Returns \b true if the load address was resolved to be
  ///     section/offset, \b false otherwise. It is often ok for an
  ///     address to not resolve to a section in a module, this often
  ///     happens for JIT'ed code, or any load addresses on the stack
  ///     or heap.
  bool SetLoadAddress(lldb::addr_t load_addr, Target *target,
                      bool allow_section_end = false);

  bool SetOpcodeLoadAddress(
      lldb::addr_t load_addr, Target *target,
      AddressClass addr_class = AddressClass::eInvalid,
      bool allow_section_end = false);

  bool SetCallableLoadAddress(lldb::addr_t load_addr, Target *target);

  /// Get accessor for the module for this address.
  ///
  /// \return
  ///     Returns the Module pointer that this address is an offset
  ///     in, or NULL if this address doesn't belong in a module, or
  ///     isn't resolved yet.
  lldb::ModuleSP GetModule() const;

  /// Get const accessor for the section.
  ///
  /// \return
  ///     Returns the const lldb::Section pointer that this address is an
  ///     offset in, or NULL if this address is absolute.
  lldb::SectionSP GetSection() const { return m_section_wp.lock(); }

  /// Set accessor for the offset.
  ///
  /// \param[in] offset
  ///     A new offset value for this object.
  ///
  /// \return
  ///     Returns \b true if the offset changed, \b false otherwise.
  bool SetOffset(lldb::addr_t offset) {
    bool changed = m_offset != offset;
    m_offset = offset;
    return changed;
  }

  void SetRawAddress(lldb::addr_t addr) {
    m_section_wp.reset();
    m_offset = addr;
  }

  bool Slide(int64_t offset) {
    if (m_offset != LLDB_INVALID_ADDRESS) {
      m_offset += offset;
      return true;
    }
    return false;
  }

  /// Set accessor for the section.
  ///
  /// \param[in] section_sp
  ///     A new lldb::Section pointer to use as the section base. Can
  ///     be NULL for absolute addresses that are not relative to
  ///     any section.
  void SetSection(const lldb::SectionSP &section_sp) {
    m_section_wp = section_sp;
  }

  void ClearSection() { m_section_wp.reset(); }

  /// Reconstruct a symbol context from an address.
  ///
  /// This class doesn't inherit from SymbolContextScope because many address
  /// objects have short lifespans. Address objects that are section offset
  /// can reconstruct their symbol context by looking up the address in the
  /// module found in the section.
  ///
  /// \see SymbolContextScope::CalculateSymbolContext(SymbolContext*)
  uint32_t CalculateSymbolContext(SymbolContext *sc,
                                  lldb::SymbolContextItem resolve_scope =
                                      lldb::eSymbolContextEverything) const;

  lldb::ModuleSP CalculateSymbolContextModule() const;

  CompileUnit *CalculateSymbolContextCompileUnit() const;

  Function *CalculateSymbolContextFunction() const;

  Block *CalculateSymbolContextBlock() const;

  Symbol *CalculateSymbolContextSymbol() const;

  bool CalculateSymbolContextLineEntry(LineEntry &line_entry) const;

  // Returns true if the section should be valid, but isn't because the shared
  // pointer to the section can't be reconstructed from a weak pointer that
  // contains a valid weak reference to a section. Returns false if the section
  // weak pointer has no reference to a section, or if the section is still
  // valid
  bool SectionWasDeleted() const;

protected:
  // Member variables.
  lldb::SectionWP m_section_wp; ///< The section for the address, can be NULL.
  lldb::addr_t m_offset = LLDB_INVALID_ADDRESS; ///< Offset into section if \a
                                                ///< m_section_wp is valid...

  // Returns true if the m_section_wp once had a reference to a valid section
  // shared pointer, but no longer does. This can happen if we have an address
  // from a module that gets unloaded and deleted. This function should only be
  // called if GetSection() returns an empty shared pointer and you want to
  // know if this address used to have a valid section.
  bool SectionWasDeletedPrivate() const;
};

// NOTE: Be careful using this operator. It can correctly compare two
// addresses from the same Module correctly. It can't compare two addresses
// from different modules in any meaningful way, but it will compare the module
// pointers.
//
// To sum things up:
// - works great for addresses within the same module - it works for addresses
// across multiple modules, but don't expect the
//   address results to make much sense
//
// This basically lets Address objects be used in ordered collection classes.
bool operator<(const Address &lhs, const Address &rhs);
bool operator>(const Address &lhs, const Address &rhs);
bool operator==(const Address &lhs, const Address &rhs);
bool operator!=(const Address &lhs, const Address &rhs);

} // namespace lldb_private

#endif // LLDB_CORE_ADDRESS_H
