mirror of
https://github.com/opnsense/src.git
synced 2026-03-26 12:43:12 -04:00
This corresponds with the branchpoint for the 3.6 release. A number of files not required for the FreeBSD build have been removed. Sponsored by: DARPA, AFRL
1415 lines
42 KiB
C++
1415 lines
42 KiB
C++
//===-- Target.h ------------------------------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef liblldb_Target_h_
|
|
#define liblldb_Target_h_
|
|
|
|
// C Includes
|
|
// C++ Includes
|
|
#include <list>
|
|
|
|
// Other libraries and framework includes
|
|
// Project includes
|
|
#include "lldb/lldb-public.h"
|
|
#include "lldb/Breakpoint/BreakpointList.h"
|
|
#include "lldb/Breakpoint/BreakpointLocationCollection.h"
|
|
#include "lldb/Breakpoint/WatchpointList.h"
|
|
#include "lldb/Core/ArchSpec.h"
|
|
#include "lldb/Core/Broadcaster.h"
|
|
#include "lldb/Core/Disassembler.h"
|
|
#include "lldb/Core/Event.h"
|
|
#include "lldb/Core/ModuleList.h"
|
|
#include "lldb/Core/UserSettingsController.h"
|
|
#include "lldb/Expression/ClangModulesDeclVendor.h"
|
|
#include "lldb/Expression/ClangPersistentVariables.h"
|
|
#include "lldb/Interpreter/Args.h"
|
|
#include "lldb/Interpreter/OptionValueBoolean.h"
|
|
#include "lldb/Interpreter/OptionValueEnumeration.h"
|
|
#include "lldb/Interpreter/OptionValueFileSpec.h"
|
|
#include "lldb/Symbol/SymbolContext.h"
|
|
#include "lldb/Target/ABI.h"
|
|
#include "lldb/Target/ExecutionContextScope.h"
|
|
#include "lldb/Target/PathMappingList.h"
|
|
#include "lldb/Target/SectionLoadHistory.h"
|
|
|
|
namespace lldb_private {
|
|
|
|
extern OptionEnumValueElement g_dynamic_value_types[];
|
|
|
|
typedef enum InlineStrategy
|
|
{
|
|
eInlineBreakpointsNever = 0,
|
|
eInlineBreakpointsHeaders,
|
|
eInlineBreakpointsAlways
|
|
} InlineStrategy;
|
|
|
|
typedef enum LoadScriptFromSymFile
|
|
{
|
|
eLoadScriptFromSymFileTrue,
|
|
eLoadScriptFromSymFileFalse,
|
|
eLoadScriptFromSymFileWarn
|
|
} LoadScriptFromSymFile;
|
|
|
|
//----------------------------------------------------------------------
|
|
// TargetProperties
|
|
//----------------------------------------------------------------------
|
|
class TargetProperties : public Properties
|
|
{
|
|
public:
|
|
TargetProperties(Target *target);
|
|
|
|
virtual
|
|
~TargetProperties();
|
|
|
|
ArchSpec
|
|
GetDefaultArchitecture () const;
|
|
|
|
void
|
|
SetDefaultArchitecture (const ArchSpec& arch);
|
|
|
|
lldb::DynamicValueType
|
|
GetPreferDynamicValue() const;
|
|
|
|
bool
|
|
GetDisableASLR () const;
|
|
|
|
void
|
|
SetDisableASLR (bool b);
|
|
|
|
bool
|
|
GetDetachOnError () const;
|
|
|
|
void
|
|
SetDetachOnError (bool b);
|
|
|
|
bool
|
|
GetDisableSTDIO () const;
|
|
|
|
void
|
|
SetDisableSTDIO (bool b);
|
|
|
|
const char *
|
|
GetDisassemblyFlavor() const;
|
|
|
|
// void
|
|
// SetDisassemblyFlavor(const char *flavor);
|
|
|
|
InlineStrategy
|
|
GetInlineStrategy () const;
|
|
|
|
const char *
|
|
GetArg0 () const;
|
|
|
|
void
|
|
SetArg0 (const char *arg);
|
|
|
|
bool
|
|
GetRunArguments (Args &args) const;
|
|
|
|
void
|
|
SetRunArguments (const Args &args);
|
|
|
|
size_t
|
|
GetEnvironmentAsArgs (Args &env) const;
|
|
|
|
bool
|
|
GetSkipPrologue() const;
|
|
|
|
PathMappingList &
|
|
GetSourcePathMap () const;
|
|
|
|
FileSpecList &
|
|
GetExecutableSearchPaths ();
|
|
|
|
FileSpecList &
|
|
GetDebugFileSearchPaths ();
|
|
|
|
bool
|
|
GetEnableSyntheticValue () const;
|
|
|
|
uint32_t
|
|
GetMaximumNumberOfChildrenToDisplay() const;
|
|
|
|
uint32_t
|
|
GetMaximumSizeOfStringSummary() const;
|
|
|
|
uint32_t
|
|
GetMaximumMemReadSize () const;
|
|
|
|
FileSpec
|
|
GetStandardInputPath () const;
|
|
|
|
void
|
|
SetStandardInputPath (const char *path);
|
|
|
|
FileSpec
|
|
GetStandardOutputPath () const;
|
|
|
|
void
|
|
SetStandardOutputPath (const char *path);
|
|
|
|
FileSpec
|
|
GetStandardErrorPath () const;
|
|
|
|
void
|
|
SetStandardErrorPath (const char *path);
|
|
|
|
bool
|
|
GetBreakpointsConsultPlatformAvoidList ();
|
|
|
|
const char *
|
|
GetExpressionPrefixContentsAsCString ();
|
|
|
|
bool
|
|
GetUseHexImmediates() const;
|
|
|
|
bool
|
|
GetUseFastStepping() const;
|
|
|
|
bool
|
|
GetDisplayExpressionsInCrashlogs () const;
|
|
|
|
LoadScriptFromSymFile
|
|
GetLoadScriptFromSymbolFile() const;
|
|
|
|
Disassembler::HexImmediateStyle
|
|
GetHexImmediateStyle() const;
|
|
|
|
MemoryModuleLoadLevel
|
|
GetMemoryModuleLoadLevel() const;
|
|
|
|
bool
|
|
GetUserSpecifiedTrapHandlerNames (Args &args) const;
|
|
|
|
void
|
|
SetUserSpecifiedTrapHandlerNames (const Args &args);
|
|
};
|
|
|
|
typedef std::shared_ptr<TargetProperties> TargetPropertiesSP;
|
|
|
|
class EvaluateExpressionOptions
|
|
{
|
|
public:
|
|
static const uint32_t default_timeout = 500000;
|
|
EvaluateExpressionOptions() :
|
|
m_execution_policy(eExecutionPolicyOnlyWhenNeeded),
|
|
m_language (lldb::eLanguageTypeUnknown),
|
|
m_coerce_to_id(false),
|
|
m_unwind_on_error(true),
|
|
m_ignore_breakpoints (false),
|
|
m_keep_in_memory(false),
|
|
m_try_others(true),
|
|
m_stop_others(true),
|
|
m_debug(false),
|
|
m_trap_exceptions(true),
|
|
m_generate_debug_info(false),
|
|
m_result_is_internal(false),
|
|
m_use_dynamic(lldb::eNoDynamicValues),
|
|
m_timeout_usec(default_timeout),
|
|
m_one_thread_timeout_usec(0),
|
|
m_cancel_callback (nullptr),
|
|
m_cancel_callback_baton (nullptr)
|
|
{
|
|
}
|
|
|
|
ExecutionPolicy
|
|
GetExecutionPolicy () const
|
|
{
|
|
return m_execution_policy;
|
|
}
|
|
|
|
void
|
|
SetExecutionPolicy (ExecutionPolicy policy = eExecutionPolicyAlways)
|
|
{
|
|
m_execution_policy = policy;
|
|
}
|
|
|
|
lldb::LanguageType
|
|
GetLanguage() const
|
|
{
|
|
return m_language;
|
|
}
|
|
|
|
void
|
|
SetLanguage(lldb::LanguageType language)
|
|
{
|
|
m_language = language;
|
|
}
|
|
|
|
bool
|
|
DoesCoerceToId () const
|
|
{
|
|
return m_coerce_to_id;
|
|
}
|
|
|
|
void
|
|
SetCoerceToId (bool coerce = true)
|
|
{
|
|
m_coerce_to_id = coerce;
|
|
}
|
|
|
|
bool
|
|
DoesUnwindOnError () const
|
|
{
|
|
return m_unwind_on_error;
|
|
}
|
|
|
|
void
|
|
SetUnwindOnError (bool unwind = false)
|
|
{
|
|
m_unwind_on_error = unwind;
|
|
}
|
|
|
|
bool
|
|
DoesIgnoreBreakpoints () const
|
|
{
|
|
return m_ignore_breakpoints;
|
|
}
|
|
|
|
void
|
|
SetIgnoreBreakpoints (bool ignore = false)
|
|
{
|
|
m_ignore_breakpoints = ignore;
|
|
}
|
|
|
|
bool
|
|
DoesKeepInMemory () const
|
|
{
|
|
return m_keep_in_memory;
|
|
}
|
|
|
|
void
|
|
SetKeepInMemory (bool keep = true)
|
|
{
|
|
m_keep_in_memory = keep;
|
|
}
|
|
|
|
lldb::DynamicValueType
|
|
GetUseDynamic () const
|
|
{
|
|
return m_use_dynamic;
|
|
}
|
|
|
|
void
|
|
SetUseDynamic (lldb::DynamicValueType dynamic = lldb::eDynamicCanRunTarget)
|
|
{
|
|
m_use_dynamic = dynamic;
|
|
}
|
|
|
|
uint32_t
|
|
GetTimeoutUsec () const
|
|
{
|
|
return m_timeout_usec;
|
|
}
|
|
|
|
void
|
|
SetTimeoutUsec (uint32_t timeout = 0)
|
|
{
|
|
m_timeout_usec = timeout;
|
|
}
|
|
|
|
uint32_t
|
|
GetOneThreadTimeoutUsec () const
|
|
{
|
|
return m_one_thread_timeout_usec;
|
|
}
|
|
|
|
void
|
|
SetOneThreadTimeoutUsec (uint32_t timeout = 0)
|
|
{
|
|
m_one_thread_timeout_usec = timeout;
|
|
}
|
|
|
|
bool
|
|
GetTryAllThreads () const
|
|
{
|
|
return m_try_others;
|
|
}
|
|
|
|
void
|
|
SetTryAllThreads (bool try_others = true)
|
|
{
|
|
m_try_others = try_others;
|
|
}
|
|
|
|
bool
|
|
GetStopOthers () const
|
|
{
|
|
return m_stop_others;
|
|
}
|
|
|
|
void
|
|
SetStopOthers (bool stop_others = true)
|
|
{
|
|
m_stop_others = stop_others;
|
|
}
|
|
|
|
bool
|
|
GetDebug() const
|
|
{
|
|
return m_debug;
|
|
}
|
|
|
|
void
|
|
SetDebug(bool b)
|
|
{
|
|
m_debug = b;
|
|
if (m_debug)
|
|
m_generate_debug_info = true;
|
|
}
|
|
|
|
bool
|
|
GetGenerateDebugInfo() const
|
|
{
|
|
return m_generate_debug_info;
|
|
}
|
|
|
|
void
|
|
SetGenerateDebugInfo(bool b)
|
|
{
|
|
m_generate_debug_info = b;
|
|
}
|
|
|
|
bool
|
|
GetTrapExceptions() const
|
|
{
|
|
return m_trap_exceptions;
|
|
}
|
|
|
|
void
|
|
SetTrapExceptions (bool b)
|
|
{
|
|
m_trap_exceptions = b;
|
|
}
|
|
|
|
void
|
|
SetCancelCallback (lldb::ExpressionCancelCallback callback, void *baton)
|
|
{
|
|
m_cancel_callback_baton = baton;
|
|
m_cancel_callback = callback;
|
|
}
|
|
|
|
bool
|
|
InvokeCancelCallback (lldb::ExpressionEvaluationPhase phase) const
|
|
{
|
|
if (m_cancel_callback == nullptr)
|
|
return false;
|
|
else
|
|
return m_cancel_callback (phase, m_cancel_callback_baton);
|
|
}
|
|
|
|
void
|
|
SetResultIsInternal (bool b)
|
|
{
|
|
m_result_is_internal = b;
|
|
}
|
|
|
|
bool
|
|
GetResultIsInternal () const
|
|
{
|
|
return m_result_is_internal;
|
|
}
|
|
|
|
private:
|
|
ExecutionPolicy m_execution_policy;
|
|
lldb::LanguageType m_language;
|
|
bool m_coerce_to_id;
|
|
bool m_unwind_on_error;
|
|
bool m_ignore_breakpoints;
|
|
bool m_keep_in_memory;
|
|
bool m_try_others;
|
|
bool m_stop_others;
|
|
bool m_debug;
|
|
bool m_trap_exceptions;
|
|
bool m_generate_debug_info;
|
|
bool m_result_is_internal;
|
|
lldb::DynamicValueType m_use_dynamic;
|
|
uint32_t m_timeout_usec;
|
|
uint32_t m_one_thread_timeout_usec;
|
|
lldb::ExpressionCancelCallback m_cancel_callback;
|
|
void *m_cancel_callback_baton;
|
|
};
|
|
|
|
//----------------------------------------------------------------------
|
|
// Target
|
|
//----------------------------------------------------------------------
|
|
class Target :
|
|
public std::enable_shared_from_this<Target>,
|
|
public TargetProperties,
|
|
public Broadcaster,
|
|
public ExecutionContextScope,
|
|
public ModuleList::Notifier
|
|
{
|
|
public:
|
|
friend class TargetList;
|
|
|
|
//------------------------------------------------------------------
|
|
/// Broadcaster event bits definitions.
|
|
//------------------------------------------------------------------
|
|
enum
|
|
{
|
|
eBroadcastBitBreakpointChanged = (1 << 0),
|
|
eBroadcastBitModulesLoaded = (1 << 1),
|
|
eBroadcastBitModulesUnloaded = (1 << 2),
|
|
eBroadcastBitWatchpointChanged = (1 << 3),
|
|
eBroadcastBitSymbolsLoaded = (1 << 4)
|
|
};
|
|
|
|
// These two functions fill out the Broadcaster interface:
|
|
|
|
static ConstString &GetStaticBroadcasterClass ();
|
|
|
|
virtual ConstString &GetBroadcasterClass() const
|
|
{
|
|
return GetStaticBroadcasterClass();
|
|
}
|
|
|
|
// This event data class is for use by the TargetList to broadcast new target notifications.
|
|
class TargetEventData : public EventData
|
|
{
|
|
public:
|
|
|
|
static const ConstString &
|
|
GetFlavorString ();
|
|
|
|
virtual const ConstString &
|
|
GetFlavor () const;
|
|
|
|
TargetEventData (const lldb::TargetSP &new_target_sp);
|
|
|
|
lldb::TargetSP &
|
|
GetTarget()
|
|
{
|
|
return m_target_sp;
|
|
}
|
|
|
|
virtual
|
|
~TargetEventData();
|
|
|
|
virtual void
|
|
Dump (Stream *s) const;
|
|
|
|
static const lldb::TargetSP
|
|
GetTargetFromEvent (const lldb::EventSP &event_sp);
|
|
|
|
static const TargetEventData *
|
|
GetEventDataFromEvent (const Event *event_sp);
|
|
|
|
private:
|
|
lldb::TargetSP m_target_sp;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN (TargetEventData);
|
|
};
|
|
|
|
static void
|
|
SettingsInitialize ();
|
|
|
|
static void
|
|
SettingsTerminate ();
|
|
|
|
// static lldb::UserSettingsControllerSP &
|
|
// GetSettingsController ();
|
|
|
|
static FileSpecList
|
|
GetDefaultExecutableSearchPaths ();
|
|
|
|
static FileSpecList
|
|
GetDefaultDebugFileSearchPaths ();
|
|
|
|
static ArchSpec
|
|
GetDefaultArchitecture ();
|
|
|
|
static void
|
|
SetDefaultArchitecture (const ArchSpec &arch);
|
|
|
|
// void
|
|
// UpdateInstanceName ();
|
|
|
|
lldb::ModuleSP
|
|
GetSharedModule (const ModuleSpec &module_spec,
|
|
Error *error_ptr = NULL);
|
|
|
|
//----------------------------------------------------------------------
|
|
// Settings accessors
|
|
//----------------------------------------------------------------------
|
|
|
|
static const TargetPropertiesSP &
|
|
GetGlobalProperties();
|
|
|
|
|
|
private:
|
|
//------------------------------------------------------------------
|
|
/// Construct with optional file and arch.
|
|
///
|
|
/// This member is private. Clients must use
|
|
/// TargetList::CreateTarget(const FileSpec*, const ArchSpec*)
|
|
/// so all targets can be tracked from the central target list.
|
|
///
|
|
/// @see TargetList::CreateTarget(const FileSpec*, const ArchSpec*)
|
|
//------------------------------------------------------------------
|
|
Target (Debugger &debugger,
|
|
const ArchSpec &target_arch,
|
|
const lldb::PlatformSP &platform_sp,
|
|
bool is_dummy_target);
|
|
|
|
// Helper function.
|
|
bool
|
|
ProcessIsValid ();
|
|
|
|
// Copy breakpoints, stop hooks and so forth from the dummy target:
|
|
void
|
|
PrimeFromDummyTarget(Target *dummy_target);
|
|
|
|
void
|
|
AddBreakpoint(lldb::BreakpointSP breakpoint_sp, bool internal);
|
|
|
|
public:
|
|
~Target();
|
|
|
|
Mutex &
|
|
GetAPIMutex ()
|
|
{
|
|
return m_mutex;
|
|
}
|
|
|
|
void
|
|
DeleteCurrentProcess ();
|
|
|
|
void
|
|
CleanupProcess ();
|
|
//------------------------------------------------------------------
|
|
/// Dump a description of this object to a Stream.
|
|
///
|
|
/// Dump a description of the contents of this object to the
|
|
/// supplied stream \a s. The dumped content will be only what has
|
|
/// been loaded or parsed up to this point at which this function
|
|
/// is called, so this is a good way to see what has been parsed
|
|
/// in a target.
|
|
///
|
|
/// @param[in] s
|
|
/// The stream to which to dump the object description.
|
|
//------------------------------------------------------------------
|
|
void
|
|
Dump (Stream *s, lldb::DescriptionLevel description_level);
|
|
|
|
const lldb::ProcessSP &
|
|
CreateProcess (Listener &listener,
|
|
const char *plugin_name,
|
|
const FileSpec *crash_file);
|
|
|
|
const lldb::ProcessSP &
|
|
GetProcessSP () const;
|
|
|
|
bool
|
|
IsValid()
|
|
{
|
|
return m_valid;
|
|
}
|
|
|
|
void
|
|
Destroy();
|
|
|
|
Error
|
|
Launch (ProcessLaunchInfo &launch_info,
|
|
Stream *stream); // Optional stream to receive first stop info
|
|
|
|
//------------------------------------------------------------------
|
|
// This part handles the breakpoints.
|
|
//------------------------------------------------------------------
|
|
|
|
BreakpointList &
|
|
GetBreakpointList(bool internal = false);
|
|
|
|
const BreakpointList &
|
|
GetBreakpointList(bool internal = false) const;
|
|
|
|
lldb::BreakpointSP
|
|
GetLastCreatedBreakpoint ()
|
|
{
|
|
return m_last_created_breakpoint;
|
|
}
|
|
|
|
lldb::BreakpointSP
|
|
GetBreakpointByID (lldb::break_id_t break_id);
|
|
|
|
// Use this to create a file and line breakpoint to a given module or all module it is NULL
|
|
lldb::BreakpointSP
|
|
CreateBreakpoint (const FileSpecList *containingModules,
|
|
const FileSpec &file,
|
|
uint32_t line_no,
|
|
LazyBool check_inlines,
|
|
LazyBool skip_prologue,
|
|
bool internal,
|
|
bool request_hardware);
|
|
|
|
// Use this to create breakpoint that matches regex against the source lines in files given in source_file_list:
|
|
lldb::BreakpointSP
|
|
CreateSourceRegexBreakpoint (const FileSpecList *containingModules,
|
|
const FileSpecList *source_file_list,
|
|
RegularExpression &source_regex,
|
|
bool internal,
|
|
bool request_hardware);
|
|
|
|
// Use this to create a breakpoint from a load address
|
|
lldb::BreakpointSP
|
|
CreateBreakpoint (lldb::addr_t load_addr,
|
|
bool internal,
|
|
bool request_hardware);
|
|
|
|
// Use this to create Address breakpoints:
|
|
lldb::BreakpointSP
|
|
CreateBreakpoint (Address &addr,
|
|
bool internal,
|
|
bool request_hardware);
|
|
|
|
// Use this to create a function breakpoint by regexp in containingModule/containingSourceFiles, or all modules if it is NULL
|
|
// When "skip_prologue is set to eLazyBoolCalculate, we use the current target
|
|
// setting, else we use the values passed in
|
|
lldb::BreakpointSP
|
|
CreateFuncRegexBreakpoint (const FileSpecList *containingModules,
|
|
const FileSpecList *containingSourceFiles,
|
|
RegularExpression &func_regexp,
|
|
LazyBool skip_prologue,
|
|
bool internal,
|
|
bool request_hardware);
|
|
|
|
// Use this to create a function breakpoint by name in containingModule, or all modules if it is NULL
|
|
// When "skip_prologue is set to eLazyBoolCalculate, we use the current target
|
|
// setting, else we use the values passed in
|
|
lldb::BreakpointSP
|
|
CreateBreakpoint (const FileSpecList *containingModules,
|
|
const FileSpecList *containingSourceFiles,
|
|
const char *func_name,
|
|
uint32_t func_name_type_mask,
|
|
LazyBool skip_prologue,
|
|
bool internal,
|
|
bool request_hardware);
|
|
|
|
lldb::BreakpointSP
|
|
CreateExceptionBreakpoint (enum lldb::LanguageType language, bool catch_bp, bool throw_bp, bool internal);
|
|
|
|
// This is the same as the func_name breakpoint except that you can specify a vector of names. This is cheaper
|
|
// than a regular expression breakpoint in the case where you just want to set a breakpoint on a set of names
|
|
// you already know.
|
|
lldb::BreakpointSP
|
|
CreateBreakpoint (const FileSpecList *containingModules,
|
|
const FileSpecList *containingSourceFiles,
|
|
const char *func_names[],
|
|
size_t num_names,
|
|
uint32_t func_name_type_mask,
|
|
LazyBool skip_prologue,
|
|
bool internal,
|
|
bool request_hardware);
|
|
|
|
lldb::BreakpointSP
|
|
CreateBreakpoint (const FileSpecList *containingModules,
|
|
const FileSpecList *containingSourceFiles,
|
|
const std::vector<std::string> &func_names,
|
|
uint32_t func_name_type_mask,
|
|
LazyBool skip_prologue,
|
|
bool internal,
|
|
bool request_hardware);
|
|
|
|
|
|
// Use this to create a general breakpoint:
|
|
lldb::BreakpointSP
|
|
CreateBreakpoint (lldb::SearchFilterSP &filter_sp,
|
|
lldb::BreakpointResolverSP &resolver_sp,
|
|
bool internal,
|
|
bool request_hardware,
|
|
bool resolve_indirect_symbols);
|
|
|
|
// Use this to create a watchpoint:
|
|
lldb::WatchpointSP
|
|
CreateWatchpoint (lldb::addr_t addr,
|
|
size_t size,
|
|
const ClangASTType *type,
|
|
uint32_t kind,
|
|
Error &error);
|
|
|
|
lldb::WatchpointSP
|
|
GetLastCreatedWatchpoint ()
|
|
{
|
|
return m_last_created_watchpoint;
|
|
}
|
|
|
|
WatchpointList &
|
|
GetWatchpointList()
|
|
{
|
|
return m_watchpoint_list;
|
|
}
|
|
|
|
void
|
|
RemoveAllBreakpoints (bool internal_also = false);
|
|
|
|
void
|
|
DisableAllBreakpoints (bool internal_also = false);
|
|
|
|
void
|
|
EnableAllBreakpoints (bool internal_also = false);
|
|
|
|
bool
|
|
DisableBreakpointByID (lldb::break_id_t break_id);
|
|
|
|
bool
|
|
EnableBreakpointByID (lldb::break_id_t break_id);
|
|
|
|
bool
|
|
RemoveBreakpointByID (lldb::break_id_t break_id);
|
|
|
|
// The flag 'end_to_end', default to true, signifies that the operation is
|
|
// performed end to end, for both the debugger and the debuggee.
|
|
|
|
bool
|
|
RemoveAllWatchpoints (bool end_to_end = true);
|
|
|
|
bool
|
|
DisableAllWatchpoints (bool end_to_end = true);
|
|
|
|
bool
|
|
EnableAllWatchpoints (bool end_to_end = true);
|
|
|
|
bool
|
|
ClearAllWatchpointHitCounts ();
|
|
|
|
bool
|
|
IgnoreAllWatchpoints (uint32_t ignore_count);
|
|
|
|
bool
|
|
DisableWatchpointByID (lldb::watch_id_t watch_id);
|
|
|
|
bool
|
|
EnableWatchpointByID (lldb::watch_id_t watch_id);
|
|
|
|
bool
|
|
RemoveWatchpointByID (lldb::watch_id_t watch_id);
|
|
|
|
bool
|
|
IgnoreWatchpointByID (lldb::watch_id_t watch_id, uint32_t ignore_count);
|
|
|
|
//------------------------------------------------------------------
|
|
/// Get \a load_addr as a callable code load address for this target
|
|
///
|
|
/// Take \a load_addr and potentially add any address bits that are
|
|
/// needed to make the address callable. For ARM this can set bit
|
|
/// zero (if it already isn't) if \a load_addr is a thumb function.
|
|
/// If \a addr_class is set to eAddressClassInvalid, then the address
|
|
/// adjustment will always happen. If it is set to an address class
|
|
/// that doesn't have code in it, LLDB_INVALID_ADDRESS will be
|
|
/// returned.
|
|
//------------------------------------------------------------------
|
|
lldb::addr_t
|
|
GetCallableLoadAddress (lldb::addr_t load_addr, lldb::AddressClass addr_class = lldb::eAddressClassInvalid) const;
|
|
|
|
//------------------------------------------------------------------
|
|
/// Get \a load_addr as an opcode for this target.
|
|
///
|
|
/// Take \a load_addr and potentially strip any address bits that are
|
|
/// needed to make the address point to an opcode. For ARM this can
|
|
/// clear bit zero (if it already isn't) if \a load_addr is a
|
|
/// thumb function and load_addr is in code.
|
|
/// If \a addr_class is set to eAddressClassInvalid, then the address
|
|
/// adjustment will always happen. If it is set to an address class
|
|
/// that doesn't have code in it, LLDB_INVALID_ADDRESS will be
|
|
/// returned.
|
|
//------------------------------------------------------------------
|
|
lldb::addr_t
|
|
GetOpcodeLoadAddress (lldb::addr_t load_addr, lldb::AddressClass addr_class = lldb::eAddressClassInvalid) const;
|
|
|
|
protected:
|
|
//------------------------------------------------------------------
|
|
/// Implementing of ModuleList::Notifier.
|
|
//------------------------------------------------------------------
|
|
|
|
virtual void
|
|
ModuleAdded (const ModuleList& module_list, const lldb::ModuleSP& module_sp);
|
|
|
|
virtual void
|
|
ModuleRemoved (const ModuleList& module_list, const lldb::ModuleSP& module_sp);
|
|
|
|
virtual void
|
|
ModuleUpdated (const ModuleList& module_list,
|
|
const lldb::ModuleSP& old_module_sp,
|
|
const lldb::ModuleSP& new_module_sp);
|
|
virtual void
|
|
WillClearList (const ModuleList& module_list);
|
|
|
|
public:
|
|
|
|
void
|
|
ModulesDidLoad (ModuleList &module_list);
|
|
|
|
void
|
|
ModulesDidUnload (ModuleList &module_list, bool delete_locations);
|
|
|
|
void
|
|
SymbolsDidLoad (ModuleList &module_list);
|
|
|
|
void
|
|
ClearModules(bool delete_locations);
|
|
|
|
//------------------------------------------------------------------
|
|
/// Called as the last function in Process::DidExec().
|
|
///
|
|
/// Process::DidExec() will clear a lot of state in the process,
|
|
/// then try to reload a dynamic loader plugin to discover what
|
|
/// binaries are currently available and then this function should
|
|
/// be called to allow the target to do any cleanup after everything
|
|
/// has been figured out. It can remove breakpoints that no longer
|
|
/// make sense as the exec might have changed the target
|
|
/// architecture, and unloaded some modules that might get deleted.
|
|
//------------------------------------------------------------------
|
|
void
|
|
DidExec ();
|
|
|
|
//------------------------------------------------------------------
|
|
/// Gets the module for the main executable.
|
|
///
|
|
/// Each process has a notion of a main executable that is the file
|
|
/// that will be executed or attached to. Executable files can have
|
|
/// dependent modules that are discovered from the object files, or
|
|
/// discovered at runtime as things are dynamically loaded.
|
|
///
|
|
/// @return
|
|
/// The shared pointer to the executable module which can
|
|
/// contains a NULL Module object if no executable has been
|
|
/// set.
|
|
///
|
|
/// @see DynamicLoader
|
|
/// @see ObjectFile::GetDependentModules (FileSpecList&)
|
|
/// @see Process::SetExecutableModule(lldb::ModuleSP&)
|
|
//------------------------------------------------------------------
|
|
lldb::ModuleSP
|
|
GetExecutableModule ();
|
|
|
|
Module*
|
|
GetExecutableModulePointer ();
|
|
|
|
//------------------------------------------------------------------
|
|
/// Set the main executable module.
|
|
///
|
|
/// Each process has a notion of a main executable that is the file
|
|
/// that will be executed or attached to. Executable files can have
|
|
/// dependent modules that are discovered from the object files, or
|
|
/// discovered at runtime as things are dynamically loaded.
|
|
///
|
|
/// Setting the executable causes any of the current dependant
|
|
/// image information to be cleared and replaced with the static
|
|
/// dependent image information found by calling
|
|
/// ObjectFile::GetDependentModules (FileSpecList&) on the main
|
|
/// executable and any modules on which it depends. Calling
|
|
/// Process::GetImages() will return the newly found images that
|
|
/// were obtained from all of the object files.
|
|
///
|
|
/// @param[in] module_sp
|
|
/// A shared pointer reference to the module that will become
|
|
/// the main executable for this process.
|
|
///
|
|
/// @param[in] get_dependent_files
|
|
/// If \b true then ask the object files to track down any
|
|
/// known dependent files.
|
|
///
|
|
/// @see ObjectFile::GetDependentModules (FileSpecList&)
|
|
/// @see Process::GetImages()
|
|
//------------------------------------------------------------------
|
|
void
|
|
SetExecutableModule (lldb::ModuleSP& module_sp, bool get_dependent_files);
|
|
|
|
bool
|
|
LoadScriptingResources (std::list<Error>& errors,
|
|
Stream* feedback_stream = NULL,
|
|
bool continue_on_error = true)
|
|
{
|
|
return m_images.LoadScriptingResourcesInTarget(this,errors,feedback_stream,continue_on_error);
|
|
}
|
|
|
|
//------------------------------------------------------------------
|
|
/// Get accessor for the images for this process.
|
|
///
|
|
/// Each process has a notion of a main executable that is the file
|
|
/// that will be executed or attached to. Executable files can have
|
|
/// dependent modules that are discovered from the object files, or
|
|
/// discovered at runtime as things are dynamically loaded. After
|
|
/// a main executable has been set, the images will contain a list
|
|
/// of all the files that the executable depends upon as far as the
|
|
/// object files know. These images will usually contain valid file
|
|
/// virtual addresses only. When the process is launched or attached
|
|
/// to, the DynamicLoader plug-in will discover where these images
|
|
/// were loaded in memory and will resolve the load virtual
|
|
/// addresses is each image, and also in images that are loaded by
|
|
/// code.
|
|
///
|
|
/// @return
|
|
/// A list of Module objects in a module list.
|
|
//------------------------------------------------------------------
|
|
const ModuleList&
|
|
GetImages () const
|
|
{
|
|
return m_images;
|
|
}
|
|
|
|
ModuleList&
|
|
GetImages ()
|
|
{
|
|
return m_images;
|
|
}
|
|
|
|
//------------------------------------------------------------------
|
|
/// Return whether this FileSpec corresponds to a module that should be considered for general searches.
|
|
///
|
|
/// This API will be consulted by the SearchFilterForUnconstrainedSearches
|
|
/// and any module that returns \b true will not be searched. Note the
|
|
/// SearchFilterForUnconstrainedSearches is the search filter that
|
|
/// gets used in the CreateBreakpoint calls when no modules is provided.
|
|
///
|
|
/// The target call at present just consults the Platform's call of the
|
|
/// same name.
|
|
///
|
|
/// @param[in] module_sp
|
|
/// A shared pointer reference to the module that checked.
|
|
///
|
|
/// @return \b true if the module should be excluded, \b false otherwise.
|
|
//------------------------------------------------------------------
|
|
bool
|
|
ModuleIsExcludedForUnconstrainedSearches (const FileSpec &module_spec);
|
|
|
|
//------------------------------------------------------------------
|
|
/// Return whether this module should be considered for general searches.
|
|
///
|
|
/// This API will be consulted by the SearchFilterForUnconstrainedSearches
|
|
/// and any module that returns \b true will not be searched. Note the
|
|
/// SearchFilterForUnconstrainedSearches is the search filter that
|
|
/// gets used in the CreateBreakpoint calls when no modules is provided.
|
|
///
|
|
/// The target call at present just consults the Platform's call of the
|
|
/// same name.
|
|
///
|
|
/// FIXME: When we get time we should add a way for the user to set modules that they
|
|
/// don't want searched, in addition to or instead of the platform ones.
|
|
///
|
|
/// @param[in] module_sp
|
|
/// A shared pointer reference to the module that checked.
|
|
///
|
|
/// @return \b true if the module should be excluded, \b false otherwise.
|
|
//------------------------------------------------------------------
|
|
bool
|
|
ModuleIsExcludedForUnconstrainedSearches (const lldb::ModuleSP &module_sp);
|
|
|
|
ArchSpec &
|
|
GetArchitecture ()
|
|
{
|
|
return m_arch;
|
|
}
|
|
|
|
const ArchSpec &
|
|
GetArchitecture () const
|
|
{
|
|
return m_arch;
|
|
}
|
|
|
|
//------------------------------------------------------------------
|
|
/// Set the architecture for this target.
|
|
///
|
|
/// If the current target has no Images read in, then this just sets the architecture, which will
|
|
/// be used to select the architecture of the ExecutableModule when that is set.
|
|
/// If the current target has an ExecutableModule, then calling SetArchitecture with a different
|
|
/// architecture from the currently selected one will reset the ExecutableModule to that slice
|
|
/// of the file backing the ExecutableModule. If the file backing the ExecutableModule does not
|
|
/// contain a fork of this architecture, then this code will return false, and the architecture
|
|
/// won't be changed.
|
|
/// If the input arch_spec is the same as the already set architecture, this is a no-op.
|
|
///
|
|
/// @param[in] arch_spec
|
|
/// The new architecture.
|
|
///
|
|
/// @return
|
|
/// \b true if the architecture was successfully set, \bfalse otherwise.
|
|
//------------------------------------------------------------------
|
|
bool
|
|
SetArchitecture (const ArchSpec &arch_spec);
|
|
|
|
Debugger &
|
|
GetDebugger ()
|
|
{
|
|
return m_debugger;
|
|
}
|
|
|
|
size_t
|
|
ReadMemoryFromFileCache (const Address& addr,
|
|
void *dst,
|
|
size_t dst_len,
|
|
Error &error);
|
|
|
|
// Reading memory through the target allows us to skip going to the process
|
|
// for reading memory if possible and it allows us to try and read from
|
|
// any constant sections in our object files on disk. If you always want
|
|
// live program memory, read straight from the process. If you possibly
|
|
// want to read from const sections in object files, read from the target.
|
|
// This version of ReadMemory will try and read memory from the process
|
|
// if the process is alive. The order is:
|
|
// 1 - if (prefer_file_cache == true) then read from object file cache
|
|
// 2 - if there is a valid process, try and read from its memory
|
|
// 3 - if (prefer_file_cache == false) then read from object file cache
|
|
size_t
|
|
ReadMemory (const Address& addr,
|
|
bool prefer_file_cache,
|
|
void *dst,
|
|
size_t dst_len,
|
|
Error &error,
|
|
lldb::addr_t *load_addr_ptr = NULL);
|
|
|
|
size_t
|
|
ReadCStringFromMemory (const Address& addr, std::string &out_str, Error &error);
|
|
|
|
size_t
|
|
ReadCStringFromMemory (const Address& addr, char *dst, size_t dst_max_len, Error &result_error);
|
|
|
|
size_t
|
|
ReadScalarIntegerFromMemory (const Address& addr,
|
|
bool prefer_file_cache,
|
|
uint32_t byte_size,
|
|
bool is_signed,
|
|
Scalar &scalar,
|
|
Error &error);
|
|
|
|
uint64_t
|
|
ReadUnsignedIntegerFromMemory (const Address& addr,
|
|
bool prefer_file_cache,
|
|
size_t integer_byte_size,
|
|
uint64_t fail_value,
|
|
Error &error);
|
|
|
|
bool
|
|
ReadPointerFromMemory (const Address& addr,
|
|
bool prefer_file_cache,
|
|
Error &error,
|
|
Address &pointer_addr);
|
|
|
|
SectionLoadList&
|
|
GetSectionLoadList()
|
|
{
|
|
return m_section_load_history.GetCurrentSectionLoadList();
|
|
}
|
|
|
|
// const SectionLoadList&
|
|
// GetSectionLoadList() const
|
|
// {
|
|
// return const_cast<SectionLoadHistory *>(&m_section_load_history)->GetCurrentSectionLoadList();
|
|
// }
|
|
|
|
static Target *
|
|
GetTargetFromContexts (const ExecutionContext *exe_ctx_ptr,
|
|
const SymbolContext *sc_ptr);
|
|
|
|
//------------------------------------------------------------------
|
|
// lldb::ExecutionContextScope pure virtual functions
|
|
//------------------------------------------------------------------
|
|
virtual lldb::TargetSP
|
|
CalculateTarget ();
|
|
|
|
virtual lldb::ProcessSP
|
|
CalculateProcess ();
|
|
|
|
virtual lldb::ThreadSP
|
|
CalculateThread ();
|
|
|
|
virtual lldb::StackFrameSP
|
|
CalculateStackFrame ();
|
|
|
|
virtual void
|
|
CalculateExecutionContext (ExecutionContext &exe_ctx);
|
|
|
|
PathMappingList &
|
|
GetImageSearchPathList ();
|
|
|
|
ClangASTContext *
|
|
GetScratchClangASTContext(bool create_on_demand=true);
|
|
|
|
ClangASTImporter *
|
|
GetClangASTImporter();
|
|
|
|
//----------------------------------------------------------------------
|
|
// Install any files through the platform that need be to installed
|
|
// prior to launching or attaching.
|
|
//----------------------------------------------------------------------
|
|
Error
|
|
Install(ProcessLaunchInfo *launch_info);
|
|
|
|
bool
|
|
ResolveFileAddress (lldb::addr_t load_addr,
|
|
Address &so_addr);
|
|
|
|
bool
|
|
ResolveLoadAddress (lldb::addr_t load_addr,
|
|
Address &so_addr,
|
|
uint32_t stop_id = SectionLoadHistory::eStopIDNow);
|
|
|
|
bool
|
|
SetSectionLoadAddress (const lldb::SectionSP §ion,
|
|
lldb::addr_t load_addr,
|
|
bool warn_multiple = false);
|
|
|
|
size_t
|
|
UnloadModuleSections (const lldb::ModuleSP &module_sp);
|
|
|
|
size_t
|
|
UnloadModuleSections (const ModuleList &module_list);
|
|
|
|
bool
|
|
SetSectionUnloaded (const lldb::SectionSP §ion_sp);
|
|
|
|
bool
|
|
SetSectionUnloaded (const lldb::SectionSP §ion_sp, lldb::addr_t load_addr);
|
|
|
|
void
|
|
ClearAllLoadedSections ();
|
|
|
|
// Since expressions results can persist beyond the lifetime of a process,
|
|
// and the const expression results are available after a process is gone,
|
|
// we provide a way for expressions to be evaluated from the Target itself.
|
|
// If an expression is going to be run, then it should have a frame filled
|
|
// in in th execution context.
|
|
lldb::ExpressionResults
|
|
EvaluateExpression (const char *expression,
|
|
StackFrame *frame,
|
|
lldb::ValueObjectSP &result_valobj_sp,
|
|
const EvaluateExpressionOptions& options = EvaluateExpressionOptions());
|
|
|
|
ClangPersistentVariables &
|
|
GetPersistentVariables()
|
|
{
|
|
return m_persistent_variables;
|
|
}
|
|
|
|
//------------------------------------------------------------------
|
|
// Target Stop Hooks
|
|
//------------------------------------------------------------------
|
|
class StopHook : public UserID
|
|
{
|
|
public:
|
|
~StopHook ();
|
|
|
|
StopHook (const StopHook &rhs);
|
|
|
|
StringList *
|
|
GetCommandPointer ()
|
|
{
|
|
return &m_commands;
|
|
}
|
|
|
|
const StringList &
|
|
GetCommands()
|
|
{
|
|
return m_commands;
|
|
}
|
|
|
|
lldb::TargetSP &
|
|
GetTarget()
|
|
{
|
|
return m_target_sp;
|
|
}
|
|
|
|
void
|
|
SetCommands (StringList &in_commands)
|
|
{
|
|
m_commands = in_commands;
|
|
}
|
|
|
|
// Set the specifier. The stop hook will own the specifier, and is responsible for deleting it when we're done.
|
|
void
|
|
SetSpecifier (SymbolContextSpecifier *specifier)
|
|
{
|
|
m_specifier_sp.reset (specifier);
|
|
}
|
|
|
|
SymbolContextSpecifier *
|
|
GetSpecifier ()
|
|
{
|
|
return m_specifier_sp.get();
|
|
}
|
|
|
|
// Set the Thread Specifier. The stop hook will own the thread specifier, and is responsible for deleting it when we're done.
|
|
void
|
|
SetThreadSpecifier (ThreadSpec *specifier);
|
|
|
|
ThreadSpec *
|
|
GetThreadSpecifier()
|
|
{
|
|
return m_thread_spec_ap.get();
|
|
}
|
|
|
|
bool
|
|
IsActive()
|
|
{
|
|
return m_active;
|
|
}
|
|
|
|
void
|
|
SetIsActive (bool is_active)
|
|
{
|
|
m_active = is_active;
|
|
}
|
|
|
|
void
|
|
GetDescription (Stream *s, lldb::DescriptionLevel level) const;
|
|
|
|
private:
|
|
lldb::TargetSP m_target_sp;
|
|
StringList m_commands;
|
|
lldb::SymbolContextSpecifierSP m_specifier_sp;
|
|
std::unique_ptr<ThreadSpec> m_thread_spec_ap;
|
|
bool m_active;
|
|
|
|
// Use CreateStopHook to make a new empty stop hook. The GetCommandPointer and fill it with commands,
|
|
// and SetSpecifier to set the specifier shared pointer (can be null, that will match anything.)
|
|
StopHook (lldb::TargetSP target_sp, lldb::user_id_t uid);
|
|
friend class Target;
|
|
};
|
|
typedef std::shared_ptr<StopHook> StopHookSP;
|
|
|
|
// Add an empty stop hook to the Target's stop hook list, and returns a shared pointer to it in new_hook.
|
|
// Returns the id of the new hook.
|
|
StopHookSP
|
|
CreateStopHook ();
|
|
|
|
void
|
|
RunStopHooks ();
|
|
|
|
size_t
|
|
GetStopHookSize();
|
|
|
|
bool
|
|
SetSuppresStopHooks (bool suppress)
|
|
{
|
|
bool old_value = m_suppress_stop_hooks;
|
|
m_suppress_stop_hooks = suppress;
|
|
return old_value;
|
|
}
|
|
|
|
bool
|
|
GetSuppressStopHooks ()
|
|
{
|
|
return m_suppress_stop_hooks;
|
|
}
|
|
|
|
// StopHookSP &
|
|
// GetStopHookByIndex (size_t index);
|
|
//
|
|
bool
|
|
RemoveStopHookByID (lldb::user_id_t uid);
|
|
|
|
void
|
|
RemoveAllStopHooks ();
|
|
|
|
StopHookSP
|
|
GetStopHookByID (lldb::user_id_t uid);
|
|
|
|
bool
|
|
SetStopHookActiveStateByID (lldb::user_id_t uid, bool active_state);
|
|
|
|
void
|
|
SetAllStopHooksActiveState (bool active_state);
|
|
|
|
size_t GetNumStopHooks () const
|
|
{
|
|
return m_stop_hooks.size();
|
|
}
|
|
|
|
StopHookSP
|
|
GetStopHookAtIndex (size_t index)
|
|
{
|
|
if (index >= GetNumStopHooks())
|
|
return StopHookSP();
|
|
StopHookCollection::iterator pos = m_stop_hooks.begin();
|
|
|
|
while (index > 0)
|
|
{
|
|
pos++;
|
|
index--;
|
|
}
|
|
return (*pos).second;
|
|
}
|
|
|
|
lldb::PlatformSP
|
|
GetPlatform ()
|
|
{
|
|
return m_platform_sp;
|
|
}
|
|
|
|
void
|
|
SetPlatform (const lldb::PlatformSP &platform_sp)
|
|
{
|
|
m_platform_sp = platform_sp;
|
|
}
|
|
|
|
SourceManager &
|
|
GetSourceManager ();
|
|
|
|
ClangModulesDeclVendor *
|
|
GetClangModulesDeclVendor ();
|
|
|
|
//------------------------------------------------------------------
|
|
// Methods.
|
|
//------------------------------------------------------------------
|
|
lldb::SearchFilterSP
|
|
GetSearchFilterForModule (const FileSpec *containingModule);
|
|
|
|
lldb::SearchFilterSP
|
|
GetSearchFilterForModuleList (const FileSpecList *containingModuleList);
|
|
|
|
lldb::SearchFilterSP
|
|
GetSearchFilterForModuleAndCUList (const FileSpecList *containingModules, const FileSpecList *containingSourceFiles);
|
|
|
|
protected:
|
|
//------------------------------------------------------------------
|
|
// Member variables.
|
|
//------------------------------------------------------------------
|
|
Debugger & m_debugger;
|
|
lldb::PlatformSP m_platform_sp; ///< The platform for this target.
|
|
Mutex m_mutex; ///< An API mutex that is used by the lldb::SB* classes make the SB interface thread safe
|
|
ArchSpec m_arch;
|
|
ModuleList m_images; ///< The list of images for this process (shared libraries and anything dynamically loaded).
|
|
SectionLoadHistory m_section_load_history;
|
|
BreakpointList m_breakpoint_list;
|
|
BreakpointList m_internal_breakpoint_list;
|
|
lldb::BreakpointSP m_last_created_breakpoint;
|
|
WatchpointList m_watchpoint_list;
|
|
lldb::WatchpointSP m_last_created_watchpoint;
|
|
// We want to tightly control the process destruction process so
|
|
// we can correctly tear down everything that we need to, so the only
|
|
// class that knows about the process lifespan is this target class.
|
|
lldb::ProcessSP m_process_sp;
|
|
lldb::SearchFilterSP m_search_filter_sp;
|
|
PathMappingList m_image_search_paths;
|
|
std::unique_ptr<ClangASTContext> m_scratch_ast_context_ap;
|
|
std::unique_ptr<ClangASTSource> m_scratch_ast_source_ap;
|
|
std::unique_ptr<ClangASTImporter> m_ast_importer_ap;
|
|
std::unique_ptr<ClangModulesDeclVendor> m_clang_modules_decl_vendor_ap;
|
|
ClangPersistentVariables m_persistent_variables; ///< These are the persistent variables associated with this process for the expression parser.
|
|
|
|
std::unique_ptr<SourceManager> m_source_manager_ap;
|
|
|
|
typedef std::map<lldb::user_id_t, StopHookSP> StopHookCollection;
|
|
StopHookCollection m_stop_hooks;
|
|
lldb::user_id_t m_stop_hook_next_id;
|
|
bool m_valid;
|
|
bool m_suppress_stop_hooks;
|
|
bool m_is_dummy_target;
|
|
|
|
static void
|
|
ImageSearchPathsChanged (const PathMappingList &path_list,
|
|
void *baton);
|
|
|
|
private:
|
|
DISALLOW_COPY_AND_ASSIGN (Target);
|
|
};
|
|
|
|
} // namespace lldb_private
|
|
|
|
#endif // liblldb_Target_h_
|