//===-- BreakpointLocation.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_BREAKPOINT_BREAKPOINTLOCATION_H
#define LLDB_BREAKPOINT_BREAKPOINTLOCATION_H

#include <memory>
#include <mutex>

#include "lldb/Breakpoint/BreakpointOptions.h"
#include "lldb/Breakpoint/StoppointHitCounter.h"
#include "lldb/Core/Address.h"
#include "lldb/Utility/UserID.h"
#include "lldb/lldb-private.h"

namespace lldb_private {

/// \class BreakpointLocation BreakpointLocation.h
/// "lldb/Breakpoint/BreakpointLocation.h" Class that manages one unique (by
/// address) instance of a logical breakpoint.

/// General Outline:
/// A breakpoint location is defined by the breakpoint that produces it,
/// and the address that resulted in this particular instantiation. Each
/// breakpoint location also may have a breakpoint site if its address has
/// been loaded into the program. Finally it has a settable options object.
///
/// FIXME: Should we also store some fingerprint for the location, so
/// we can map one location to the "equivalent location" on rerun?  This would
/// be useful if you've set options on the locations.

class BreakpointLocation
    : public std::enable_shared_from_this<BreakpointLocation> {
public:
  ~BreakpointLocation();

  /// Gets the load address for this breakpoint location \return
  ///     Returns breakpoint location load address, \b
  ///     LLDB_INVALID_ADDRESS if not yet set.
  lldb::addr_t GetLoadAddress() const;

  /// Gets the Address for this breakpoint location \return
  ///     Returns breakpoint location Address.
  Address &GetAddress();
  /// Gets the Breakpoint that created this breakpoint location \return
  ///     Returns the owning breakpoint.
  Breakpoint &GetBreakpoint();

  Target &GetTarget();

  /// Determines whether we should stop due to a hit at this breakpoint
  /// location.
  ///
  /// Side Effects: This may evaluate the breakpoint condition, and run the
  /// callback.  So this command may do a considerable amount of work.
  ///
  /// \return
  ///     \b true if this breakpoint location thinks we should stop,
  ///     \b false otherwise.
  bool ShouldStop(StoppointCallbackContext *context);

  // The next section deals with various breakpoint options.

  /// If \a enabled is \b true, enable the breakpoint, if \b false disable it.
  void SetEnabled(bool enabled);

  /// Check the Enable/Disable state.
  ///
  /// \return
  ///     \b true if the breakpoint is enabled, \b false if disabled.
  bool IsEnabled() const;

  /// If \a auto_continue is \b true, set the breakpoint to continue when hit.
  void SetAutoContinue(bool auto_continue);

  /// Check the AutoContinue state.
  ///
  /// \return
  ///     \b true if the breakpoint is set to auto-continue, \b false if not.
  bool IsAutoContinue() const;

  /// Return the current Hit Count.
  uint32_t GetHitCount() const { return m_hit_counter.GetValue(); }

  /// Return the current Ignore Count.
  ///
  /// \return
  ///     The number of breakpoint hits to be ignored.
  uint32_t GetIgnoreCount() const;

  /// Set the breakpoint to ignore the next \a count breakpoint hits.
  ///
  /// \param[in] n
  ///    The number of breakpoint hits to ignore.
  void SetIgnoreCount(uint32_t n);

  /// Set the callback action invoked when the breakpoint is hit.
  ///
  /// The callback will return a bool indicating whether the target should
  /// stop at this breakpoint or not.
  ///
  /// \param[in] callback
  ///     The method that will get called when the breakpoint is hit.
  ///
  /// \param[in] callback_baton_sp
  ///     A shared pointer to a Baton that provides the void * needed
  ///     for the callback.
  ///
  /// \see lldb_private::Baton
  void SetCallback(BreakpointHitCallback callback,
                   const lldb::BatonSP &callback_baton_sp, bool is_synchronous);

  void SetCallback(BreakpointHitCallback callback, void *baton,
                   bool is_synchronous);

  void ClearCallback();

  /// Set the breakpoint location's condition.
  ///
  /// \param[in] condition
  ///    The condition expression to evaluate when the breakpoint is hit.
  void SetCondition(const char *condition);

  /// Return a pointer to the text of the condition expression.
  ///
  /// \return
  ///    A pointer to the condition expression text, or nullptr if no
  //     condition has been set.
  const char *GetConditionText(size_t *hash = nullptr) const;

  bool ConditionSaysStop(ExecutionContext &exe_ctx, Status &error);

  /// Set the valid thread to be checked when the breakpoint is hit.
  ///
  /// \param[in] thread_id
  ///    If this thread hits the breakpoint, we stop, otherwise not.
  void SetThreadID(lldb::tid_t thread_id);

  lldb::tid_t GetThreadID();

  void SetThreadIndex(uint32_t index);

  uint32_t GetThreadIndex() const;

  void SetThreadName(const char *thread_name);

  const char *GetThreadName() const;

  void SetQueueName(const char *queue_name);

  const char *GetQueueName() const;

  // The next section deals with this location's breakpoint sites.

  /// Try to resolve the breakpoint site for this location.
  ///
  /// \return
  ///     \b true if we were successful at setting a breakpoint site,
  ///     \b false otherwise.
  bool ResolveBreakpointSite();

  /// Clear this breakpoint location's breakpoint site - for instance when
  /// disabling the breakpoint.
  ///
  /// \return
  ///     \b true if there was a breakpoint site to be cleared, \b false
  ///     otherwise.
  bool ClearBreakpointSite();

  /// Return whether this breakpoint location has a breakpoint site. \return
  ///     \b true if there was a breakpoint site for this breakpoint
  ///     location, \b false otherwise.
  bool IsResolved() const;

  lldb::BreakpointSiteSP GetBreakpointSite() const;

  // The next section are generic report functions.

  /// Print a description of this breakpoint location to the stream \a s.
  ///
  /// \param[in] s
  ///     The stream to which to print the description.
  ///
  /// \param[in] level
  ///     The description level that indicates the detail level to
  ///     provide.
  ///
  /// \see lldb::DescriptionLevel
  void GetDescription(Stream *s, lldb::DescriptionLevel level);

  /// Standard "Dump" method.  At present it does nothing.
  void Dump(Stream *s) const;

  /// Use this to set location specific breakpoint options.
  ///
  /// It will create a copy of the containing breakpoint's options if that
  /// hasn't been done already
  ///
  /// \return
  ///    A pointer to the breakpoint options.
  BreakpointOptions *GetLocationOptions();

  /// Use this to access breakpoint options from this breakpoint location.
  /// This will return the options that have a setting for the specified
  /// BreakpointOptions kind.
  ///
  /// \param[in] kind
  ///     The particular option you are looking up.
  /// \return
  ///     A pointer to the containing breakpoint's options if this
  ///     location doesn't have its own copy.
  const BreakpointOptions *GetOptionsSpecifyingKind(
      BreakpointOptions::OptionKind kind) const;

  bool ValidForThisThread(Thread *thread);

  /// Invoke the callback action when the breakpoint is hit.
  ///
  /// Meant to be used by the BreakpointLocation class.
  ///
  /// \param[in] context
  ///    Described the breakpoint event.
  ///
  /// \return
  ///     \b true if the target should stop at this breakpoint and \b
  ///     false not.
  bool InvokeCallback(StoppointCallbackContext *context);
  
  /// Report whether the callback for this location is synchronous or not.
  ///
  /// \return
  ///     \b true if the callback is synchronous and \b false if not.
  bool IsCallbackSynchronous();

  /// Returns whether we should resolve Indirect functions in setting the
  /// breakpoint site for this location.
  ///
  /// \return
  ///     \b true if the breakpoint SITE for this location should be set on the
  ///     resolved location for Indirect functions.
  bool ShouldResolveIndirectFunctions() {
    return m_should_resolve_indirect_functions;
  }

  /// Returns whether the address set in the breakpoint site for this location
  /// was found by resolving an indirect symbol.
  ///
  /// \return
  ///     \b true or \b false as given in the description above.
  bool IsIndirect() { return m_is_indirect; }

  void SetIsIndirect(bool is_indirect) { m_is_indirect = is_indirect; }

  /// Returns whether the address set in the breakpoint location was re-routed
  /// to the target of a re-exported symbol.
  ///
  /// \return
  ///     \b true or \b false as given in the description above.
  bool IsReExported() { return m_is_reexported; }

  void SetIsReExported(bool is_reexported) { m_is_reexported = is_reexported; }

  /// Returns whether the two breakpoint locations might represent "equivalent
  /// locations". This is used when modules changed to determine if a Location
  /// in the old module might be the "same as" the input location.
  ///
  /// \param[in] location
  ///    The location to compare against.
  ///
  /// \return
  ///     \b true or \b false as given in the description above.
  bool EquivalentToLocation(BreakpointLocation &location);

  /// Returns the breakpoint location ID.
  lldb::break_id_t GetID() const { return m_loc_id; }

protected:
  friend class BreakpointSite;
  friend class BreakpointLocationList;
  friend class Process;
  friend class StopInfoBreakpoint;

  /// Set the breakpoint site for this location to \a bp_site_sp.
  ///
  /// \param[in] bp_site_sp
  ///      The breakpoint site we are setting for this location.
  ///
  /// \return
  ///     \b true if we were successful at setting the breakpoint site,
  ///     \b false otherwise.
  bool SetBreakpointSite(lldb::BreakpointSiteSP &bp_site_sp);

  void DecrementIgnoreCount();

  bool IgnoreCountShouldStop();

private:
  void SwapLocation(lldb::BreakpointLocationSP swap_from);

  void BumpHitCount();

  void UndoBumpHitCount();

  // Constructors and Destructors
  //
  // Only the Breakpoint can make breakpoint locations, and it owns them.

  /// Constructor.
  ///
  /// \param[in] owner
  ///     A back pointer to the breakpoint that owns this location.
  ///
  /// \param[in] addr
  ///     The Address defining this location.
  ///
  /// \param[in] tid
  ///     The thread for which this breakpoint location is valid, or
  ///     LLDB_INVALID_THREAD_ID if it is valid for all threads.
  ///
  /// \param[in] hardware
  ///     \b true if a hardware breakpoint is requested.

  BreakpointLocation(lldb::break_id_t bid, Breakpoint &owner,
                     const Address &addr, lldb::tid_t tid, bool hardware,
                     bool check_for_resolver = true);

  // Data members:
  bool m_being_created;
  bool m_should_resolve_indirect_functions;
  bool m_is_reexported;
  bool m_is_indirect;
  Address m_address;   ///< The address defining this location.
  Breakpoint &m_owner; ///< The breakpoint that produced this object.
  std::unique_ptr<BreakpointOptions> m_options_up; ///< Breakpoint options
                                                   /// pointer, nullptr if we're
                                                   /// using our breakpoint's
                                                   /// options.
  lldb::BreakpointSiteSP m_bp_site_sp; ///< Our breakpoint site (it may be
                                       ///shared by more than one location.)
  lldb::UserExpressionSP m_user_expression_sp; ///< The compiled expression to
                                               ///use in testing our condition.
  std::mutex m_condition_mutex; ///< Guards parsing and evaluation of the
                                ///condition, which could be evaluated by
                                /// multiple processes.
  size_t m_condition_hash; ///< For testing whether the condition source code
                           ///changed.
  lldb::break_id_t m_loc_id; ///< Breakpoint location ID.
  StoppointHitCounter m_hit_counter; ///< Number of times this breakpoint
                                     /// location has been hit.

  void SetShouldResolveIndirectFunctions(bool do_resolve) {
    m_should_resolve_indirect_functions = do_resolve;
  }

  void SendBreakpointLocationChangedEvent(lldb::BreakpointEventType eventKind);

  BreakpointLocation(const BreakpointLocation &) = delete;
  const BreakpointLocation &operator=(const BreakpointLocation &) = delete;
};

} // namespace lldb_private

#endif // LLDB_BREAKPOINT_BREAKPOINTLOCATION_H
